summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-11-05 22:33:17 -0500
committerJason Merrill <jason@gcc.gnu.org>2009-11-05 22:33:17 -0500
commit040ca4b38fd75538442804d77b96f27df21fbd8f (patch)
tree7ebc951476c81c98d39e8f49916832f1dc4ea217 /gcc
parent2395cd2e91cda97a8d0bad70134f12534d4d3562 (diff)
downloadgcc-040ca4b38fd75538442804d77b96f27df21fbd8f.tar.gz
re PR c++/7046 (#pragma pack(1) context evaluated at point of instantiation rather than declaration)
PR c++/7046 * class.c (finish_struct): Store maximum_field_alignment in TYPE_PRECISION. * pt.c (instantiate_class_template): Set maximum_field_alignment. From-SVN: r153959
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/class.c3
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/abi/pragma-pack1.C37
5 files changed, 53 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0dfc57f6048..98cca71b56c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index dc4c6b39c9a..4020144e815 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d4556cd527f..75180eabbe8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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 ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index eedfe229337..6d1786aa17b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..d90fc200cbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/pragma-pack1.C
@@ -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>());
+}