linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* 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).