Message ID | 20240712185328.113699-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: alias template with dependent attributes [PR115897] | expand |
On 7/12/24 2:53 PM, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk/14? > > -- >8 -- > > Here we're prematurely stripping the dependent alias template-id A<T> to > its defining-type-id T when used as a template argument, which in turn > causes us to essentially ignore A's vector_size attribute. It seems this > has always been an issue for class template-ids, but after r14-2170 > variable template-ids are affected as well. > > To fix this, it seems natural to mark alias templates that have a > dependent attribute as complex, alongside e.g. constrained alias > templates, which prevents us from looking through them prematurely. > > PR c++/115897 > > gcc/cp/ChangeLog: > > * pt.cc (complex_alias_template_p): Return true for an alias > template with attributes. > (get_underlying_template): Don't look through an alias template > with attributes. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/alias-decl-77.C: New test. > --- > gcc/cp/pt.cc | 10 +++++++ > gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C | 32 ++++++++++++++++++++++ > 2 files changed, 42 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index e38e02488be..8239392923f 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -6628,6 +6628,11 @@ complex_alias_template_p (const_tree tmpl, tree *seen_out) > if (get_constraints (tmpl)) > return true; > > + /* An alias with dependent type attributes is complex. */ > + if (any_dependent_type_attributes_p (DECL_ATTRIBUTES > + (DECL_TEMPLATE_RESULT (tmpl)))) > + return true; > + > if (!complex_alias_tmpl_info) > complex_alias_tmpl_info = hash_map<const_tree, tree>::create_ggc (13); > > @@ -6780,6 +6785,11 @@ get_underlying_template (tree tmpl) > if (!at_least_as_constrained (underlying, tmpl)) > break; > > + /* If TMPL adds dependent attributes, it isn't equivalent. */ > + if (any_dependent_type_attributes_p (DECL_ATTRIBUTES > + (DECL_TEMPLATE_RESULT (tmpl)))) > + break; > + > /* Alias is equivalent. Strip it and repeat. */ > tmpl = underlying; > } > diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C > new file mode 100644 > index 00000000000..d518c040a92 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C > @@ -0,0 +1,32 @@ > +// PR c++/115897 > +// { dg-do compile { target c++11 } } > + > +template<class T, class U> > +struct is_same { static constexpr bool value = __is_same(T, U); }; > + > +#if __cpp_variable_templates > +template<class T, class U> > +constexpr bool is_same_v = __is_same(T, U); > +#endif > + > +template<class T> > +using A [[gnu::vector_size(16)]] = T; > + > +template<class T> > +using B = T; > + > +template<class T> > +using C [[gnu::vector_size(16)]] = B<T>; > + > +template<class T> > +void f() { > + static_assert(!is_same<T, A<T>>::value, ""); > + static_assert(!is_same<T, C<T>>::value, ""); How about a positive test that A<T> and C<T> are the same? OK with that change. > +#if __cpp_variable_templates > + static_assert(!is_same_v<T, A<T>>, ""); > + static_assert(!is_same_v<T, C<T>>, ""); > +#endif > +}; > + > +template void f<float>();
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index e38e02488be..8239392923f 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -6628,6 +6628,11 @@ complex_alias_template_p (const_tree tmpl, tree *seen_out) if (get_constraints (tmpl)) return true; + /* An alias with dependent type attributes is complex. */ + if (any_dependent_type_attributes_p (DECL_ATTRIBUTES + (DECL_TEMPLATE_RESULT (tmpl)))) + return true; + if (!complex_alias_tmpl_info) complex_alias_tmpl_info = hash_map<const_tree, tree>::create_ggc (13); @@ -6780,6 +6785,11 @@ get_underlying_template (tree tmpl) if (!at_least_as_constrained (underlying, tmpl)) break; + /* If TMPL adds dependent attributes, it isn't equivalent. */ + if (any_dependent_type_attributes_p (DECL_ATTRIBUTES + (DECL_TEMPLATE_RESULT (tmpl)))) + break; + /* Alias is equivalent. Strip it and repeat. */ tmpl = underlying; } diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C new file mode 100644 index 00000000000..d518c040a92 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C @@ -0,0 +1,32 @@ +// PR c++/115897 +// { dg-do compile { target c++11 } } + +template<class T, class U> +struct is_same { static constexpr bool value = __is_same(T, U); }; + +#if __cpp_variable_templates +template<class T, class U> +constexpr bool is_same_v = __is_same(T, U); +#endif + +template<class T> +using A [[gnu::vector_size(16)]] = T; + +template<class T> +using B = T; + +template<class T> +using C [[gnu::vector_size(16)]] = B<T>; + +template<class T> +void f() { + static_assert(!is_same<T, A<T>>::value, ""); + static_assert(!is_same<T, C<T>>::value, ""); + +#if __cpp_variable_templates + static_assert(!is_same_v<T, A<T>>, ""); + static_assert(!is_same_v<T, C<T>>, ""); +#endif +}; + +template void f<float>();