aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-04-19 13:07:46 -0400
committerPatrick Palka <ppalka@redhat.com>2023-04-19 13:07:46 -0400
commit5e284ebbc3082c5a8974d24e3a0977aa48f3cc60 (patch)
treeb5bd4f7613203bcf18394c160b655c6850736145
parent6fc8e25cb6b5d720bedd85194b0ad740d75082f4 (diff)
downloadgcc-5e284ebbc3082c5a8974d24e3a0977aa48f3cc60.zip
gcc-5e284ebbc3082c5a8974d24e3a0977aa48f3cc60.tar.gz
gcc-5e284ebbc3082c5a8974d24e3a0977aa48f3cc60.tar.bz2
c++: bad ggc_free in try_class_unification [PR109556]
Aside from correcting how try_class_unification copies multi-dimensional 'targs', r13-377-g3e948d645bc908 also made it ggc_free this copy as an optimization. But this is wrong since the call to unify within might've captured the args in persistent memory such as the satisfaction cache (as part of constrained auto deduction). PR c++/109556 gcc/cp/ChangeLog: * pt.cc (try_class_unification): Don't ggc_free the copy of 'targs'. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-placeholder13.C: New test.
-rw-r--r--gcc/cp/pt.cc5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-placeholder13.C18
2 files changed, 18 insertions, 5 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index e065ace..68a056a 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -23895,11 +23895,6 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg,
err = unify (tparms, targs, CLASSTYPE_TI_ARGS (parm),
CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE, explain_p);
- if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs))
- for (tree level : tree_vec_range (targs))
- ggc_free (level);
- ggc_free (targs);
-
return err ? NULL_TREE : arg;
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder13.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder13.C
new file mode 100644
index 0000000..ac9f845
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder13.C
@@ -0,0 +1,18 @@
+// PR c++/109556
+// { dg-do compile { target c++20 } }
+
+template<class T, auto N>
+concept C = (N != 0);
+
+template<auto N, auto M>
+struct A { };
+
+template<auto N, C<N> auto M>
+void f(A<N, M>);
+
+int main() {
+ f(A<1, 42>{});
+ f(A<2, 42>{});
+ f(A<1, 43>{});
+ f(A<2, 43>{});
+}