c++: Satisfaction caching of inherited ctor [PR94819]
authorPatrick Palka <ppalka@redhat.com>
Wed, 29 Apr 2020 01:45:59 +0000 (21:45 -0400)
committerPatrick Palka <ppalka@redhat.com>
Wed, 29 Apr 2020 01:45:59 +0000 (21:45 -0400)
As observed in PR94719, an inherited constructor for an instantiation of
a constructor template confusingly has as its DECL_INHERITED_CTOR the
TEMPLATE_DECL of the constructor template rather than the particular
instantiation of the template.

This means two inherited constructors for two different instantiations
of the same constructor template have the same DECL_INHERITED_CTOR.  And
since in satisfy_declaration_constraints our decl satisfaction cache is
keyed off of the result of strip_inheriting_ctors, we may end up
conflating the satisfaction values of the two inherited constructors'
constraints.

This patch fixes this issue by using the original tree, not the result
of strip_inheriting_ctors, as the key to the decl satisfaction cache.

gcc/cp/ChangeLog:

PR c++/94819
* constraint.cc (satisfy_declaration_constraints): Use saved_t
instead of t as the key to decl_satisfied_cache.

gcc/testsuite/ChangeLog:

PR c++/94819
* g++.dg/cpp2a/concepts-inherit-ctor10.C: New test.
* g++.dg/cpp2a/concepts-inherit-ctor11.C: New test.

gcc/cp/ChangeLog
gcc/cp/constraint.cc
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor11.C [new file with mode: 0644]

index c0558015eb8359ec67a25d1f671dfeef7ca989c3..f2bfe84b1e633578cd35af093f3149e4e1033dc1 100644 (file)
@@ -1,5 +1,9 @@
 2020-04-29  Patrick Palka  <ppalka@redhat.com>
 
+       PR c++/94819
+       * constraint.cc (satisfy_declaration_constraints): Use saved_t
+       instead of t as the key to decl_satisfied_cache.
+
        PR c++/94808
        * error.c (print_requires_expression_info): Print the dependent
        form of the parameter list with its template parameter mapping,
index 06161b8c8c4823a8ba87f22e6cfbe872e45973be..866b0f51b0532fb2f70fea38c595d8236e6a5646 100644 (file)
@@ -2752,7 +2752,7 @@ satisfy_declaration_constraints (tree t, subst_info info)
   info.in_decl = t;
 
   if (info.quiet ())
-    if (tree *result = hash_map_safe_get (decl_satisfied_cache, t))
+    if (tree *result = hash_map_safe_get (decl_satisfied_cache, saved_t))
       return *result;
 
   /* Get the normalized constraints.  */
@@ -2787,7 +2787,7 @@ satisfy_declaration_constraints (tree t, subst_info info)
     }
 
   if (info.quiet ())
-    hash_map_safe_put<hm_ggc> (decl_satisfied_cache, t, result);
+    hash_map_safe_put<hm_ggc> (decl_satisfied_cache, saved_t, result);
 
   return result;
 }
index a824ba8424ea14ef272c021bcc817f3defd31def..512974831c24862f82bb47fc8f0cc061f2a8be46 100644 (file)
@@ -1,5 +1,9 @@
 2020-04-29  Patrick Palka  <ppalka@redhat.com>
 
+       PR c++/94819
+       * g++.dg/cpp2a/concepts-inherit-ctor10.C: New test.
+       * g++.dg/cpp2a/concepts-inherit-ctor11.C: New test.
+
        PR c++/94808
        * g++.dg/concepts/diagnostic12.C: New test.
        * g++.dg/concepts/diagnostic5.C: Adjust dg-message.
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor10.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor10.C
new file mode 100644 (file)
index 0000000..387c07a
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/94819
+// { dg-do compile { target concepts } }
+
+struct dna4 {};
+struct rna4 {};
+
+struct alphabet_tuple_base {
+    template <typename component_type>
+        requires __is_same(component_type, rna4)
+    alphabet_tuple_base(component_type) {}
+};
+
+struct structured_rna : alphabet_tuple_base {
+    using alphabet_tuple_base::alphabet_tuple_base;
+};
+
+structured_rna t2{dna4{}}; // { dg-error "no match" }
+structured_rna t3{rna4{}}; // { dg-bogus "no match" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor11.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor11.C
new file mode 100644 (file)
index 0000000..947edd8
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/94819
+// { dg-do compile { target concepts } }
+
+struct dna4 {};
+struct rna4 {};
+
+template <typename component_types>
+struct alphabet_tuple_base {
+    template <typename component_type>
+        requires __is_same(component_type, component_types)
+    alphabet_tuple_base(component_type) {}
+};
+
+template <typename sequence_alphabet_t>
+struct structured_rna : alphabet_tuple_base<sequence_alphabet_t> {
+    using base_type = alphabet_tuple_base<sequence_alphabet_t>;
+    using base_type::base_type;
+};
+
+structured_rna<rna4> t2{dna4{}}; // { dg-error "no match" }
+structured_rna<rna4> t3{rna4{}}; // { dg-bogus "no match" }