aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-03-11 16:43:37 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-03-11 16:43:37 +0100
commite33eba75933fdd7bd895a3b35ef1b1b710ddbb13 (patch)
tree646fcf3880fcf55f5b06c27e45a7d9a15287445c /gcc/cp/init.c
parent4074f163fc39eedabb09f1ddcbd4c78bf55cb19b (diff)
downloadgcc-e33eba75933fdd7bd895a3b35ef1b1b710ddbb13.zip
gcc-e33eba75933fdd7bd895a3b35ef1b1b710ddbb13.tar.gz
gcc-e33eba75933fdd7bd895a3b35ef1b1b710ddbb13.tar.bz2
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
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r--gcc/cp/init.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 56f66fa..e1961c8 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1,7 +1,7 @@
/* 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]. */