From: Jason Merrill Date: Fri, 16 Dec 2011 22:59:27 +0000 (-0500) Subject: re PR c++/51331 (bad code generated when explicitly calling auto-generated constructo... X-Git-Tag: releases/gcc-4.6.3~255 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78a8ed44d721a70e1fcebc72da9a9fec138a2fa1;p=thirdparty%2Fgcc.git re PR c++/51331 (bad code generated when explicitly calling auto-generated constructor of virtual base) PR c++/51331 * class.c (convert_to_base_statically): Just call build_simple_base_path. (build_simple_base_path): Check field offset. From-SVN: r182418 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a2fa74895b16..6260496830cc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2011-12-16 Jason Merrill + + PR c++/51331 + * class.c (convert_to_base_statically): Just call + build_simple_base_path. + (build_simple_base_path): Check field offset. + 2011-12-14 Jason Merrill PR c++/51248 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1c9a17b746a2..f14dd7804dc3 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -464,7 +464,14 @@ build_simple_base_path (tree expr, tree binfo) /* Is this the base field created by build_base_field? */ if (TREE_CODE (field) == FIELD_DECL && DECL_FIELD_IS_BASE (field) - && TREE_TYPE (field) == type) + && TREE_TYPE (field) == type + /* If we're looking for a field in the most-derived class, + also check the field offset; we can have two base fields + of the same type if one is an indirect virtual base and one + is a direct non-virtual base. */ + && (BINFO_INHERITANCE_CHAIN (d_binfo) + || tree_int_cst_equal (byte_position (field), + BINFO_OFFSET (binfo)))) { /* We don't use build_class_member_access_expr here, as that has unnecessary checks, and more importantly results in @@ -541,6 +548,10 @@ convert_to_base_statically (tree expr, tree base) { tree pointer_type; + /* If this is a non-empty base, use a COMPONENT_REF. */ + if (!is_empty_class (BINFO_TYPE (base))) + return build_simple_base_path (expr, base); + pointer_type = build_pointer_type (expr_type); /* We use fold_build2 and fold_convert below to simplify the trees diff --git a/gcc/cp/init.c b/gcc/cp/init.c index f85a30b01fbe..14766b648fbc 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -141,7 +141,9 @@ initialize_vtbl_ptrs (tree addr) zero-initialization does not simply mean filling the storage with zero bytes. FIELD_SIZE, if non-NULL, is the bit size of the field, subfields with bit positions at or above that bit size shouldn't - be added. */ + be added. Note that this only works when the result is assigned + to a base COMPONENT_REF; if we only have a pointer to the base subobject, + expand_assignment will end up clearing the full size of TYPE. */ static tree build_zero_init_1 (tree type, tree nelts, bool static_storage_p, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0e3d1f662fc0..3bfeedb5a73a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-12-16 Jason Merrill + + PR c++/51331 + * g++.dg/init/value10.C: New. + 2011-12-15 H.J. Lu Backport from mainline. diff --git a/gcc/testsuite/g++.dg/init/value10.C b/gcc/testsuite/g++.dg/init/value10.C new file mode 100644 index 000000000000..2066410a01d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/value10.C @@ -0,0 +1,27 @@ +// PR c++/51331 +// { dg-do run } + +struct A { + A(): x(10) {} + virtual ~A() {} + + int x; +}; + +struct B: public virtual A { +}; + +struct C: public virtual A { +}; + +struct D: public B, virtual public C { + D(): B(), C() {} // note an explicit call to C() which is auto-generated +}; + +int main() { + D* d = new D(); + + // Crashes here with the following message: + // *** glibc detected *** ./test: free(): invalid next size (fast) + delete d; +}