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: r182414
This commit is contained in:
Jason Merrill 2011-12-16 17:34:39 -05:00 committed by Jason Merrill
parent 20fb2c13c1
commit a8c1d89997
5 changed files with 54 additions and 2 deletions

View File

@ -1,3 +1,10 @@
2011-12-16 Jason Merrill <jason@redhat.com>
PR c++/51331
* class.c (convert_to_base_statically): Just call
build_simple_base_path.
(build_simple_base_path): Check field offset.
2011-12-15 Jason Merrill <jason@redhat.com> 2011-12-15 Jason Merrill <jason@redhat.com>
PR c++/51458 PR c++/51458

View File

@ -471,7 +471,14 @@ build_simple_base_path (tree expr, tree binfo)
/* Is this the base field created by build_base_field? */ /* Is this the base field created by build_base_field? */
if (TREE_CODE (field) == FIELD_DECL if (TREE_CODE (field) == FIELD_DECL
&& DECL_FIELD_IS_BASE (field) && 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 /* We don't use build_class_member_access_expr here, as that
has unnecessary checks, and more importantly results in has unnecessary checks, and more importantly results in
@ -546,6 +553,10 @@ convert_to_base_statically (tree expr, tree base)
expr_type = TREE_TYPE (expr); expr_type = TREE_TYPE (expr);
if (!SAME_BINFO_TYPE_P (BINFO_TYPE (base), expr_type)) if (!SAME_BINFO_TYPE_P (BINFO_TYPE (base), expr_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);
/* We use fold_build2 and fold_convert below to simplify the trees /* We use fold_build2 and fold_convert below to simplify the trees
provided to the optimizers. It is not safe to call these functions provided to the optimizers. It is not safe to call these functions
when processing a template because they do not handle C++-specific when processing a template because they do not handle C++-specific

View File

@ -140,7 +140,9 @@ initialize_vtbl_ptrs (tree addr)
zero-initialization does not simply mean filling the storage with zero-initialization does not simply mean filling the storage with
zero bytes. FIELD_SIZE, if non-NULL, is the bit size of the field, 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 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 static tree
build_zero_init_1 (tree type, tree nelts, bool static_storage_p, build_zero_init_1 (tree type, tree nelts, bool static_storage_p,

View File

@ -1,3 +1,8 @@
2011-12-16 Jason Merrill <jason@redhat.com>
PR c++/51331
* g++.dg/init/value10.C: New.
2011-12-16 Jakub Jelinek <jakub@redhat.com> 2011-12-16 Jakub Jelinek <jakub@redhat.com>
PR testsuite/50803 PR testsuite/50803

View File

@ -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;
}