[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Arsen Arsenović changed: What|Removed |Added CC||arsen at gcc dot gnu.org --- Comment #16 from Arsen Arsenović --- (In reply to Jason Merrill from comment #14) > It would certainly be possible to recognize this situation (all enumerators > handled) and suppress the -Wreturn-type warning even though we can't in > general assume that we can't get other values of the enumeration. With the > ability to explicitly request warnings in this situation with another flag. > I don't know how much work that would be. can't we assume that following the aforementioned https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1766 ? at least in C++>=17 (and, this bug should either be hijacked or remade for C++, probably)
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Eric Gallager changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=61864 --- Comment #15 from Eric Gallager --- (In reply to Martin Sebor from comment #12) > I do agree there is room for improvement here. Consider the following test > case: > > $ cat t.c && gcc -O2 -S -Wall -Wextra -Wpedantic -Wswitch-enum > -fdump-tree-optimized=/dev/stdout t.c > > enum E { e0 } e; > > int f (void) > { > switch (e) > case e0: return 0; > } > t.c: In function ‘f’: > t.c:7:1: warning: control reaches end of non-void function [-Wreturn-type] > 7 | } > | ^ > > ;; Function f (f, funcdef_no=0, decl_uid=1909, cgraph_uid=1, > symbol_order=1) > > f () > { > E e.0_1; > > [local count: 1073741824]: > e.0_1 = e; > if (e.0_1 == 0) > goto ; [50.00%] > else > goto ; [50.00%] > > [local count: 536870913]: > return 0; > > [local count: 536870913]: > return; > > } > > The -Wswitch-enum option doesn't warn about the switch statement not > handling switch values that don't correspond to any of the enumerators. To > have it diagnosed the -Wswitch-default option has to be explicitly specified > (it's off by default). > > Given that, I believe the same logic should apply to the -Wreturn-type > warning: it should not trigger for the snippet above or for the test case in > comment #0 unless explicitly requested somehow (perhaps it should consider > -Wswitch-default). kinda related here (w.r.t. other warnings considering whether -Wswitch-default is on or not): bug 61864 > > In addition, note the comparison to zero in the optimized GIMPLE. It's > unnecessary because the function returns no value when the value of e is > non-zero. Clang notices that and avoids the comparison. But perhaps a > better example to illustrate the missed optimization opportunity than the > contrived test case above is this: > > enum E { e0, e1, e2 } e; > > int f (void) > { > switch (e) > { > case e0: return 1; > case e1: return 2; > case e2: return 3; > } > } > > Here, GCC also emits the same pointless comparison/branch: > > f: > movle(%rip), %eax > cmpl$2, %eax > ja .L2 > addl$1, %eax > ret > .L2: > ret
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Jason Merrill changed: What|Removed |Added CC||jason at gcc dot gnu.org --- Comment #14 from Jason Merrill --- It would certainly be possible to recognize this situation (all enumerators handled) and suppress the -Wreturn-type warning even though we can't in general assume that we can't get other values of the enumeration. With the ability to explicitly request warnings in this situation with another flag. I don't know how much work that would be.
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 --- Comment #13 from Martin Sebor --- *** Bug 87951 has been marked as a duplicate of this bug. ***
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Martin Sebor changed: What|Removed |Added Keywords||missed-optimization Status|RESOLVED|NEW Last reconfirmed||2018-11-09 CC||msebor at gcc dot gnu.org Resolution|INVALID |--- Ever confirmed|0 |1 --- Comment #12 from Martin Sebor --- I do agree there is room for improvement here. Consider the following test case: $ cat t.c && gcc -O2 -S -Wall -Wextra -Wpedantic -Wswitch-enum -fdump-tree-optimized=/dev/stdout t.c enum E { e0 } e; int f (void) { switch (e) case e0: return 0; } t.c: In function ‘f’: t.c:7:1: warning: control reaches end of non-void function [-Wreturn-type] 7 | } | ^ ;; Function f (f, funcdef_no=0, decl_uid=1909, cgraph_uid=1, symbol_order=1) f () { E e.0_1; [local count: 1073741824]: e.0_1 = e; if (e.0_1 == 0) goto ; [50.00%] else goto ; [50.00%] [local count: 536870913]: return 0; [local count: 536870913]: return; } The -Wswitch-enum option doesn't warn about the switch statement not handling switch values that don't correspond to any of the enumerators. To have it diagnosed the -Wswitch-default option has to be explicitly specified (it's off by default). Given that, I believe the same logic should apply to the -Wreturn-type warning: it should not trigger for the snippet above or for the test case in comment #0 unless explicitly requested somehow (perhaps it should consider -Wswitch-default). In addition, note the comparison to zero in the optimized GIMPLE. It's unnecessary because the function returns no value when the value of e is non-zero. Clang notices that and avoids the comparison. But perhaps a better example to illustrate the missed optimization opportunity than the contrived test case above is this: enum E { e0, e1, e2 } e; int f (void) { switch (e) { case e0: return 1; case e1: return 2; case e2: return 3; } } Here, GCC also emits the same pointless comparison/branch: f: movle(%rip), %eax cmpl$2, %eax ja .L2 addl$1, %eax ret .L2: ret
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Richard Biener changed: What|Removed |Added Keywords||diagnostic Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #11 from Richard Biener --- .
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 --- Comment #10 from Martin Liška --- (In reply to Andrew Pinski from comment #9) > (In reply to Martin Liška from comment #8) > > Thank you Andrew for clarification of the behavior. Apparently it's quite > > common question. One note that I have about C behavior is that we can maybe > > also add -fstrict-enums to behave the same as in C++. Thoughts? > > No, we try not to add extensions which change well defined behavior to be > undefined behavior. Adding -fstrict-enums for C would cause just that. Good, then as mentioned explicit usage of __builtin_unreachable() will enable desired optimization. Then, let's close this as invalid?
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 --- Comment #9 from Andrew Pinski --- (In reply to Martin Liška from comment #8) > Thank you Andrew for clarification of the behavior. Apparently it's quite > common question. One note that I have about C behavior is that we can maybe > also add -fstrict-enums to behave the same as in C++. Thoughts? No, we try not to add extensions which change well defined behavior to be undefined behavior. Adding -fstrict-enums for C would cause just that.
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Martin Liška changed: What|Removed |Added CC||marxin at gcc dot gnu.org --- Comment #8 from Martin Liška --- Thank you Andrew for clarification of the behavior. Apparently it's quite common question. One note that I have about C behavior is that we can maybe also add -fstrict-enums to behave the same as in C++. Thoughts?
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 --- Comment #7 from Andrew Pinski --- (In reply to Vitali from comment #6) > Actually as of C++17 it's undefined behaviour. > > http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1766 > > so at the very least when compiled with C++17 the compiler should be smart > enough to strengthen the control flow analysis. Open a C++ bug then rather than reusing a C bug report ...
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Vitali changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #6 from Vitali --- Actually as of C++17 it's undefined behaviour. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1766 so at the very least when compiled with C++17 the compiler should be smart enough to strengthen the control flow analysis.
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Andrew Pinski changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #4 from Andrew Pinski --- (In reply to Vitali from comment #2) > Why has clang made a different decision? Also, this warning is present in > C++ code too. You need to ask clang why they made that decision. C rules are clear about value ranges of enums and all. In C++, (unlike C), out of ranges are just unspecified rather than undefined. This means the warning is correct too. NOTE there is a big difference between the three: implmenentation defined, undefined and unspecified behaviors. implmenentation defined is behavior that needs to be documented. Undefined behavior means the behavior can be different at different runs. unspecified behaviors means the behavior does not need to be documented but it has to be constitiant between runs. So there is no bug here again. See PR12242 also about a warning for the unspecified behavior when doing the conversion; NOTE it is not undefined which is different. See also https://gcc.gnu.org/ml/gcc-patches/2010-04/msg01694.html . Also see PR 53479 for the C++ side of the warning too (for enum classes). --- Comment #5 from Andrew Pinski --- (In reply to Vitali from comment #2) > Why has clang made a different decision? Also, this warning is present in > C++ code too. You need to ask clang why they made that decision. C rules are clear about value ranges of enums and all. In C++, (unlike C), out of ranges are just unspecified rather than undefined. This means the warning is correct too. NOTE there is a big difference between the three: implmenentation defined, undefined and unspecified behaviors. implmenentation defined is behavior that needs to be documented. Undefined behavior means the behavior can be different at different runs. unspecified behaviors means the behavior does not need to be documented but it has to be constitiant between runs. So there is no bug here again. See PR12242 also about a warning for the unspecified behavior when doing the conversion; NOTE it is not undefined which is different. See also https://gcc.gnu.org/ml/gcc-patches/2010-04/msg01694.html . Also see PR 53479 for the C++ side of the warning too (for enum classes).
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Andrew Pinski changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #4 from Andrew Pinski --- (In reply to Vitali from comment #2) > Why has clang made a different decision? Also, this warning is present in > C++ code too. You need to ask clang why they made that decision. C rules are clear about value ranges of enums and all. In C++, (unlike C), out of ranges are just unspecified rather than undefined. This means the warning is correct too. NOTE there is a big difference between the three: implmenentation defined, undefined and unspecified behaviors. implmenentation defined is behavior that needs to be documented. Undefined behavior means the behavior can be different at different runs. unspecified behaviors means the behavior does not need to be documented but it has to be constitiant between runs. So there is no bug here again. See PR12242 also about a warning for the unspecified behavior when doing the conversion; NOTE it is not undefined which is different. See also https://gcc.gnu.org/ml/gcc-patches/2010-04/msg01694.html . Also see PR 53479 for the C++ side of the warning too (for enum classes). --- Comment #5 from Andrew Pinski --- (In reply to Vitali from comment #2) > Why has clang made a different decision? Also, this warning is present in > C++ code too. You need to ask clang why they made that decision. C rules are clear about value ranges of enums and all. In C++, (unlike C), out of ranges are just unspecified rather than undefined. This means the warning is correct too. NOTE there is a big difference between the three: implmenentation defined, undefined and unspecified behaviors. implmenentation defined is behavior that needs to be documented. Undefined behavior means the behavior can be different at different runs. unspecified behaviors means the behavior does not need to be documented but it has to be constitiant between runs. So there is no bug here again. See PR12242 also about a warning for the unspecified behavior when doing the conversion; NOTE it is not undefined which is different. See also https://gcc.gnu.org/ml/gcc-patches/2010-04/msg01694.html . Also see PR 53479 for the C++ side of the warning too (for enum classes).
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Vitali changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #3 from Vitali --- Follow-up comment.
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 --- Comment #2 from Vitali --- Why has clang made a different decision? Also, this warning is present in C++ code too.
[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87950 Andrew Pinski changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #1 from Andrew Pinski --- In C, enum valid value range is the full int range. So all switch cases are not being handled even for valid C code.