https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127095
Bug ID: 127095
Summary: constexpr assertions are disabled by
-fimplicit-constexpr
Product: gcc
Version: 15.3.1
Status: UNCONFIRMED
Keywords: accepts-invalid
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Target Milestone: ---
#include <vector>
constexpr int f()
{
std::vector<int> v{1,2,3};
v.clear();
return v.front();
}
static_assert( f() == 1 );
With -std=c++20 -D_GLIBCXX_NO_ASSERTIONS this diagnoses the precondition
violation:
vec.cc:10:20: error: non-constant condition for static assertion
10 | static_assert( f() == 1 );
| ~~~~^~~~
In file included from
/home/jwakely/gcc/15/include/c++/15.3.1/bits/requires_hosted.h:31,
from /home/jwakely/gcc/15/include/c++/15.3.1/vector:62,
from vec.cc:1:
vec.cc:10:17: in 'constexpr' expansion of 'f()'
vec.cc:7:17: in 'constexpr' expansion of 'v.std::vector<int>::front()'
/home/jwakely/gcc/15/include/c++/15.3.1/bits/stl_vector.h:1346:9: error: call
to non-'constexpr' function 'void std::__glibcxx_assert_fail()'
1346 | __glibcxx_requires_nonempty();
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/jwakely/gcc/15/include/c++/15.3.1/x86_64-pc-linux-gnu/bits/c++config.h:652:3:
note: 'void std::__glibcxx_assert_fail()' declared here
652 | __glibcxx_assert_fail()
| ^~~~~~~~~~~~~~~~~~~~~
But if -fimplicit-constexpr is added, GCC 15 compiles it without any error.
(For this specific example, GCC 16 diagnoses that v.front() is outside its
lifetime, so we do still get an error, just not the library assertion. Other
examples could be produced which GCC 16 accepts when it shouldn't. GCC 14
doesn't diagnose it with or without -fimplicit-constexpr.)
The problem is that the constexpr-only version of __glibcxx_assert calls an
inline-but-not-constexpr function, intending for that to cause constant
evaluation to fail:
#elif _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
// _GLIBCXX_ASSERTIONS is not defined, so assertions checks are only enabled
// during constant evaluation. This ensures we diagnose undefined behaviour
// in constant expressions.
namespace std
{
__attribute__((__always_inline__,__visibility__("default")))
inline void
__glibcxx_assert_fail()
{ }
}
# define __glibcxx_assert(cond) \
do { \
if (std::__is_constant_evaluated() && !bool(cond)) \
std::__glibcxx_assert_fail(); \
} while (false)
But with -fimplicit-constexpr it doesn't fail, the inline function can be
called, and it doesn't produce the desired error.