This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA (stor-layout): PATCH for c++/65734 (attribute aligned and templates)


On 04/20/2015 10:35 AM, Jakub Jelinek wrote:
Wonder what will happen if finalize_type_size or fixup_attribute_variants
is called on a type variant with TYPE_USER_ALIGN before it is called
on the TYPE_MAIN_VARIANT; I'd guess that in that case all the variants
including the main variant would be marked as TYPE_USER_ALIGN and might have
incorrect TYPE_ALIGN.

Good point. Changing layout_type to always work on the TYPE_MAIN_VARIANT passes testing:



commit 0f520c7c862aa3c8850c3d3c024d19e4b8f1a757
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Apr 10 18:13:56 2015 -0400

    	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.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d80d312e..8103e60 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 f18f1ac..5bc8a29 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 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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]