Bug 35170

Summary: Earlier VRP would help -Wreturn-type
Product: gcc Reporter: dps <dps>
Component: middle-endAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: enhancement CC: gcc-bugs, manu, rguenth, sjames
Priority: P3 Keywords: diagnostic
Version: 4.3.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2016-08-19 00:00:00

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).
Comment 2 Manuel López-Ibáñez 2016-08-19 12:10:31 UTC
Confirm it so it does not appear in the list of UNCONFIRMED.