Commit e33eba75 by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/48035 (Mismatch on size of class when initializing hierarchy involving…

re PR c++/48035 (Mismatch on size of class when initializing hierarchy involving virtual inheritance and empty base classes)

	PR c++/48035
	* init.c (build_zero_init_1): Extracted from build_zero_init.
	Add FIELD_SIZE argument, if non-NULL and field bit_position
	as not smaller than that, don't add that field's initializer.
	Pass DECL_SIZE as last argument to build_zero_init_1
	for DECL_FIELD_IS_BASE fields.
	(build_zero_init): Use build_zero_init_1.

	* g++.dg/inherit/virtual8.C: New test.

From-SVN: r170874
parent 4074f163
2011-03-11 Jakub Jelinek <jakub@redhat.com>
PR c++/48035
* init.c (build_zero_init_1): Extracted from build_zero_init.
Add FIELD_SIZE argument, if non-NULL and field bit_position
as not smaller than that, don't add that field's initializer.
Pass DECL_SIZE as last argument to build_zero_init_1
for DECL_FIELD_IS_BASE fields.
(build_zero_init): Use build_zero_init_1.
2011-03-10 Jason Merrill <jason@redhat.com>
PR c++/48029
......
/* Handle initialization things in C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
......@@ -140,10 +140,13 @@ initialize_vtbl_ptrs (tree addr)
is the number of elements in the array. If STATIC_STORAGE_P is
TRUE, initializers are only generated for entities for which
zero-initialization does not simply mean filling the storage with
zero bytes. */
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. */
tree
build_zero_init (tree type, tree nelts, bool static_storage_p)
static tree
build_zero_init_1 (tree type, tree nelts, bool static_storage_p,
tree field_size)
{
tree init = NULL_TREE;
......@@ -188,15 +191,32 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
if (TREE_CODE (field) != FIELD_DECL)
continue;
/* Don't add virtual bases for base classes if they are beyond
the size of the current field, that means it is present
somewhere else in the object. */
if (field_size)
{
tree bitpos = bit_position (field);
if (TREE_CODE (bitpos) == INTEGER_CST
&& !tree_int_cst_lt (bitpos, field_size))
continue;
}
/* Note that for class types there will be FIELD_DECLs
corresponding to base classes as well. Thus, iterating
over TYPE_FIELDs will result in correct initialization of
all of the subobjects. */
if (!static_storage_p || !zero_init_p (TREE_TYPE (field)))
{
tree value = build_zero_init (TREE_TYPE (field),
/*nelts=*/NULL_TREE,
static_storage_p);
tree new_field_size
= (DECL_FIELD_IS_BASE (field)
&& DECL_SIZE (field)
&& TREE_CODE (DECL_SIZE (field)) == INTEGER_CST)
? DECL_SIZE (field) : NULL_TREE;
tree value = build_zero_init_1 (TREE_TYPE (field),
/*nelts=*/NULL_TREE,
static_storage_p,
new_field_size);
if (value)
CONSTRUCTOR_APPEND_ELT(v, field, value);
}
......@@ -244,9 +264,9 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node,
max_index);
ce->value = build_zero_init (TREE_TYPE (type),
/*nelts=*/NULL_TREE,
static_storage_p);
ce->value = build_zero_init_1 (TREE_TYPE (type),
/*nelts=*/NULL_TREE,
static_storage_p, NULL_TREE);
}
/* Build a constructor to contain the initializations. */
......@@ -264,6 +284,24 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
return init;
}
/* Return an expression for the zero-initialization of an object with
type T. This expression will either be a constant (in the case
that T is a scalar), or a CONSTRUCTOR (in the case that T is an
aggregate), or NULL (in the case that T does not require
initialization). In either case, the value can be used as
DECL_INITIAL for a decl of the indicated TYPE; it is a valid static
initializer. If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS
is the number of elements in the array. If STATIC_STORAGE_P is
TRUE, initializers are only generated for entities for which
zero-initialization does not simply mean filling the storage with
zero bytes. */
tree
build_zero_init (tree type, tree nelts, bool static_storage_p)
{
return build_zero_init_1 (type, nelts, static_storage_p, NULL_TREE);
}
/* Return a suitable initializer for value-initializing an object of type
TYPE, as described in [dcl.init]. */
......
2011-03-11 Jakub Jelinek <jakub@redhat.com>
PR c++/48035
* g++.dg/inherit/virtual8.C: New test.
PR middle-end/48044
* gcc.dg/torture/pr48044.c: New test.
......
// PR c++/48035
// { dg-do run }
#include <new>
#include <cstring>
#include <cstdlib>
struct A
{
virtual void foo (void) {}
virtual ~A () {}
};
struct B : public A
{
virtual ~B () {}
};
struct C
{
virtual ~C () {}
int c;
};
struct D : public virtual B, public C
{
virtual ~D () {}
};
struct E : public virtual D
{
virtual ~E () {}
};
int
main ()
{
char *v = new char[sizeof (E) + 16];
memset (v, 0x55, sizeof (E) + 16);
E *e = new (v) E ();
e->~E ();
for (unsigned i = sizeof (E); i < sizeof (E) + 16; ++i)
if (v[i] != 0x55)
abort ();
delete[] v;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment