From aae1e08cbd281be518d525d34685e3073e29577b Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 2 Jan 2013 14:03:46 -0500 Subject: [PATCH] re PR c++/55804 (GCC omits required call to constructor) PR c++/55804 PR c++/55032 PR c++/55245 * tree.c (build_array_type_1): Revert earlier change. * cp/tree.c (build_cplus_array_type): Copy layout information to main variant if necessary. From-SVN: r194813 --- gcc/ChangeLog | 5 ++++ gcc/cp/ChangeLog | 7 ++++++ gcc/cp/tree.c | 38 ++++++++++++++++++++++++----- gcc/testsuite/g++.dg/init/array33.C | 22 +++++++++++++++++ gcc/tree.c | 5 ---- 5 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/array33.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bf6be369800e..069c169f11ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2013-01-02 Jason Merrill + + PR c++/55804 + * tree.c (build_array_type_1): Revert earlier change. + 2012-12-26 John David Anglin PR target/53789 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f3048c182b77..b847830b3151 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2013-01-02 Jason Merrill + + PR c++/55032 + PR c++/55245 + * tree.c (build_cplus_array_type): Copy layout information + to main variant if necessary. + 2012-12-11 Jason Merrill PR c++/54883 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 4d5407073f5a..999eff35d8cd 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -702,6 +702,7 @@ tree build_cplus_array_type (tree elt_type, tree index_type) { tree t; + bool needs_ctor, needs_dtor; if (elt_type == error_mark_node || index_type == error_mark_node) return error_mark_node; @@ -756,6 +757,15 @@ build_cplus_array_type (tree elt_type, tree index_type) else t = build_array_type (elt_type, index_type); + /* Push these needs up so that initialization takes place + more easily. */ + needs_ctor + = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type)); + TYPE_NEEDS_CONSTRUCTING (t) = needs_ctor; + needs_dtor + = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type)); + TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = needs_dtor; + /* We want TYPE_MAIN_VARIANT of an array to strip cv-quals from the element type as well, so fix it up if needed. */ if (elt_type != TYPE_MAIN_VARIANT (elt_type)) @@ -764,18 +774,34 @@ build_cplus_array_type (tree elt_type, tree index_type) index_type); if (TYPE_MAIN_VARIANT (t) != m) { + if (COMPLETE_TYPE_P (t) && !COMPLETE_TYPE_P (m)) + { + /* m was built before the element type was complete, so we + also need to copy the layout info from t. */ + tree size = TYPE_SIZE (t); + tree size_unit = TYPE_SIZE_UNIT (t); + unsigned int align = TYPE_ALIGN (t); + unsigned int user_align = TYPE_USER_ALIGN (t); + enum machine_mode mode = TYPE_MODE (t); + tree var; + for (var = m; var; var = TYPE_NEXT_VARIANT (var)) + { + TYPE_SIZE (var) = size; + TYPE_SIZE_UNIT (var) = size_unit; + TYPE_ALIGN (var) = align; + TYPE_USER_ALIGN (var) = user_align; + SET_TYPE_MODE (var, mode); + TYPE_NEEDS_CONSTRUCTING (var) = needs_ctor; + TYPE_HAS_NONTRIVIAL_DESTRUCTOR (var) = needs_dtor; + } + } + TYPE_MAIN_VARIANT (t) = m; TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); TYPE_NEXT_VARIANT (m) = t; } } - /* Push these needs up so that initialization takes place - more easily. */ - TYPE_NEEDS_CONSTRUCTING (t) - = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type)); - TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) - = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type)); return t; } diff --git a/gcc/testsuite/g++.dg/init/array33.C b/gcc/testsuite/g++.dg/init/array33.C new file mode 100644 index 000000000000..4440d3d5432d --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array33.C @@ -0,0 +1,22 @@ +// PR c++/55804 +// { dg-do run } + +int t = 0; +template struct vector { + vector() { t++; } +}; + +typedef vector Arrays[1]; +class C +{ + vector v_; + void Foo(const Arrays &); +}; +Arrays a; + +int main(void) +{ + if (t!=1) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree.c b/gcc/tree.c index 7a0ac82a3d10..83a07117fe8e 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -7282,15 +7282,10 @@ build_array_type_1 (tree elt_type, tree index_type, bool shared) if (shared) { - tree old_t = t; hashval_t hashcode = iterative_hash_object (TYPE_HASH (elt_type), 0); if (index_type) hashcode = iterative_hash_object (TYPE_HASH (index_type), hashcode); t = type_hash_canon (hashcode, t); - if (t != old_t) - /* Lay it out again in case the element type has been completed since - the array was added to the hash table. */ - layout_type (t); } if (TYPE_CANONICAL (t) == t) -- 2.47.2