Bug 8828 - [3.2/3.3/3.4 regression] gcc reports some code is unreachable when it is not
Summary: [3.2/3.3/3.4 regression] gcc reports some code is unreachable when it is not
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-12-05 13:06 UTC by rcampbell
Modified: 2004-01-17 04:22 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
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 rcampbell 2002-12-05 13:06:00 UTC
When gcc is run with "-Wunreachable-code", certain reachable code sections involving switch's generate warnings about unreachable code.

Here's "a.i"
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "a.c"
int b;

int func(int a)
{
  int j = 2;
  switch(a) {
    case 0:
      for(j=0; j<b; j++)
        j++;
      break;
    case 1:
      for(j=0; j<3; j++)
        j++;
      break;
  }
  return j;
}

When I compile it with
gcc -v -save-temps -Wunreachable-code -c a.c

I get:
Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.2/specs
Configured with: /netrel/src/gcc-3.2-3/configure --enable-languages=c,c++,f77,java --enable-libgcj --enable-threads=posix --with-system-zlib --enable-nls --without-included-gettext --enable-interpreter --disable-sjlj-exceptions --disable-version-specific-runtime-libs --enable-shared --build=i686-pc-linux --host=i686-pc-cygwin --target=i686-pc-cygwin --enable-haifa --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --includedir=/nonexistent/include --libexecdir=/usr/sbin
Thread model: posix
gcc version 3.2 20020927 (prerelease)
 /usr/lib/gcc-lib/i686-pc-cygwin/3.2/cpp0.exe -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=0 -D__GXX_ABI_VERSION=102 -D_X86_=1 -D_X86_=1 -Asystem=winnt -D__NO_INLINE__ -D__STDC_HOSTED__=1 -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i686__ -D__tune_pentiumpro__ -D__tune_pentium2__ -D__tune_pentium3__ -D__stdcall=__attribute__((__stdcall__)) -D__fastcall=__attribute__((__fastcall__)) -D__cdecl=__attribute__((__cdecl__)) -D_stdcall=__attribute__((__stdcall__)) -D_fastcall=__attribute__((__fastcall__)) -D_cdecl=__attribute__((__cdecl__)) -D__declspec(x)=__attribute__((x)) -D__i386__ -D__i386 -D__CYGWIN32__ -D__CYGWIN__ -Dunix -D__unix__ -D__unix -isystem /usr/lib/gcc-lib/i686-pc-cygwin/3.2/../../../../include/w32api -isystem /usr/lib/gcc-lib/i686-pc-cygwin/3.2/../../../../i686-pc-cygwin/lib/../../include/w32api a.c -Wunreachable-code a.i
GNU CPP version 3.2 20020927 (prerelease) (cpplib) (80386, BSD syntax)
ignoring nonexistent directory "/usr/i686-pc-cygwin/include"
ignoring duplicate directory "/usr/i686-pc-cygwin/lib/../../include/w32api"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/w32api
 /usr/local/include
 /usr/lib/gcc-lib/i686-pc-cygwin/3.2/include
 /usr/include
End of search list.
 /usr/lib/gcc-lib/i686-pc-cygwin/3.2/cc1.exe -fpreprocessed a.i -quiet -dumpbase a.c -Wunreachable-code -version -o a.s
GNU CPP version 3.2 20020927 (prerelease) (cpplib) (80386, BSD syntax)
GNU C version 3.2 20020927 (prerelease) (i686-pc-cygwin)
        compiled by GNU C version 3.2 20020927 (prerelease).
a.c: In function `func':
a.c:10: warning: will never be executed
a.c:14: warning: will never be executed

Release:
GNU C version 3.2 20020927 (prerelease) (i686-pc-cygwin)

Environment:
Cygwin 1.3.17 running under Win2000 (SP3)
Comment 1 Volker Reichelt 2002-12-06 01:29:11 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed.
    
    An even shorter example is the following:
    
    -----------------snip here----------------
    void foo(int i)
    {
      switch(i) {
        case 0:
          break;
        case 1:
          break;
      }
    }
    -----------------snip here----------------
    
    Compiling this with gcc 3.2.1 or mainline I get the message
    
    PR8828.c: In function `foo':
    PR8828.c:7: warning: will never be executed
    PR8828.c:5: warning: will never be executed
    
    i.e. the compiler complains about the "break" statements.
    
    This is a regression from gcc 3.0.4 where the warning is not issued.
