Patchwork C++ PATCH for c++/48138 (losing __attribute ((aligned)) on template argument)

login
register
mail settings
Submitter Jason Merrill
Date June 20, 2011, 2:23 p.m.
Message ID <4DFF57E3.7080407@redhat.com>
Download mbox | patch
Permalink /patch/101134/
State New
Headers show

Comments

Jason Merrill - June 20, 2011, 2:23 p.m.
strip_typedefs needs to propagate DECL_USER_ALIGN as well as attributes 
in the attribute list.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit fd43d02986ccbd7c43014ea093fe06f94d3d0af7
Author: Jason Merrill <jason@redhat.com>
Date:   Sun Jun 19 22:20:03 2011 -0400

    	PR c++/48138
    	* tree.c (strip_typedefs): Use build_aligned_type.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index c1824b4..3100508 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1167,6 +1167,16 @@  strip_typedefs (tree t)
 
   if (!result)
       result = TYPE_MAIN_VARIANT (t);
+  if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
+      || TYPE_ALIGN (t) != TYPE_ALIGN (result))
+    {
+      gcc_assert (TYPE_USER_ALIGN (t));
+      if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
+	result = build_variant_type_copy (result);
+      else
+	result = build_aligned_type (result, TYPE_ALIGN (t));
+      TYPE_USER_ALIGN (result) = true;
+    }
   if (TYPE_ATTRIBUTES (t))
     result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
   return cp_build_qualified_type (result, cp_type_quals (t));
diff --git a/gcc/testsuite/g++.dg/ext/attr-aligned01.C b/gcc/testsuite/g++.dg/ext/attr-aligned01.C
new file mode 100644
index 0000000..a051c6e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attr-aligned01.C
@@ -0,0 +1,20 @@ 
+// PR c++/48138
+// { dg-options -std=c++0x }
+
+#define ALIGNED(x) __attribute__((aligned(x)))
+#define SA(X) static_assert ((X),#X)
+
+template<typename T>
+void type_alignment(const T&) {
+  struct { char c; T t; } s;
+  SA((char*)&s.t - (char*)&s.c == 8);
+}
+
+int main() {
+  typedef char unaligned[15];
+  typedef char aligned[15] ALIGNED(8);
+
+  aligned z;
+  type_alignment(z);
+  type_alignment<unaligned ALIGNED(8)>(z);
+}