diff options
author | Jason Merrill <jason@redhat.com> | 2009-11-05 22:33:17 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-11-05 22:33:17 -0500 |
commit | 040ca4b38fd75538442804d77b96f27df21fbd8f (patch) | |
tree | 7ebc951476c81c98d39e8f49916832f1dc4ea217 /gcc | |
parent | 2395cd2e91cda97a8d0bad70134f12534d4d3562 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/class.c | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/pragma-pack1.C | 37 |
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>()); +} |