diff options
author | Jason Merrill <jason@redhat.com> | 2015-04-28 10:43:48 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-04-28 10:43:48 -0400 |
commit | 7bfc5adac8d7151ed4c5ed13ed230f29c2102d9c (patch) | |
tree | 67cb947fcbac45db1e0afffa2d193017396302a4 | |
parent | 544f7fc84123aa03d37cc5325576f0db51d94ef8 (diff) | |
download | gcc-7bfc5adac8d7151ed4c5ed13ed230f29c2102d9c.zip gcc-7bfc5adac8d7151ed4c5ed13ed230f29c2102d9c.tar.gz gcc-7bfc5adac8d7151ed4c5ed13ed230f29c2102d9c.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/class.c | 13 | ||||
-rw-r--r-- | gcc/stor-layout.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alignas1.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alignas2.C | 20 |
6 files changed, 77 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1c59fd..3857fa0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-04-28 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-04-28 Yvan Roux <yvan.roux@linaro.org> * config/arm/arm.md (*arm_movt): Fix type attribute. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3f91187..b7c4720 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-04-28 Jason Merrill <jason@redhat.com> + + PR c++/65734 + * class.c (fixup_attribute_variants): Respect TYPE_USER_ALIGN. + 2015-04-27 Trevor Saunders <tbsaunde+gcc@tbsaunde.org> * class.c (layout_class_type): Remove check if diff --git a/gcc/cp/class.c b/gcc/cp/class.c index be5f5c2..c1548a0 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 1d1de99..38760b2 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 0000000..d73c875 --- /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 0000000..2e7d051 --- /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); |