Comment 2 rcampbell 2002-12-06 11:22:32 UTC
From: "Rolf Campbell" <rcampbell@tropicnetworks.com>
To: "Christian Ehrhardt" <ehrhardt@mathematik.uni-ulm.de>,
	<reichelt@igpm.rwth-aachen.de>,
	<gcc-bugs@gcc.gnu.org>,
	<gcc-prs@gcc.gnu.org>,
	<nobody@gcc.gnu.org>,
	<gcc-gnats@gcc.gnu.org>
Cc:  
Subject: RE: c/8828: gcc reports some code is unreachable when it is not
Date: Fri, 6 Dec 2002 11:22:32 -0500

 But, this was compiled WITHOUT optimizations (gcc -Wunreachable-code -c
 a.c), so there should be no removal of superfluous code, or folding of
 break statements.
 
 -Rolf
 
 > -----Original Message-----
 > From: Christian Ehrhardt [mailto:ehrhardt@mathematik.uni-ulm.de]=20
 > Sent: Friday, December 06, 2002 11:14 AM
 > To: reichelt@igpm.rwth-aachen.de; gcc-bugs@gcc.gnu.org;=20
 > gcc-prs@gcc.gnu.org; nobody@gcc.gnu.org; Rolf Campbell;=20
 > gcc-gnats@gcc.gnu.org
 > Subject: Re: c/8828: gcc reports some code is unreachable=20
 > when it is not
 >=20
 >=20
 > On Fri, Dec 06, 2002 at 09:29:12AM -0000,=20
 > reichelt@igpm.rwth-aachen.de wrote:
 > >     An even shorter example is the following:
 > >    =20
 > >     -----------------snip here----------------
 > >     void foo(int i)
 > >     {
 > >       switch(i) {
 > >         case 0:
 > >           break;
 > >         case 1:
 > >           break;
 > >       }
 > >     }
 > >     -----------------snip here----------------
 > >    =20
 > >     Compiling this with gcc 3.2.1 or mainline I get the message
 > >    =20
 > >     PR8828.c: In function `foo':
 > >     PR8828.c:7: warning: will never be executed
 > >     PR8828.c:5: warning: will never be executed
 >=20
 > Looks like warnings removed by the optimizer. In this case=20
 > the optimizer will just remove both of the empty case labels=20
 > and warn that the instructions therein (the breaks) aren't=20
 > executed. In the original example the break is probably=20
 > folded into the for loop an then optimized away. I even=20
 > managed to get warnings for code like
 > this:
 >=20
 > switch (i) {
 > 	case 0:
 > 		x++;
 > 		break;
 > 	case 1:
 > 		x++;
 > 		break;
 > }
 >=20
 > where the optimizer tells me that it removed one of the x++=20
 > instructions probably because the two case labels were=20
 > combined. This is probably not a bug, the documentation=20
 > doesn't explicitly mention optimizations but it does mention=20
 > that inlined function may produce warning for code that is=20
 > unreachable only in a single inlined copy. This case looks=20
 > rather similar.
 >=20
 >    regards   Christian
 >=20
 > --=20
 > THAT'S ALL FOLKS!
 >=20

Comment 3 Christian Ehrhardt 2002-12-06 17:13:43 UTC
From: "Christian Ehrhardt" <ehrhardt@mathematik.uni-ulm.de>
To: reichelt@igpm.rwth-aachen.de, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org,
  nobody@gcc.gnu.org, rcampbell@tropicnetworks.com, gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: c/8828: gcc reports some code is unreachable when it is not
Date: Fri, 6 Dec 2002 17:13:43 +0100

 On Fri, Dec 06, 2002 at 09:29:12AM -0000, reichelt@igpm.rwth-aachen.de wrote:
 >     An even shorter example is the following:
 >     
 >     -----------------snip here----------------
 >     void foo(int i)
 >     {
 >       switch(i) {
 >         case 0:
 >           break;
 >         case 1:
 >           break;
 >       }
 >     }
 >     -----------------snip here----------------
 >     
 >     Compiling this with gcc 3.2.1 or mainline I get the message
 >     
 >     PR8828.c: In function `foo':
 >     PR8828.c:7: warning: will never be executed
 >     PR8828.c:5: warning: will never be executed
 
 Looks like warnings removed by the optimizer. In this case the
 optimizer will just remove both of the empty case labels and warn
 that the instructions therein (the breaks) aren't executed. In
 the original example the break is probably folded into the for loop
 an then optimized away. I even managed to get warnings for code like
 this:
 
 switch (i) {
 	case 0:
 		x++;
 		break;
 	case 1:
 		x++;
 		break;
 }
 
 where the optimizer tells me that it removed one of the x++ instructions
 probably because the two case labels were combined. This is probably not
 a bug, the documentation doesn't explicitly mention optimizations but
 it does mention that inlined function may produce warning for code that
 is unreachable only in a single inlined copy. This case looks rather
 similar.
 
    regards   Christian
 
 -- 
 THAT'S ALL FOLKS!

