summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-17 15:44:35 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-17 15:44:35 +0000
commit7efd805cd9a52b3023b95abb67e78262b613fa49 (patch)
tree3115962b3b5268cfa7c9b229ef639b9c69bbe6da
parentd7bf39711ad2367458a1705a49839cd4b84c82f8 (diff)
downloadgcc-7efd805cd9a52b3023b95abb67e78262b613fa49.tar.gz
PR c++/65734
gcc/ * stor-layout.c (layout_type): Layout the TYPE_MAIN_VARIANT. (finalize_type_size): Respect TYPE_USER_ALIGN. (layout_type) [ARRAY_TYPE]: Likewise. gcc/cp/ * class.c (fixup_attribute_variants): Respect TYPE_USER_ALIGN. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-5-branch@226941 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/class.c13
-rw-r--r--gcc/stor-layout.c24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alignas1.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alignas2.C20
6 files changed, 75 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b0736ed85cf..6d43958699a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-08-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/65734
+ * stor-layout.c (layout_type): Layout the TYPE_MAIN_VARIANT.
+ (finalize_type_size): Respect TYPE_USER_ALIGN.
+ (layout_type) [ARRAY_TYPE]: Likewise.
+
2015-08-17 Yvan Roux <yvan.roux@linaro.org>
Backport from mainline:
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6678f1d8381..222efbfc1d9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2015-08-17 Jason Merrill <jason@redhat.com>
+ PR c++/65734
+ * class.c (fixup_attribute_variants): Respect TYPE_USER_ALIGN.
+
PR c++/67104
* constexpr.c (cxx_eval_array_reference): Handle sparse
CONSTRUCTORs.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d59d351537d..f3ec826c865 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1989,14 +1989,23 @@ fixup_attribute_variants (tree t)
if (!t)
return;
+ tree attrs = TYPE_ATTRIBUTES (t);
+ unsigned align = TYPE_ALIGN (t);
+ bool user_align = TYPE_USER_ALIGN (t);
+
for (variants = TYPE_NEXT_VARIANT (t);
variants;
variants = TYPE_NEXT_VARIANT (variants))
{
/* These are the two fields that check_qualified_type looks at and
are affected by attributes. */
- TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
- TYPE_ALIGN (variants) = TYPE_ALIGN (t);
+ TYPE_ATTRIBUTES (variants) = attrs;
+ unsigned valign = align;
+ if (TYPE_USER_ALIGN (variants))
+ valign = MAX (valign, TYPE_ALIGN (variants));
+ else
+ TYPE_USER_ALIGN (variants) = user_align;
+ TYPE_ALIGN (variants) = valign;
}
}
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index f18f1ac5273..5bc8a291787 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -1831,9 +1831,13 @@ finalize_type_size (tree type)
{
TYPE_SIZE (variant) = size;
TYPE_SIZE_UNIT (variant) = size_unit;
- TYPE_ALIGN (variant) = align;
+ unsigned valign = align;
+ if (TYPE_USER_ALIGN (variant))
+ valign = MAX (valign, TYPE_ALIGN (variant));
+ else
+ TYPE_USER_ALIGN (variant) = user_align;
+ TYPE_ALIGN (variant) = valign;
TYPE_PRECISION (variant) = precision;
- TYPE_USER_ALIGN (variant) = user_align;
SET_TYPE_MODE (variant, mode);
}
}
@@ -2154,6 +2158,10 @@ layout_type (tree type)
if (type == error_mark_node)
return;
+ /* We don't want finalize_type_size to copy an alignment attribute to
+ variants that don't have it. */
+ type = TYPE_MAIN_VARIANT (type);
+
/* Do nothing if type has been laid out before. */
if (TYPE_SIZE (type))
return;
@@ -2350,13 +2358,17 @@ layout_type (tree type)
/* Now round the alignment and size,
using machine-dependent criteria if any. */
+ unsigned align = TYPE_ALIGN (element);
+ if (TYPE_USER_ALIGN (type))
+ align = MAX (align, TYPE_ALIGN (type));
+ else
+ TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
#ifdef ROUND_TYPE_ALIGN
- TYPE_ALIGN (type)
- = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (element), BITS_PER_UNIT);
+ align = ROUND_TYPE_ALIGN (type, align, BITS_PER_UNIT);
#else
- TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
+ align = MAX (align, BITS_PER_UNIT);
#endif
- TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
+ TYPE_ALIGN (type) = align;
SET_TYPE_MODE (type, BLKmode);
if (TYPE_SIZE (type) != 0
&& ! targetm.member_type_forces_blk (type, VOIDmode)
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas1.C b/gcc/testsuite/g++.dg/cpp0x/alignas1.C
new file mode 100644
index 00000000000..d73c875d637
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas1.C
@@ -0,0 +1,16 @@
+// PR c++/65734
+// { dg-do compile { target c++11 } }
+
+template <class T> struct A
+{
+ T t;
+};
+
+typedef A<int> T[4] alignas (2 * alignof (int));
+A<int> a[4];
+
+typedef A<char> T2[4] alignas (2 * alignof (int));
+
+#define SA(X) static_assert((X),#X)
+SA(alignof (T) == 2 * alignof(int));
+SA(alignof (T2) == 2 * alignof(int));
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas2.C b/gcc/testsuite/g++.dg/cpp0x/alignas2.C
new file mode 100644
index 00000000000..2e7d051c886
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas2.C
@@ -0,0 +1,20 @@
+// PR c++/65734
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+struct BVector
+{
+ T t;
+};
+BVector<int> m;
+
+template <template <class> class T>
+struct BV2
+{
+ typedef T<float> value_type alignas (16);
+ value_type v;
+};
+BV2<BVector> m2;
+
+#define SA(X) static_assert((X),#X)
+SA(alignof (BV2<BVector>::value_type) == 16);