The attached patch adds handling of dependent arguments to attribute aligned and attribute vector_size, fixing c++/58109 and 69022 - attribute vector_size ignored with dependent bytes.
Tested on x86_64. Martin
gcc/testsuite/ChangeLog: 2015-12-22 Martin Sebor <mse...@redhat.com> PR c++/58109 PR c++/69022 * g++.dg/cpp0x/alignas5.C: New test. * g++.dg/ext/vector29.C: Same. gcc/cp/ChangeLog: 2015-12-22 Martin Sebor <mse...@redhat.com> PR c++/58109 PR c++/69022 * decl2.c (is_late_template_attribute): Handle dependent argument to attribute align and attribute vector_size. Index: gcc/cp/decl2.c =================================================================== --- gcc/cp/decl2.c (revision 231903) +++ gcc/cp/decl2.c (working copy) @@ -1183,6 +1183,16 @@ if (args && PACK_EXPANSION_P (args)) return true; + if (is_attribute_p ("aligned", name) + || is_attribute_p ("vector_size", name)) + { + /* Attribute argument may be a dependent indentifier. */ + if (tree t = args ? TREE_VALUE (args) : NULL_TREE) + if (value_dependent_expression_p (t) + || type_dependent_expression_p (t)) + return true; + } + /* If any of the arguments are dependent expressions, we can't evaluate the attribute until instantiation time. */ for (arg = args; arg; arg = TREE_CHAIN (arg)) Index: gcc/testsuite/g++.dg/cpp0x/alignas5.C =================================================================== --- gcc/testsuite/g++.dg/cpp0x/alignas5.C (revision 0) +++ gcc/testsuite/g++.dg/cpp0x/alignas5.C (working copy) @@ -0,0 +1,45 @@ +// PR c++/58109 - alignas() fails to compile with constant expression +// { dg-do compile } + +template <typename T> +struct Base { + static const int Align = sizeof (T); +}; + +// Never instantiated. +template <typename T> +struct Derived: Base<T> +{ +#if __cplusplus >= 201102L + // This is the meat of the (simplified) regression test for c++/58109. + using B = Base<T>; + using B::Align; + + alignas (Align) char a [1]; + alignas (Align) T b [1]; +#else + // Fake the test for C++ 98. +# define Align Base<T>::Align +#endif + + char __attribute__ ((aligned (Align))) c [1]; + T __attribute__ ((aligned (Align))) d [1]; +}; + +// Instantiated to verify that the code is accepted even when instantiated. +template <typename T> +struct InstDerived: Base<T> +{ +#if __cplusplus >= 201102L + using B = Base<T>; + using B::Align; + + alignas (Align) char a [1]; + alignas (Align) T b [1]; +#endif + + char __attribute__ ((aligned (Align))) c [1]; + T __attribute__ ((aligned (Align))) d [1]; +}; + +InstDerived<int> dx; Index: gcc/testsuite/g++.dg/ext/vector29.C =================================================================== --- gcc/testsuite/g++.dg/ext/vector29.C (revision 0) +++ gcc/testsuite/g++.dg/ext/vector29.C (working copy) @@ -0,0 +1,53 @@ +// PR c++/69022 - attribute vector_size ignored with dependent bytes +// { dg-do compile } + +template <int N> +struct A { static const int X = N; }; + +#if __cplusplus >= 201202L +# define ASSERT(e) static_assert (e, #e) +#else +# define ASSERT(e) \ + do { struct S { bool: !!(e); } asrt; (void)&asrt; } while (0) +#endif + +template <class T, int N> +struct B: A<N> +{ +#if __cplusplus >= 201202L + using A<N>::X; +# define VecSize X +#else +# define VecSize A<N>::X +#endif + + static void foo () + { + char a __attribute__ ((vector_size (N))); + ASSERT (sizeof a == N); + + T b __attribute__ ((vector_size (N))); + ASSERT (sizeof b == N); + } + + static void bar () + { + char c1 __attribute__ ((vector_size (VecSize))); + ASSERT (sizeof c1 == VecSize); + + char c2 __attribute__ ((vector_size (A<N>::X))); + ASSERT (sizeof c2 == A<N>::X); + + T d1 __attribute__ ((vector_size (VecSize))); + ASSERT (sizeof d1 == VecSize); + + T d2 __attribute__ ((vector_size (A<N>::X))); + ASSERT (sizeof d2 == A<N>::X); + } +}; + +void bar () +{ + B<int, 16>::foo (); + B<int, 16>::bar (); +}