diff options
author | Jason Merrill <jason@redhat.com> | 2024-02-07 15:03:01 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2024-02-07 19:21:57 -0500 |
commit | 4797f0100b95802b2c043d64364ce9b77469a182 (patch) | |
tree | 383374e9694ea1683aa834747cf7264b788288e5 | |
parent | 0535c203c5b5ce9c7ae29fc8ba6288986fc3b34e (diff) | |
download | gcc-4797f0100b95802b2c043d64364ce9b77469a182.zip gcc-4797f0100b95802b2c043d64364ce9b77469a182.tar.gz gcc-4797f0100b95802b2c043d64364ce9b77469a182.tar.bz2 |
c++: class nttp ICE
The new testcase from P2308 crashed trying to expand 'this' without an
object to refer to, because we stripped the TARGET_EXPR in
create_template_parm_object. So let's leave it on for giving an error.
gcc/cp/ChangeLog:
* pt.cc (create_template_parm_object): Pass TARGET_EXPR to
cxx_constant_value.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/nontype-class64.C: New test.
-rw-r--r-- | gcc/cp/pt.cc | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/nontype-class64.C | 23 |
2 files changed, 26 insertions, 2 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 903a4a1..55c23b6 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -7308,14 +7308,15 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain) static tree create_template_parm_object (tree expr, tsubst_flags_t complain) { + tree orig = expr; if (TREE_CODE (expr) == TARGET_EXPR) expr = TARGET_EXPR_INITIAL (expr); if (!TREE_CONSTANT (expr)) { if ((complain & tf_error) - && require_rvalue_constant_expression (expr)) - cxx_constant_value (expr); + && require_rvalue_constant_expression (orig)) + cxx_constant_value (orig); return error_mark_node; } if (invalid_tparm_referent_p (TREE_TYPE (expr), expr, complain)) diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class64.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class64.C new file mode 100644 index 0000000..eb64892 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class64.C @@ -0,0 +1,23 @@ +// Testcase from P2308R1 +// { dg-do compile { target c++20 } } + +template<auto n> struct B { /* ... */ }; +B<5> b1; // OK, template parameter type is int +B<'a'> b2; // OK, template parameter type is char +B<2.5> b3; // OK, template parameter type is double +B<void(0)> b4; // { dg-error "void" } + +template<int i> struct C { /* ... */ }; +C<{ 42 }> c1; // OK + +struct J1 { + J1 *self=this; +}; +B<J1{}> j1; // { dg-error "not a constant expression" } + +struct J2 { + J2 *self=this; + constexpr J2() {} + constexpr J2(const J2&) {} +}; +B<J2{}> j2; // { dg-error "" } |