PR c++/7046
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 6 Nov 2009 03:33:17 +0000 (03:33 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 6 Nov 2009 03:33:17 +0000 (03:33 +0000)
* class.c (finish_struct): Store maximum_field_alignment in
TYPE_PRECISION.
* pt.c (instantiate_class_template): Set maximum_field_alignment.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153959 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/pragma-pack1.C [new file with mode: 0644]

index 0dfc57f..98cca71 100644 (file)
@@ -1,5 +1,10 @@
 2009-11-05  Jason Merrill  <jason@redhat.com>
 
+       PR c++/7046
+       * class.c (finish_struct): Store maximum_field_alignment in
+       TYPE_PRECISION.
+       * pt.c (instantiate_class_template): Set maximum_field_alignment.
+
        PR c++/34870
        * name-lookup.c (arg_assoc_class): Call complete_type.
        * pt.c (instantiate_class_template): Call uses_template_parms
index dc4c6b3..4020144 100644 (file)
@@ -5516,6 +5516,9 @@ finish_struct (tree t, tree attributes)
        if (DECL_PURE_VIRTUAL_P (x))
          VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
       complete_vars (t);
+
+      /* Remember current #pragma pack value.  */
+      TYPE_PRECISION (t) = maximum_field_alignment;
     }
   else
     finish_struct_1 (t);
index d4556cd..75180ea 100644 (file)
@@ -7352,6 +7352,7 @@ instantiate_class_template (tree type)
   tree typedecl;
   tree pbinfo;
   tree base_list;
+  unsigned int saved_maximum_field_alignment;
 
   if (type == error_mark_node)
     return error_mark_node;
@@ -7412,6 +7413,9 @@ instantiate_class_template (tree type)
   push_deferring_access_checks (dk_no_deferred);
 
   push_to_top_level ();
+  /* Use #pragma pack from the template context.  */
+  saved_maximum_field_alignment = maximum_field_alignment;
+  maximum_field_alignment = TYPE_PRECISION (pattern);
 
   SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
 
@@ -7827,6 +7831,7 @@ instantiate_class_template (tree type)
   perform_typedefs_access_check (pattern, args);
   perform_deferred_access_checks ();
   pop_nested_class ();
+  maximum_field_alignment = saved_maximum_field_alignment;
   pop_from_top_level ();
   pop_deferring_access_checks ();
   pop_tinst_level ();
index eedfe22..6d1786a 100644 (file)
@@ -1,5 +1,8 @@
 2009-11-05  Jason Merrill  <jason@redhat.com>
 
+       PR c++/7046
+       * g++.dg/abi/pragma-pack1.C: New.
+
        PR c++/34870
        * g++.dg/lookup/koenig7.C: New.
 
diff --git a/gcc/testsuite/g++.dg/abi/pragma-pack1.C b/gcc/testsuite/g++.dg/abi/pragma-pack1.C
new file mode 100644 (file)
index 0000000..d90fc20
--- /dev/null
@@ -0,0 +1,37 @@
+// PR c++/7046
+
+extern "C" int printf (const char *, ...);
+
+#pragma pack(4)
+
+template <typename X >
+struct T
+{
+    char      x1;   /* Usually 3 padding bytes are added after x1 member. */
+    int       x2;
+};
+
+template <class T>
+int f()
+{
+  struct A { char i1; int i2; };
+  return sizeof (A);
+}
+
+#pragma pack(1)
+template struct T<int>;   /* T<int> is instantiated here */
+template int f<int>();
+
+#pragma pack(4)
+template struct T<float>; /* T<float> is instantiated here */
+template int f<double>();
+
+int main()
+{
+  printf("sizeof T<int>   = %d\n", sizeof(T<int>));
+  printf("sizeof T<float> = %d\n", sizeof(T<float>));
+  printf("f<int>()        = %d\n", f<int>());
+  printf("f<float>()      = %d\n", f<float>());
+  return (sizeof(T<int>) != sizeof(T<float>)
+         || f<int>() != f<float>());
+}