Bug 35170 - Suspected value range propagation [VRP] failure with ? :
Summary: Suspected value range propagation [VRP] failure with ? :
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.3.0
: P3 trivial
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-02-12 01:46 UTC by dps@simpson.demon.co.uk
Modified: 2008-02-12 10:53 UTC (History)
2 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dps@simpson.demon.co.uk 2008-02-12 01:46:56 UTC
There is at least one simple case that the value range deduction apparently fails to cover. The compiler generates a message about control reaching possibly the end of a non-void function given the source file:

#include <string.h>

int ns_strcmp(const char *a, const char *b)
{
    int i;
    i= (a==NULL) ? 0 : 1;
    i |= (b==NULL) ? 0 : 2;
    switch(i)
    {
    case 0:			/* a=NULL, b=NULL */
	return 0;		/* a=b */
	/* NOT REACHED */
    case 1:			/* a=NULL, b!=NULL */
	return -1;		/* a<b */
	/* NOT REACHED */
    case 2:			/* a!=NULL, b=NULL */
	return 1;		/* a>b */
	/* NOT REACHED */
    case 3:			/* a!=NULL, b!=NULL */
	return strcmp(a, b);	/* Use strcmp */
	/* NOT REACHED */
    }
    /* NOT REACHED */
}

Reaching the end of the function is clearly impossible because i must be 0, 1 after  i=(a==NULL) ? 0 : 1 and 0, 1, 2, 3 or after the i |= (b==NULL) ? 0 : 2. It would be nice if value range propagation could deduce that i>=0 and i<=3, after which it would be sufficient to notice that all the possible values are covered in the switch to deduce that the control can not reach beyond the switch.

However gcc seems to miss this fact, even with -O3, and the generated assembly seems to include coverage of both i<0 and i>3. Replacing |= with += does not eliminate the warning about control possibly reaching the end of a non-void function.

It would be even nicer if I could replace 2 with 4 and adjust the case values accordingly and still not get a warning but that would require propagation of more than a single value range. My processor is an AMD Athlon(tm) 64 X2 Dual Core Processor 4400+, although I suspect the logic that misses the relevant information is target independent.

I can avoid the warning by handling the last case after the switch.

host$ Linux dps 2.6.24 #9 SMP PREEMPT Sat Feb 2 18:17:42 GMT 2008 x86_64 GNU/Linux
host$ gcc --version
gcc (GCC) 4.3.0 20080209 (experimental)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

host$ gcc -c -O3 -Wall /tmp/message.c  
/tmp/message.c: In function ‘ns_strcmp’:
/tmp/message.c:24: warning: control reaches end of non-void function
Comment 1 Andrew Pinski 2008-02-12 01:54:59 UTC
> /tmp/message.c:24: warning: control reaches end of non-void function

this warning happens before VRP anyways.

This is related to PR 14495 (or really the same).