diff options
author | Patrick Palka <ppalka@redhat.com> | 2024-05-21 15:54:10 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2024-05-21 15:54:10 -0400 |
commit | f0c0bced62b9c728ed1e672747aa234d918da22c (patch) | |
tree | 23043e9ee7b3d27eea9e73056daf2283199a3974 | |
parent | 9926c40a902edbc665919d508ef0c36f362f9c41 (diff) | |
download | gcc-f0c0bced62b9c728ed1e672747aa234d918da22c.zip gcc-f0c0bced62b9c728ed1e672747aa234d918da22c.tar.gz gcc-f0c0bced62b9c728ed1e672747aa234d918da22c.tar.bz2 |
c++: folding non-dep enumerator from current inst [PR115139]
After the tsubst_copy removal r14-4796-g3e3d73ed5e85e7 GCC 14 ICEs during
fold_non_dependent_expr for 'e1 | e2' below ultimately because we no
longer exit early when substituting the CONST_DECLs for e1 and e2 with
args=NULL_TREE and instead proceed to substitute the class context A<Ts...>
(also with args=NULL_TREE) which ends up ICEing from tsubst_pack_expansion
(due to processing_template_decl being cleared).
Incidentally, the ICE went away on trunk ever since the tsubst_aggr_type
removal r15-123-gf04dc89a991ddc since it changed the CONST_DECL case of
tsubst_expr to use tsubst to substitute the context, which short circuits
for empty args and so avoids the ICE.
This patch fixes this ICE for GCC 14 by narrowly restoring the early exit
for empty args that would've happened in tsubst_copy when substituting an
enumerator CONST_DECL. We might as well apply this to trunk too, as a
small optimization.
PR c++/115139
gcc/cp/ChangeLog:
* pt.cc (tsubst_expr) <case CONST_DECL>: Exit early if args
is empty.
gcc/testsuite/ChangeLog:
* g++.dg/template/non-dependent33.C: New test.
Reviewed-by: Marek Polacek <mpolacek@redhat.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
-rw-r--r-- | gcc/cp/pt.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/non-dependent33.C | 13 |
2 files changed, 14 insertions, 1 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index e77c48e..a95ce6e 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -21519,7 +21519,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (DECL_TEMPLATE_PARM_P (t)) RETURN (RECUR (DECL_INITIAL (t))); - if (!uses_template_parms (DECL_CONTEXT (t))) + if (!args || !uses_template_parms (DECL_CONTEXT (t))) RETURN (t); /* Unfortunately, we cannot just call lookup_name here. diff --git a/gcc/testsuite/g++.dg/template/non-dependent33.C b/gcc/testsuite/g++.dg/template/non-dependent33.C new file mode 100644 index 0000000..ea5b41f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent33.C @@ -0,0 +1,13 @@ +// PR c++/115139 +// { dg-do compile { target c++11 } } + +template<class... Ts> +class A { + enum E { + e1 = 1, + e2 = 2, + e3 = e1 | e2, + }; +}; + +template class A<int>; |