https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124445
Bug ID: 124445
Summary: Variables with non-literal types accepted in constexpr
templates for C++20
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
struct S { S () : s (42) {} ~S () {} int s; };
#ifdef TMPL
template <int N>
#endif
constexpr bool
foo ()
{
if (__builtin_is_constant_evaluated ()) { return true; }
S s;
return true;
}
#ifdef TMPL
auto a = foo <42> ();
#else
auto a = foo ();
#endif
Both g++ and clang++ reject this with -std=c++20 if TMPL is not defined
g++ -S -std=c++20 -o /tmp/0.s /tmp/0.C
/tmp/0.C: In function ‘constexpr bool foo()’:
/tmp/0.C:9:5: error: variable ‘s’ of non-literal type ‘S’ in ‘constexpr’
function only available with ‘-std=c++23’ or ‘-std=gnu++23’
9 | S s;
| ^
/tmp/0.C:1:8: note: ‘S’ is not literal because:
1 | struct S { S () : s (42) {} ~S () {} int s; };
| ^
/tmp/0.C:1:8: note: ‘S’ does not have ‘constexpr’ destructor
clang++ -S -std=c++20 -o /tmp/0.s /tmp/0.C
/tmp/0.C:9:5: error: variable of non-literal type 'S' cannot be defined in a
constexpr function before C++23
9 | S s;
| ^
/tmp/0.C:1:8: note: 'S' is not literal because it is not an aggregate and has
no constexpr constructors other than copy or move constructors
1 | struct S { S () : s (42) {} ~S () {} int s; };
| ^
1 error generated.
but
g++ -S -DTMPL -std=c++20 -o /tmp/0.s /tmp/0.C
is quiet and
clang++ -S -DTMPL -std=c++20 -o /tmp/0.s /tmp/0.C
/tmp/0.C:9:5: error: variable of non-literal type 'S' cannot be defined in a
constexpr function before C++23
9 | S s;
| ^
/tmp/0.C:1:8: note: 'S' is not literal because it is not an aggregate and has
no constexpr constructors other than copy or move constructors
1 | struct S { S () : s (42) {} ~S () {} int s; };
| ^
/tmp/0.C:13:10: error: no matching function for call to 'foo'
13 | auto a = foo <42> ();
| ^~~~~~~~
/tmp/0.C:6:1: note: candidate template ignored: substitution failure [with N =
42]
6 | foo ()
| ^
2 errors generated.