The following code causes a wrong warning (I couldn't reduce it to less): #include <set> using namespace std; struct CExtendedEmailInfo { bool _s; }; struct CMetaBitField { int _type; int GetType() const{ return _type; } bool operator < (const CMetaBitField&) const { return true; } }; int GetMetaCombination (CExtendedEmailInfo& info) { try { if (info._s) { set<CMetaBitField> _bitfields; set<CMetaBitField>::iterator bi; if (bi != _bitfields.end()) { const CMetaBitField& bf = *bi; switch (bf.GetType()) { case 0: { return 17; } break; case 1: { return 18; } break; default: // really shouldn't happen, but just in case... return 0; } } else { return 0; } } else { return 0; } } catch (...) { return -1; } } C:\Dev-Cpp\Projects\test-stlport\main_6.cpp In function 'int GetMetaCombination(CExtendedEmailInfo&)': 66 C:\Dev-Cpp\Projects\test-stlport\main_6.cpp [Warning] control reaches end of non-void function I am using: Using built-in specs. Target: i686-pc-mingw32 Configured with: /datal/gcc/gcc/configure --prefix=/datal/gcc/build/wingcc --build=i686-pc-linux-gnu --host=i686-pc-mingw32 --target=i686-pc-mingw32 --enable-languages=c,c++,java --with-gcc --with-gnu-as --with-gnu-ld --enable-threads=win32 --disable-nls --disable-win32-registry --disable-shared --disable-debug --without-newlib --enable-libgcj --disable-java-awt --without-x --enable-java-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchronization --enable-sjlj-exceptions --enable-libgcj-multifile --enable-libgcj-mingw-osapi=ansi Thread model: win32 gcc version 4.0.0 20050324 (prerelease)
Created attachment 8482 [details] preprocessed source
Reduced testcase: struct a{~a();a();}; int GetMetaCombination (int a2) { a bi; switch (a2) { case 1: return 18; break;//removing this works around the warning default: return 0; } }
This is also a rejects valid with -Werror.
Removing rejects-valid; treating all incorrect warnings as rejects-valid due to -Werror is not useful.
*** Bug 20918 has been marked as a duplicate of this bug. ***
Hmm, seems like anything after a "return" should be removed even before CFG was created: return D.1766; goto <D1765>; I think I might get around to implementing that but it might take me some time.
This is a dup of bug 20624, see comment #13. I wonder why useless did not remove the goto. *** This bug has been marked as a duplicate of 20624 ***
Reopening as I have a fix for PR 20624 but this one is harder, there might be others too.
Why is this marked as a C++ front-end bug? Isn't this a middle-end problem?
Subject: Re: [4.0/4.1 Regression] wrong "control reaches" warning with switches > > > > ------- Comment #9 from mmitchel at gcc dot gnu dot org 2005-10-17 00:41 ------- > Why is this marked as a C++ front-end bug? Isn't this a middle-end problem? Because there is a "work around" in the C front-end, that could be copied into the C++ front-end. -- Pinski
For the record, this is the work-around in the C frontend: http://gcc.gnu.org/ml/gcc-patches/2005-01/msg01452.html A corresponding patch in the C++ frontend would be more complicated, in order to continue to emit the error "break statement not within loop or switch" when required. This class of bugs is a pain to work with at present. The warning just follows the CFG, which makes sense. But code like case 1: return; break; builds a CFG which has a return followed by a goto. remove_useless_stmts is currently not clever enough to remove code after a return, so the goto gets incorporated into the CFG. Note that we don't get the warning when optimizing; we only get it with -O0. And indeed when not optimizing the assembly code has the code path which returns an uninitialized value, although of course it never gets executed in practice. Fixing this in the middle-end will require a version of remove_useless_stmts which is clever enough to efficiently discard statements which follow a return statement. Andrew was working on that at one point; I don't recall what the status is.
Subject: Re: [4.0/4.1 Regression] wrong "control reaches" warning with switches On Oct 17, 2005, at 12:39 AM, ian at airs dot com wrote: > Fixing this in the middle-end will require a version of > remove_useless_stmts > which is clever enough to efficiently discard statements which follow > a return > statement. Andrew was working on that at one point; I don't recall > what the > status is. The status is that it will only be approved for 4.2 (this was decided by RTH). The problem is also comes into play with extra unreachable labels which was not going to be fixed by my patch and is what really causes this bug, rather than the stuff after a goto/return. We lower the eh before removing the unreachable label which causes us to think that there is a way to get fallthrough the switch. This means that we need a switch table for cleanup of the variable (the call to the dtor). -- Pinski
Given the kind of solutions we're looking at, I can't imagine this being fixed for 4.0, and probably not even for 4.1, so I've set this to P4. However, it seems sad to me that we can't find some efficient way to skip statements after a return at -O0. If we really can't do that, then we ought to think hard about whether or not we should be emitting this warning at -O0, given that we want to do this warning via the optimization framework.
*** Bug 25390 has been marked as a duplicate of this bug. ***
one more valid code rejected by 4.1/4.2: typedef enum { foo, bar } e; int zoo( e __e ) { switch ( __e ) { case foo: return -1; case bar: return +1; } } $ x86_64-gnu-linux-g++ bug.cpp -c -Wall -O2 bug.cpp: In function 'int zoo(e)': bug.cpp:9: warning: control reaches end of non-void function
(In reply to comment #15) > one more valid code rejected by 4.1/4.2: > > typedef enum { foo, bar } e; > int zoo( e __e ) > { > switch ( __e ) > { > case foo: return -1; > case bar: return +1; > } > } > > $ x86_64-gnu-linux-g++ bug.cpp -c -Wall -O2 > bug.cpp: In function 'int zoo(e)': > bug.cpp:9: warning: control reaches end of non-void function > ohh, 3.3.6 also fails.
(In reply to comment #16) > ohh, 3.3.6 also fails. That is a different issue and really should be filed in a different bug. The issue there is C++'s enums are only defined for those two values.
(In reply to comment #17) > (In reply to comment #16) > > ohh, 3.3.6 also fails. > > That is a different issue and really should be filed in a different bug. The > issue there is C++'s enums are only defined for those two values. reported in PR28236
won't fix for GCC-4.0.x
*** Bug 31783 has been marked as a duplicate of this bug. ***
Closing 4.1 branch.
(In reply to comment #2) > Reduced testcase: > struct a{~a();a();}; > int GetMetaCombination (int a2) > { > a bi; > switch (a2) > { > case 1: > return 18; > break;//removing this works around the warning > default: > return 0; > } > } This also fails in gcc-4.2 (GCC) 4.2.4
*** Bug 38552 has been marked as a duplicate of this bug. ***
Closing 4.2 branch.
GCC 4.3.4 is being released, adjusting target milestone.
GCC 4.3.5 is being released, adjusting target milestone.
*** Bug 45497 has been marked as a duplicate of this bug. ***
*** Bug 47864 has been marked as a duplicate of this bug. ***
Further reduced test case from dup bug 47864: $ nl t.cc ; g++ -finstrument-functions -Wreturn-type -Werror -c t.cc 1 int foo(int type) { 2 switch(type) { 3 case 0: return 1; break; 4 default: return 0; 5 } 6 } cc1plus: warnings being treated as errors t.cc: In function ‘int foo(int)’: t.cc:6: error: control reaches end of non-void function (in 4.4.3)
4.3 branch is being closed, moving to 4.4.7 target.
gcc -Wreturn-type -c r.c r.c: In function 'bar': r.c:8:1: warning: control reaches end of non-void function [-Wreturn-type] enum foo { e_1 }; int bar(enum foo x) { switch(x) { case e_1: return 0; } } gcc version 4.7.0 20111115 (experimental) [trunk revision 181378] (GCC)
(In reply to comment #31) > gcc -Wreturn-type -c r.c > r.c: In function 'bar': > r.c:8:1: warning: control reaches end of non-void function [-Wreturn-type] > > enum foo { e_1 }; > int bar(enum foo x) > { > switch(x) { > case e_1: > return 0; > } > } Not a bug, enum foo can have other values except e_1. What happens if you call bar( (foo)1 ) ?
> Not a bug, enum foo can have other values except e_1. > > What happens if you call bar( (foo)1 ) ? sorry for noise :( You are right - no error in c#31
Author: jason Date: Fri Jan 13 20:06:16 2012 New Revision: 183161 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=183161 Log: PR c++/20681 * semantics.c (finish_break_stmt): Avoid adding an unreachable BREAK_STMT. Added: trunk/gcc/testsuite/g++.dg/warn/Wreturn-type-7.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/semantics.c trunk/gcc/testsuite/ChangeLog
Fixed for 4.7. Could backport if there's interest.
4.4 branch is being closed, moving to 4.5.4 target.
Closing as fixed.