Comment 4 Wolfgang Bangerth 2002-12-06 17:48:13 UTC
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: gcc-gnats@gcc.gnu.org
Cc: Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>,
   Volker Reichelt <reichelt@igpm.rwth-aachen.de>,
   <rcampbell@tropicnetworks.com>
Subject: Re: c/8828: gcc reports some code is unreachable when it is not
Date: Fri, 6 Dec 2002 17:48:13 -0600 (CST)

 Just for reference, I think this is actually a duplicate of PR 5230.
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth              email:           bangerth@ticam.utexas.edu
                                www: http://www.ticam.utexas.edu/~bangerth
 
 

Comment 5 Christian Ehrhardt 2002-12-07 01:58:19 UTC
From: "Christian Ehrhardt" <ehrhardt@mathematik.uni-ulm.de>
To: Rolf Campbell <rcampbell@tropicnetworks.com>
Cc: reichelt@igpm.rwth-aachen.de, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org,
  nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Subject: Re: c/8828: gcc reports some code is unreachable when it is not
Date: Sat, 7 Dec 2002 01:58:19 +0100

 On Fri, Dec 06, 2002 at 11:22:32AM -0500, Rolf Campbell wrote:
 > But, this was compiled WITHOUT optimizations (gcc -Wunreachable-code -c
 > a.c), so there should be no removal of superfluous code, or folding of
 > break statements.
 
 Even without optimization it is possible that some code is unused
 and removed. In this particular case the following case statement
 
 switch (i) {
 case 0:
    for (; i<2; i++)
       x++
    break;
 case 1:
    x++;break;
 }
 
 Is rewritten to look like this (even without optimization this is allowed):
 switch (i) {
 case 0:
 startfor:
    if (i>=2)
       goto caseend;
    x++; i++;
    goto startfor;
    break;
 case 1:
    x++;break;
 }
 caseend:
 
 which makes the first break statement unreachable. This is completly
 legal and the compiler is even right in some sense that the break
 statement is unreachable. Others should decide if this is actually a
 bug but the warning is off by default for a reason.
 
     regards   Christian
 
 -- 
 THAT'S ALL FOLKS!

Comment 6 janis187 2002-12-24 12:28:20 UTC
From: Janis Johnson <janis187@us.ibm.com>
To: gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org, rcampbell@tropicnetworks.com,
   gcc-bugs@gcc.gnu.org, nobody@gcc.gnu.org
Cc:  
Subject: Re: c/8828: [3.2/3.3 regression] gcc reports some code is unreachable 
 when it is not
