https://gcc.gnu.org/g:2249c6348835c817f43c9fc55eac66e54ac1efeb

commit r14-10450-g2249c6348835c817f43c9fc55eac66e54ac1efeb
Author: Patrick Palka <ppa...@redhat.com>
Date:   Mon Jul 15 18:07:55 2024 -0400

    c++: alias template with dependent attributes [PR115897]
    
    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 in the outer
    template-id.
    
    This has always been a problem for class template-ids it seems, and after
    r14-2170 variable template-ids are affected as well.
    
    This patch marks alias templates that have a dependent attribute as
    complex (as with e.g. constrained alias templates) so that we don't look
    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.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>
    (cherry picked from commit 7954bb4fcb6fa80f6bb840133314885011821188)

Diff:
---
 gcc/cp/pt.cc                               | 10 ++++++++++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C | 32 ++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 580c3fc2cb2b..83638fd74b4d 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -6655,6 +6655,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);
 
@@ -6807,6 +6812,11 @@ get_underlying_template (tree tmpl)
       if (!at_least_as_constrained (underlying, tmpl))
        break;
 
+      /* If TMPL adds dependent type 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 000000000000..f72e4cc26538
--- /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<C<T>, A<T>>::value, "");
+
+#if __cpp_variable_templates
+  static_assert(!is_same_v<T, A<T>>, "");
+  static_assert(is_same_v<C<T>, A<T>>, "");
+#endif
+};
+
+template void f<float>();

Reply via email to