]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: bad ggc_free in try_class_unification [PR109556]
authorPatrick Palka <ppalka@redhat.com>
Wed, 19 Apr 2023 17:07:46 +0000 (13:07 -0400)
committerPatrick Palka <ppalka@redhat.com>
Wed, 19 Apr 2023 17:07:46 +0000 (13:07 -0400)
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.

gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp2a/concepts-placeholder13.C [new file with mode: 0644]

index e065ace5c55c64bc13e8c154dd0f6e8bf84578d4..68a056acf8b6014325b259258d298e4abc74b701 100644 (file)
@@ -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 (file)
index 0000000..ac9f845
--- /dev/null
@@ -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>{});
+}