diff mbox series

c++: Satisfaction caching of inherited ctor [PR94819]

Message ID 20200428201338.1651152-1-ppalka@redhat.com
State New
Headers show
Series c++: Satisfaction caching of inherited ctor [PR94819] | expand

Commit Message

Patrick Palka April 28, 2020, 8:13 p.m. UTC
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 will 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 value 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.

Passes 'make check-c++', does this look OK to commit after a full
bootstrap and regtest?

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/constraint.cc                          |  4 ++--
 .../g++.dg/cpp2a/concepts-inherit-ctor10.C    | 18 ++++++++++++++++
 .../g++.dg/cpp2a/concepts-inherit-ctor11.C    | 21 +++++++++++++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor10.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor11.C

Comments

Jason Merrill April 28, 2020, 9:52 p.m. UTC | #1
On 4/28/20 4:13 PM, Patrick Palka wrote:
> 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 will 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 value 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.
> 
> Passes 'make check-c++', does this look OK to commit after a full
> bootstrap and regtest?

OK.

> 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/constraint.cc                          |  4 ++--
>   .../g++.dg/cpp2a/concepts-inherit-ctor10.C    | 18 ++++++++++++++++
>   .../g++.dg/cpp2a/concepts-inherit-ctor11.C    | 21 +++++++++++++++++++
>   3 files changed, 41 insertions(+), 2 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor10.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor11.C
> 
> diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> index 06161b8c8c4..866b0f51b05 100644
> --- a/gcc/cp/constraint.cc
> +++ b/gcc/cp/constraint.cc
> @@ -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;
>   }
> 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
> index 00000000000..387c07ae6b2
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor10.C
> @@ -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
> index 00000000000..947edd84e53
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor11.C
> @@ -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" }
>
diff mbox series

Patch

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 06161b8c8c4..866b0f51b05 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -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;
 }
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
index 00000000000..387c07ae6b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor10.C
@@ -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
index 00000000000..947edd84e53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor11.C
@@ -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" }