Date: Tue, 24 Dec 2002 12:28:20 -0800

 The regression reported in PR c/8828 showed up starting
 with this patch:
 
 2002-02-12  Jakub Jelinek  <jakub@redhat.com>
 
         * jump.c (never_reached_warning): Add finish argument.
         If finish is NULL, stop on CODE_LABEL, otherwise stop before
 first
         real insn after end.
         * rtl.h (never_reached_warning): Adjust prototype.
         * cse.c (cse_insn): Pass NULL as finish to
 never_reached_warning.
         * cfgrtl.c (flow_delete_block): Pass b->end as finish to
         never_reached_warning.
 
 Here's a small test case that causes the compiler to issue
 warnings when compiled on i686-linux with -Wunreachable-code:
 
 -------------------
 /* incorrect(?) warnings with -Wunreachable-code */
 
 void foo(int i) {
   switch (i)    {
     case 0:         break;
     case 1:         break;
   };
 };
 -------------------
 
 Output from mainline gcc:
 
 8828.c: In function `foo':
 8828.c:6: warning: will never be executed
 8828.c:5: warning: will never be executed
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8828
 
 
 

Comment 7 s.bosscher 2003-02-15 20:56:34 UTC
From: Steven Bosscher <s.bosscher@student.tudelft.nl>
To: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org,
	rcampbell@tropicnetworks.com, nobody@gcc.gnu.org, gcc-prs@gcc.gnu.org
Cc:  
Subject: Re: c/8828: [3.2/3.3/3.4 regression] gcc reports some code is
	unreachable when it is not
Date: 15 Feb 2003 20:56:34 +0100

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8828
 
 We would incorrectly flag the case blocks as unreachable code (with
 -Wunreachable-code, or course) for this testcase:
 
 void foo (int i) {
   switch (i) {
     case 0: break;
     case 1: break;
   };
 };
 
 The problem seems to be that in the loop in
 jump.c:never_reached_warning() ignores barriers, so it happily falls
 through to the next basic block and thinks that the jump_insn for break
 is an unreachable insn.
 
 With the attached patch, we terminate the loop when we hit a barrier.
 
 I hardly tested this patch, but I've made sure that it bootstraps, fixes
 the testcase and does not break any of the test cases in the test suite
 that have the option "-Wunreachable-code".  I can't do a full regression
 test (just a bootstrap takes about half a day on my computer :-/), and
 it wouldn't even matter for the bootstrap because -Wunreachable-code is
 not set for "-Wall".
 
 There's also another change in behavior; for this test case:
 
 int x;
 void
 foo (int i)
 {
  switch (i) {
  case 0:
  startfor:
     goto caseend;
     x = 1;
  case 1:
     x = 1;
     break;
  }
  caseend:
  return;
 }
 
 We used to flag that the "goto caseend;" was unreachable code, instead
 of "x=1".  I think this is actually an example of this PR (8828), not
 warning about "x = 1" is probably the same bug as reported in PR c/5897.
 With this patch we don't have a warning for this code at all.  I think
 this still is better than having false positives.
 
 Can somebody with a better machine give this patch some propper testing?
 
 Greetz
 Steven
 
 Index: gcc/jump.c
 ===================================================================
 RCS file: /cvsroot/gcc/gcc/gcc/jump.c,v
 retrieving revision 1.216
 diff -c -3 -p -r1.216 jump.c
 *** gcc/jump.c	10 Jan 2003 13:44:28 -0000	1.216
 --- gcc/jump.c	15 Feb 2003 19:16:48 -0000
 *************** never_reached_warning (avoided_insn, fin
 *** 1918,1924 ****
   
     for (insn = avoided_insn; insn != NULL; insn = NEXT_INSN (insn))
       {
 !       if (finish == NULL && GET_CODE (insn) == CODE_LABEL)
   	break;
   
         if (GET_CODE (insn) == NOTE		/* A line number note?  */
 --- 1918,1925 ----
   
     for (insn = avoided_insn; insn != NULL; insn = NEXT_INSN (insn))
       {
 !       if ((finish == NULL && GET_CODE (insn) == CODE_LABEL)
 ! 	  || GET_CODE (insn) == BARRIER)
   	break;
   
         if (GET_CODE (insn) == NOTE		/* A line number note?  */
 

Comment 8 s.bosscher 2003-02-20 10:33:47 UTC
From: Steven Bosscher <s.bosscher@student.tudelft.nl>
To: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org,
	rcampbell@tropicnetworks.com, nobody@gcc.gnu.org, gcc-prs@gcc.gnu.org
Cc:  
Subject: Re: c/8828: [3.2/3.3/3.4 regression] gcc reports some code is unreachable
 when it is not
Date: Thu, 20 Feb 2003 10:33:47 +0100

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8828
 
 Approved patch pending:
 http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01317.html
 http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01597.html
 
 
Comment 9 Andreas Jaeger 2003-02-22 05:44:21 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: Steven's patch was applied to 3.2/3.3 and mainline.