aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alignas5.C47
-rw-r--r--gcc/testsuite/g++.dg/ext/vector29.C53
5 files changed, 112 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 05ca52a..07fcef4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2016-01-23 Martin Sebor <msebor@redhat.com>
+
+ PR c++/58109
+ PR c++/69022
+ * decl2.c (is_late_template_attribute): Handle dependent argument
+ to attribute align and attribute vector_size.
+
2016-01-21 Jason Merrill <jason@redhat.com>
PR c++/69392
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a7212ca0..7d68961 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1193,7 +1193,8 @@ is_late_template_attribute (tree attr, tree decl)
second and following arguments. Attributes like mode, format,
cleanup and several target specific attributes aren't late
just because they have an IDENTIFIER_NODE as first argument. */
- if (arg == args && identifier_p (t))
+ if (arg == args && attribute_takes_identifier_p (name)
+ && identifier_p (t))
continue;
if (value_dependent_expression_p (t)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f6f0fdb..27d0389 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2016-01-23 Martin Sebor <msebor@redhat.com>
+
+ PR c++/58109
+ PR c++/69022
+ * g++.dg/cpp0x/alignas5.C: New test.
+ * g++.dg/ext/vector29.C: Same.
+
2016-01-23 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/chkp-strlen-2.c: Define _GNU_SOURCE.
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas5.C b/gcc/testsuite/g++.dg/cpp0x/alignas5.C
index 2820ca7..2dcc41f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alignas5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas5.C
@@ -1,6 +1,45 @@
-// { dg-do compile { target c++11 } }
+// PR c++/58109 - alignas() fails to compile with constant expression
+// { dg-do compile }
-#define SA(X) static_assert(X,#X)
+template <typename T>
+struct Base {
+ static const int Align = sizeof (T);
+};
-enum alignas(16) E {};
-SA(alignof(E) == 16);
+// 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;
diff --git a/gcc/testsuite/g++.dg/ext/vector29.C b/gcc/testsuite/g++.dg/ext/vector29.C
new file mode 100644
index 0000000..4a13009
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector29.C
@@ -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 ();
+}