[Bug c++/89056] Optimizer generates bad code for non-void function that fails to return a value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89056 --- Comment #7 from Jonathan Wakely --- (In reply to Darryl Okahata from comment #6) > I just wish the C++ standard instead just allowed an undefined value to be > returned, instead of generating bad optimized code. It does allow it. The behaviour is undefined, so anything is allowed. Nobody is claiming the standard *requires* GCC to do this. But it allows it. > With the current state, > I either have to add compiler-specific extensions or unreachable return > statements to insure that correct code is generated (unexpected and violates > POLA). Or fix the code. Your original example was buggy code. The warning told you about it. So fix the code. > The issue is that g++ (understandably) can't always detect if there > is always a proper return statement (execution can never hit the end of the > function). Grossly-oversimplified example (real code is much more > complicated): > > enum E { A, B }; > > bool bah(const enum E a) > { > if (a == A) > return false; > if (a == B) > return true; > } > > Compiling with (8.2.0): > > g++ -S -O badbad.cc > > gives: > > badbad.cc: In function 'bool bah(E)': > badbad.cc:10:1: warning: control reaches end of non-void function > [-Wreturn-type] > } > ^ If somebody calls bah((E)2) the function has undefined behaviour. Consider using the -fstrict-enums option if you want GCC to assume nobody creates invalid enum values. > Understandable, as I don't expect g++ to figure out complicated code > machinations. However, I don't know all the circumstances under which this > warning means that g++ is generating bad code. It only generates bad code *if the end of the function can be reached*. If you know it can't be reached, good for you. The warning is bogus in that case. Either suppress the warning for that function, or ignore the warning for that function. If you don't know for sure, and maybe the end of the function can be reached somehow, then the warning is useful and adding the return statement improves the code. This really does seem like whinging. Some warnings aren't perfect, but in your original report the warning was entirely right, and pointed out a bug that helps fix the code (if you actually heed the warning).
[Bug c++/89056] Optimizer generates bad code for non-void function that fails to return a value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89056 --- Comment #6 from Darryl Okahata --- (OK, at this point, I'm just whinging, so please feel free to ignore this.) I just wish the C++ standard instead just allowed an undefined value to be returned, instead of generating bad optimized code. With the current state, I either have to add compiler-specific extensions or unreachable return statements to insure that correct code is generated (unexpected and violates POLA). The issue is that g++ (understandably) can't always detect if there is always a proper return statement (execution can never hit the end of the function). Grossly-oversimplified example (real code is much more complicated): enum E { A, B }; bool bah(const enum E a) { if (a == A) return false; if (a == B) return true; } Compiling with (8.2.0): g++ -S -O badbad.cc gives: badbad.cc: In function 'bool bah(E)': badbad.cc:10:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ Understandable, as I don't expect g++ to figure out complicated code machinations. However, I don't know all the circumstances under which this warning means that g++ is generating bad code. As a result, I have to add unreachable return statements to insure that g++ does not generate bad optimized code. Our code runs on multiple platforms, and so I'd rather avoid the use of g++ extensions (e.g., __builtin_unreachable() or attributes) and cluttering #ifdefs. Adding an unreachable return is undesirable but simple and portable: enum E { A, B }; bool bah(const enum E a) { if (a == A) return false; if (a == B) return true; return false; // UNREACHABLE }
[Bug c++/89056] Optimizer generates bad code for non-void function that fails to return a value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89056 --- Comment #5 from Jonathan Wakely --- Yes, it allows it. It's undefined behaviour for your code to reach the end of the function (because there's no return statement) so the compiler assumes that the function will never reach that point. That means the loop must keep going (only exiting if one of the expressions in the loop throws an exception). If that's what you intended, then you can mark the function with the noreturn attribute to inform the compiler of your intention, or you can explicitly add __builtin_unreachable() at the end of the function. Either of those will suppress the warning. Of course that's not what you intended here, so you should heed the warning and fix the code.
[Bug c++/89056] Optimizer generates bad code for non-void function that fails to return a value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89056 --- Comment #4 from Darryl Okahata --- This seems rather draconian but, if the standard allows for that, so be it. Thanks.
[Bug c++/89056] Optimizer generates bad code for non-void function that fails to return a value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89056 --- Comment #3 from Andrew Pinski --- See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86761#c4 on the differences between C and C++.
[Bug c++/89056] Optimizer generates bad code for non-void function that fails to return a value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89056 --- Comment #2 from Andrew Pinski --- You can use -fsanatizer=undefined to find this behavior at runtime.
[Bug c++/89056] Optimizer generates bad code for non-void function that fails to return a value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89056 Andrew Pinski changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE --- Comment #1 from Andrew Pinski --- In C++ it is undefined what happens when a return happens without a value. This is different from C. So these returns are marked as calling __builtin_unreachable(). *** This bug has been marked as a duplicate of bug 86761 ***