mirror of git://gcc.gnu.org/git/gcc.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: r182414
This commit is contained in:
parent
20fb2c13c1
commit
a8c1d89997
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue