https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119149
Bug ID: 119149
Summary: Bogus "control reaches end of non-void function"
warning with ill-formed expression on RHS of comma
operator
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Keywords: diagnostic
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Target Milestone: ---
void g(long&);
int good(int i)
{
if (i > 0)
return i;
__builtin_abort();
g(i);
}
int bad(int i)
{
if (i > 0)
return i;
(__builtin_abort(), (void) g(i));
}
Both functions are ill-formed due to calling g(i) but the second one gives a
bogus warning:
warn.cc: In function 'int good(int)':
warn.cc:8:5: error: cannot bind non-const lvalue reference of type 'long int&'
to a value of type 'int'
8 | g(i);
| ^
warn.cc:1:8: note: initializing argument 1 of 'void g(long int&)'
1 | void g(long&);
| ^~~~~
warn.cc: In function 'int bad(int)':
warn.cc:15:32: error: cannot bind non-const lvalue reference of type 'long
int&' to a value of type 'int'
15 | (__builtin_abort(), (void) g(i));
| ^
warn.cc:1:8: note: initializing argument 1 of 'void g(long int&)'
1 | void g(long&);
| ^~~~~
warn.cc:16:1: warning: control reaches end of non-void function [-Wreturn-type]
16 | }
| ^
The problematic construct in the second one matches what libstdc++ does since
r15-7856-gd87c0d5443ba86
In std::expected::value() we have:
constexpr const _Tp&
value() const &
{
static_assert( is_copy_constructible_v<_Er> );
if (_M_has_value) [[likely]]
return _M_val;
_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
}
When the static_assert fails, the bad_expected_access<_Er>(_M_unex) expression
is ill-formed.
With -fexceptions we get the static_assert and an error for the ill-formed
bad_expected_access initialization (I would prefer to not get the latter, but
that's Bug 96286).
Previously with -fno-exceptions we would just get the failed static_assert, now
we get the failed static_assert and the ill-formed initialization, *and* a
-Wreturn-type warning.