[Bug c++/89056] Optimizer generates bad code for non-void function that fails to return a value

2019-01-26 Thread redi at gcc dot gnu.org
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

2019-01-25 Thread darryl_okahata at keysight dot com
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

2019-01-25 Thread redi at gcc dot gnu.org
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

2019-01-24 Thread darryl_okahata at keysight dot com
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

2019-01-24 Thread pinskia at gcc dot gnu.org
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

2019-01-24 Thread pinskia at gcc dot gnu.org
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

2019-01-24 Thread pinskia at gcc dot gnu.org
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 ***