aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-06-07 14:19:53 -0400
committerPatrick Palka <ppalka@redhat.com>2022-09-12 17:05:34 -0400
commitc3ba0eaaa223f7b8208d279e3f39ff134912f9e9 (patch)
tree7053a8ee00c8cae538a5c5a6f7d7559482972224 /gcc/cp
parent03381beccb52c0e2c15da3b8b8dfa3bb6eb71df9 (diff)
downloadgcc-c3ba0eaaa223f7b8208d279e3f39ff134912f9e9.zip
gcc-c3ba0eaaa223f7b8208d279e3f39ff134912f9e9.tar.gz
gcc-c3ba0eaaa223f7b8208d279e3f39ff134912f9e9.tar.bz2
c++: template-id arguments are evaluated [PR101906]
Here we're neglecting to clear cp_unevaluated_operand when substituting into the arguments of the alias template-id 'skip<(T(), 0), T>' with T=A, which means cp_unevaluated_operand remains set during mark_used for A::A() and so we don't synthesize it. Later constant evaluation for the substituted template argument '(A(), 0)' (from coerce_template_parms) fails with "'constexpr A::A()' used before its definition" since it was never synthesized. This doesn't happen with a class template because tsubst_aggr_type clears cp_unevaluated_operand during substitution thereof. But since template arguments are generally manifestly constant-evaluated, which in turn are evaluated even in an unevaluated operand, we should be clearing cp_unevaluated_operand more broadly whenever substituting into any set of template arguments. To that end this patch makes us clear it during tsubst_template_args. PR c++/101906 gcc/cp/ChangeLog: * pt.cc (tsubst_template_args): Set cp_evaluated here. (tsubst_aggr_type): Not here. gcc/testsuite/ChangeLog: * g++.dg/template/evaluated1.C: New test. * g++.dg/template/evaluated1a.C: New test. * g++.dg/template/evaluated1b.C: New test. * g++.dg/template/evaluated1c.C: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/pt.cc6
1 files changed, 3 insertions, 3 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 31e3e39..4c6b343 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13616,6 +13616,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (t == error_mark_node)
return error_mark_node;
+ /* In "sizeof(X<I>)" we need to evaluate "I". */
+ cp_evaluated ev;
+
const int len = TREE_VEC_LENGTH (t);
tree *elts = XALLOCAVEC (tree, len);
int expanded_len_adjust = 0;
@@ -13888,9 +13891,6 @@ tsubst_aggr_type (tree t,
tree argvec;
tree r;
- /* In "sizeof(X<I>)" we need to evaluate "I". */
- cp_evaluated ev;
-
/* Figure out what arguments are appropriate for the
type we are trying to find. For example, given: