* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse [not found] ` <DC148C5AA1CEBA4E87973D432B1C2D8825E9CBD6@P3PWEX4MB008.ex4.secureserver.net> @ 2014-06-11 21:24 ` Dan Carpenter 2014-06-11 21:45 ` josh 0 siblings, 1 reply; 10+ messages in thread From: Dan Carpenter @ 2014-06-11 21:24 UTC (permalink / raw) To: Hartley Sweeten Cc: Marcos A. Di Pietro, devel@driverdev.osuosl.org, linux-sparse [-- Attachment #1: Type: text/plain, Size: 865 bytes --] Let's forward this to the Sparse mailing list. We're seeing a Sparse false positive testing drivers/staging/comedi/drivers/ni_pcimio.c. CHECK drivers/staging/comedi/drivers/ni_pcimio.c drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int I have created some test code to demonstrate the problem (attached). The check_shift_count() warning is only supposed to be printed for number literals but because of the way inline functions are expanded it still complains even though channel is a variable. regards, dan carpenter [-- Attachment #2: test_shift.c --] [-- Type: text/x-csrc, Size: 355 bytes --] #include <stdio.h> #include <limits.h> #include <string.h> static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel) { if (channel < 4) return 1 << channel; return 0; } static inline void filter(int channel) { if (channel < 0) return; ni_stc_dma_channel_select_bitfield(channel); } int main(void) { filter(-1); return 0; } ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-11 21:24 ` [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse Dan Carpenter @ 2014-06-11 21:45 ` josh 2014-06-15 19:32 ` Sam Ravnborg 2014-06-28 18:07 ` Christopher Li 0 siblings, 2 replies; 10+ messages in thread From: josh @ 2014-06-11 21:45 UTC (permalink / raw) To: Dan Carpenter Cc: Hartley Sweeten, Marcos A. Di Pietro, devel@driverdev.osuosl.org, linux-sparse On Thu, Jun 12, 2014 at 12:24:25AM +0300, Dan Carpenter wrote: > Let's forward this to the Sparse mailing list. > > We're seeing a Sparse false positive testing > drivers/staging/comedi/drivers/ni_pcimio.c. > > CHECK drivers/staging/comedi/drivers/ni_pcimio.c > drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > > I have created some test code to demonstrate the problem (attached). > > The check_shift_count() warning is only supposed to be printed for > number literals but because of the way inline functions are expanded it > still complains even though channel is a variable. Thanks for the test case; this definitely makes no sense. I don't think Sparse will suddenly develop enough range analysis or reachability analysis to handle this case; I think the right answer is to avoid giving such warnings for shifts with a non-constant RHS. > #include <stdio.h> > #include <limits.h> > #include <string.h> > > static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel) > { > if (channel < 4) > return 1 << channel; > return 0; > } > > static inline void filter(int channel) > { > if (channel < 0) > return; > ni_stc_dma_channel_select_bitfield(channel); > } > > int main(void) > { > filter(-1); > > return 0; > } ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-11 21:45 ` josh @ 2014-06-15 19:32 ` Sam Ravnborg 2014-06-16 7:40 ` Dan Carpenter 2014-06-28 18:07 ` Christopher Li 1 sibling, 1 reply; 10+ messages in thread From: Sam Ravnborg @ 2014-06-15 19:32 UTC (permalink / raw) To: josh Cc: Dan Carpenter, Hartley Sweeten, Marcos A. Di Pietro, devel@driverdev.osuosl.org, linux-sparse Hi Josh. On Wed, Jun 11, 2014 at 02:45:29PM -0700, josh@joshtriplett.org wrote: > On Thu, Jun 12, 2014 at 12:24:25AM +0300, Dan Carpenter wrote: > > Let's forward this to the Sparse mailing list. > > > > We're seeing a Sparse false positive testing > > drivers/staging/comedi/drivers/ni_pcimio.c. > > > > CHECK drivers/staging/comedi/drivers/ni_pcimio.c > > drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > > drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > > drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > > drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > > > > I have created some test code to demonstrate the problem (attached). > > > > The check_shift_count() warning is only supposed to be printed for > > number literals but because of the way inline functions are expanded it > > still complains even though channel is a variable. > > Thanks for the test case; this definitely makes no sense. I don't think > Sparse will suddenly develop enough range analysis or reachability > analysis to handle this case; I think the right answer is to avoid > giving such warnings for shifts with a non-constant RHS. Something like the appended? It seems to work for me - and it cured a lot of warnings in math-emu.c on sparc. If it looks OK I will do a proper patch submission. Sam diff --git a/expand.c b/expand.c index 0f6720c..4a96de4 100644 --- a/expand.c +++ b/expand.c @@ -187,7 +187,7 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype) return 0; r = right->value; if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) { - if (r >= ctype->bit_size) { + if (expr->flags & Int_const_expr && r >= ctype->bit_size) { if (conservative) return 0; r = check_shift_count(expr, ctype, r); ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-15 19:32 ` Sam Ravnborg @ 2014-06-16 7:40 ` Dan Carpenter 2014-06-16 8:06 ` Sam Ravnborg 0 siblings, 1 reply; 10+ messages in thread From: Dan Carpenter @ 2014-06-16 7:40 UTC (permalink / raw) To: Sam Ravnborg Cc: devel@driverdev.osuosl.org, linux-sparse, josh, Marcos A. Di Pietro On Sun, Jun 15, 2014 at 09:32:27PM +0200, Sam Ravnborg wrote: > diff --git a/expand.c b/expand.c > index 0f6720c..4a96de4 100644 > --- a/expand.c > +++ b/expand.c > @@ -187,7 +187,7 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype) > return 0; > r = right->value; > if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) { > - if (r >= ctype->bit_size) { > + if (expr->flags & Int_const_expr && r >= ctype->bit_size) { Thanks! I had no idea how to start writing a fix for this, but the test should be: if (expr->right->flags & Int_const_expr Otherwise both sides of the shift have to be const. > if (conservative) > return 0; > r = check_shift_count(expr, ctype, r); > regards, dan carpenter ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-16 7:40 ` Dan Carpenter @ 2014-06-16 8:06 ` Sam Ravnborg 0 siblings, 0 replies; 10+ messages in thread From: Sam Ravnborg @ 2014-06-16 8:06 UTC (permalink / raw) To: Dan Carpenter Cc: devel@driverdev.osuosl.org, linux-sparse, josh, Marcos A. Di Pietro On Mon, Jun 16, 2014 at 10:40:19AM +0300, Dan Carpenter wrote: > On Sun, Jun 15, 2014 at 09:32:27PM +0200, Sam Ravnborg wrote: > > diff --git a/expand.c b/expand.c > > index 0f6720c..4a96de4 100644 > > --- a/expand.c > > +++ b/expand.c > > @@ -187,7 +187,7 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype) > > return 0; > > r = right->value; > > if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) { > > - if (r >= ctype->bit_size) { > > + if (expr->flags & Int_const_expr && r >= ctype->bit_size) { > > Thanks! I had no idea how to start writing a fix for this, but the test > should be: > if (expr->right->flags & Int_const_expr > > Otherwise both sides of the shift have to be const. Thanks - will fix. I will update the test case to check for this, and then send a proper patch. Sam ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-11 21:45 ` josh 2014-06-15 19:32 ` Sam Ravnborg @ 2014-06-28 18:07 ` Christopher Li 2014-06-28 19:20 ` Josh Triplett 1 sibling, 1 reply; 10+ messages in thread From: Christopher Li @ 2014-06-28 18:07 UTC (permalink / raw) To: Josh Triplett Cc: devel@driverdev.osuosl.org, Linux-Sparse, Marcos A. Di Pietro, Dan Carpenter Sorry for the late reply. On Wed, Jun 11, 2014 at 2:45 PM, <josh@joshtriplett.org> wrote: > On Thu, Jun 12, 2014 at 12:24:25AM +0300, Dan Carpenter wrote: >> Let's forward this to the Sparse mailing list. >> >> We're seeing a Sparse false positive testing No, this is a valid complain. See my point follows. >> drivers/staging/comedi/drivers/ni_pcimio.c. >> >> CHECK drivers/staging/comedi/drivers/ni_pcimio.c >> drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int >> drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int >> drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int >> drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int >> >> I have created some test code to demonstrate the problem (attached). >> >> The check_shift_count() warning is only supposed to be printed for >> number literals but because of the way inline functions are expanded it >> still complains even though channel is a variable. > > Thanks for the test case; this definitely makes no sense. I don't think > Sparse will suddenly develop enough range analysis or reachability > analysis to handle this case; I think the right answer is to avoid > giving such warnings for shifts with a non-constant RHS. Sparse can handle inline function expand and some constant propagate. In this case, sparse seems doing the right thing. Sparse actually sees the channel value being 4294967295 (-1). >> static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel) This is the bug. See this channel is *unsigned*. When -1 pass into channel, it become a really large number 4294967295. The code does request C compiler to perform left shift 4294967295 bits. Which did not make sense. >> { >> if (channel < 4) >> return 1 << channel; >> return 0; >> } >> >> static inline void filter(int channel) >> { >> if (channel < 0) >> return; >> ni_stc_dma_channel_select_bitfield(channel); See this channel is *signed*, with -1 convert to 4294967295. This is a bug in the kernel source not sparse. Chris ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-28 18:07 ` Christopher Li @ 2014-06-28 19:20 ` Josh Triplett 2014-06-29 3:09 ` Christopher Li 0 siblings, 1 reply; 10+ messages in thread From: Josh Triplett @ 2014-06-28 19:20 UTC (permalink / raw) To: Christopher Li Cc: devel@driverdev.osuosl.org, Linux-Sparse, Marcos A. Di Pietro, Dan Carpenter On Sat, Jun 28, 2014 at 11:07:48AM -0700, Christopher Li wrote: > On Wed, Jun 11, 2014 at 2:45 PM, <josh@joshtriplett.org> wrote: > > On Thu, Jun 12, 2014 at 12:24:25AM +0300, Dan Carpenter wrote: > >> Let's forward this to the Sparse mailing list. > >> > >> We're seeing a Sparse false positive testing > > No, this is a valid complain. See my point follows. > > >> drivers/staging/comedi/drivers/ni_pcimio.c. > >> > >> CHECK drivers/staging/comedi/drivers/ni_pcimio.c > >> drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > >> drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > >> drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > >> drivers/staging/comedi/drivers/ni_stc.h:720:26: warning: shift too big (4294967295) for type int > >> > >> I have created some test code to demonstrate the problem (attached). > >> > >> The check_shift_count() warning is only supposed to be printed for > >> number literals but because of the way inline functions are expanded it > >> still complains even though channel is a variable. > > > > Thanks for the test case; this definitely makes no sense. I don't think > > Sparse will suddenly develop enough range analysis or reachability > > analysis to handle this case; I think the right answer is to avoid > > giving such warnings for shifts with a non-constant RHS. > > Sparse can handle inline function expand and some constant > propagate. In this case, sparse seems doing the right thing. > Sparse actually sees the channel value being 4294967295 (-1). > > >> static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel) > > This is the bug. See this channel is *unsigned*. When -1 pass into > channel, it become a really large number 4294967295. > The code does request C compiler to perform left shift 4294967295 bits. > Which did not make sense. > > >> { > >> if (channel < 4) > >> return 1 << channel; > >> return 0; > >> } > >> > >> static inline void filter(int channel) > >> { > >> if (channel < 0) > >> return; > >> ni_stc_dma_channel_select_bitfield(channel); > > See this channel is *signed*, with -1 convert to 4294967295. > This is a bug in the kernel source not sparse. Except that "filter" has an "int channel" (signed), so it can successfully test "channel < 0" and return early; it'll never call ni_stc_dma_channel_select_bitfield(channel) with a negative number. I do agree that this code should sort out the signedness of its types, but in this case I don't think the bad shift can actually happen, making this a false positive. - Josh Triplett ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-28 19:20 ` Josh Triplett @ 2014-06-29 3:09 ` Christopher Li 2014-06-30 17:49 ` Christopher Li 0 siblings, 1 reply; 10+ messages in thread From: Christopher Li @ 2014-06-29 3:09 UTC (permalink / raw) To: Josh Triplett Cc: Dan Carpenter, Hartley Sweeten, Marcos A. Di Pietro, devel@driverdev.osuosl.org, Linux-Sparse On Sat, Jun 28, 2014 at 12:20 PM, Josh Triplett <josh@joshtriplett.org> wrote: > Except that "filter" has an "int channel" (signed), so it can > successfully test "channel < 0" and return early; it'll never call > ni_stc_dma_channel_select_bitfield(channel) with a negative number. > > I do agree that this code should sort out the signedness of its types, > but in this case I don't think the bad shift can actually happen, making > this a false positive. Ah, I see. I agree that the warning happen on the dead code. However, the root cause for the warning is not because sparse can not figure out the value of "channel". Sparse actually correctly does the inline and figure out "channel" is 4294967295. The root cause of your complain against sparse is that it happen on the dead code. I don' think the patch is the right fix for this problem though. This patch try to silence a warning purely because it can happen on dead code, otherwise perfectly valid warning. My point is that, it can happen on dead code is not a valid reason to weaken the warning. Sparse can give any possible warning on dead code. e.g. On the dead code path, you can construct an address space warning. Do we weakling the address space warning purely because it can happen on the dead code as well? Of course not. The same apply to any other sparse warnings. So if there is a bug, It is sparse did not know exactly which part of the code is dead on AST level. If you enable the "#if 0" inside expand_if_statement(), sparse can actually correctly expand "if (channel < 0)" into "return". Of course, it still can't handle jump into dead code situation, which is the reason that piece of code is not enabled in the first place. It needs more work. I think that is a better approach than just random weakening some warnings on dead code path. Chris ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-29 3:09 ` Christopher Li @ 2014-06-30 17:49 ` Christopher Li 2014-06-30 18:32 ` Christopher Li 0 siblings, 1 reply; 10+ messages in thread From: Christopher Li @ 2014-06-30 17:49 UTC (permalink / raw) To: Josh Triplett Cc: Dan Carpenter, Hartley Sweeten, Marcos A. Di Pietro, devel@driverdev.osuosl.org, Linux-Sparse On Sat, Jun 28, 2014 at 8:09 PM, Christopher Li <sparse@chrisli.org> wrote: > So if there is a bug, It is sparse did not know exactly which part > of the code is dead on AST level. If you enable the "#if 0" inside I am thinking about how to fix the dead code issue. Try to do more than trivial dead code analyses is really not the right place for AST. Actually, there is a simple way out. We can just move the warning to the linearize instruction level. $ ./test-linearize /tmp/test_shift.c /tmp/test_shift.c:8:26: warning: shift too big (4294967295) for type int main: .L0x7f8f490e5010: <entry-point> # call %r1 <- filter, $0xffffffff ret.32 $0 You see, once drop into the instruction level, sparse already know that code is dead. Since the sparse is already linearizing instruction to perform the context check. We just need to move the warning from AST to instruction level. The warning should be trivial in instruction level. We are looking for an instruction has larger than type size constant shift value. Comments and feed backs, even patches? Chris ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse 2014-06-30 17:49 ` Christopher Li @ 2014-06-30 18:32 ` Christopher Li 0 siblings, 0 replies; 10+ messages in thread From: Christopher Li @ 2014-06-30 18:32 UTC (permalink / raw) To: Josh Triplett Cc: devel@driverdev.osuosl.org, Linux-Sparse, Marcos A. Di Pietro, Dan Carpenter On Mon, Jun 30, 2014 at 10:49 AM, Christopher Li <sparse@chrisli.org> wrote: > The warning should be trivial in instruction level. We are looking > for an instruction has larger than type size constant shift > value. Actually, just try it. Not as trivial as I thought. The problem is that, in the instruction level, sparse will optimize away the shift instruction when it see a larger than type size shift. The finial instruction level don't see the big constant shift any way. Need to catch it before the instruction get optimized away. That is unfortunate. If we check it too early, we can't tell it is in the dead code. If we check it too late, the instruction itself get optimized away. Chris ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-06-30 18:32 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <53965E53.5080504@gmail.com> [not found] ` <20140610054741.GE5500@mwanda> [not found] ` <DC148C5AA1CEBA4E87973D432B1C2D8825E9AE6A@P3PWEX4MB008.ex4.secureserver.net> [not found] ` <20140611065612.GQ5015@mwanda> [not found] ` <DC148C5AA1CEBA4E87973D432B1C2D8825E9CBD6@P3PWEX4MB008.ex4.secureserver.net> 2014-06-11 21:24 ` [PATCH] Staging/comedi: Fixes static analysis warning raised by sparse Dan Carpenter 2014-06-11 21:45 ` josh 2014-06-15 19:32 ` Sam Ravnborg 2014-06-16 7:40 ` Dan Carpenter 2014-06-16 8:06 ` Sam Ravnborg 2014-06-28 18:07 ` Christopher Li 2014-06-28 19:20 ` Josh Triplett 2014-06-29 3:09 ` Christopher Li 2014-06-30 17:49 ` Christopher Li 2014-06-30 18:32 ` Christopher Li
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).