From 7bfc5adac8d7151ed4c5ed13ed230f29c2102d9c Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 28 Apr 2015 10:43:48 -0400 Subject: [PATCH] re PR c++/65734 (Yet another case of lost alignment by stor_layout) 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. From-SVN: r222529 --- gcc/ChangeLog | 7 +++++++ gcc/cp/ChangeLog | 5 +++++ gcc/cp/class.c | 13 +++++++++++-- gcc/stor-layout.c | 24 ++++++++++++++++++------ gcc/testsuite/g++.dg/cpp0x/alignas1.C | 16 ++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/alignas2.C | 20 ++++++++++++++++++++ 6 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alignas1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/alignas2.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1c59fd6fa1..3857fa08e0b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-04-28 Jason Merrill + + 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-04-28 Yvan Roux * config/arm/arm.md (*arm_movt): Fix type attribute. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3f91187aa97..b7c4720c41c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-04-28 Jason Merrill + + PR c++/65734 + * class.c (fixup_attribute_variants): Respect TYPE_USER_ALIGN. + 2015-04-27 Trevor Saunders * class.c (layout_class_type): Remove check if diff --git a/gcc/cp/class.c b/gcc/cp/class.c index be5f5c22fff..c1548a0ae16 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 1d1de997363..38760b29a69 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1826,9 +1826,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); } } @@ -2149,6 +2153,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; @@ -2345,13 +2353,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 struct A +{ + T t; +}; + +typedef A T[4] alignas (2 * alignof (int)); +A a[4]; + +typedef A 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 +struct BVector +{ + T t; +}; +BVector m; + +template