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

Jason Merrill jason@redhat.com
Tue Apr 28 21:52:00 GMT 2020


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" }
> 



More information about the Gcc-patches mailing list