[Bug c/87950] GCC warns about reaching end of non-void function when all switch cases are completely handled

2024-01-06 Thread arsen at gcc dot gnu.org via Gcc-bugs
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

2019-03-12 Thread egallager at gcc dot gnu.org
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

2018-12-11 Thread jason at gcc dot gnu.org
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

2018-12-10 Thread msebor at gcc dot gnu.org
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

2018-11-09 Thread msebor at gcc dot gnu.org
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

2018-11-09 Thread rguenth at gcc dot gnu.org
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

2018-11-09 Thread marxin at gcc dot gnu.org
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

2018-11-09 Thread pinskia at gcc dot gnu.org
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

2018-11-09 Thread marxin at gcc dot gnu.org
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

2018-11-08 Thread pinskia at gcc dot gnu.org
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

2018-11-08 Thread vlovich at gmail dot com
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

2018-11-08 Thread pinskia at gcc dot gnu.org
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

2018-11-08 Thread pinskia at gcc dot gnu.org
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

2018-11-08 Thread vlovich at gmail dot com
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

2018-11-08 Thread vlovich at gmail dot com
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

2018-11-08 Thread pinskia at gcc dot gnu.org
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.