aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c464
1 files changed, 243 insertions, 221 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 40702867405..2ac4e30f6c3 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -114,7 +114,6 @@ static int build_primary_vtable PARAMS ((tree, tree));
static int build_secondary_vtable PARAMS ((tree, tree));
static void finish_vtbls PARAMS ((tree));
static void modify_vtable_entry PARAMS ((tree, tree, tree, tree, tree *));
-static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
static void delete_duplicate_fields PARAMS ((tree));
static void finish_struct_bits PARAMS ((tree));
@@ -150,8 +149,8 @@ static void check_methods PARAMS ((tree));
static void remove_zero_width_bit_fields PARAMS ((tree));
static void check_bases PARAMS ((tree, int *, int *, int *));
static void check_bases_and_members PARAMS ((tree, int *));
-static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *));
-static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *));
+static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *));
+static void layout_class_type PARAMS ((tree, int *, int *, tree *));
static void fixup_pending_inline PARAMS ((tree));
static void fixup_inline_methods PARAMS ((tree));
static void set_primary_base PARAMS ((tree, tree, int *));
@@ -290,12 +289,9 @@ build_base_path (code, expr, binfo, nonnull)
}
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
- if (fixed_type_p < 0)
- /* Virtual base layout is not fixed, even in ctors and dtors. */
- fixed_type_p = 0;
- if (!fixed_type_p && TREE_SIDE_EFFECTS (expr))
+ if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr))
expr = save_expr (expr);
-
+
if (!want_pointer)
expr = build_unary_op (ADDR_EXPR, expr, 0);
else if (!nonnull)
@@ -303,7 +299,7 @@ build_base_path (code, expr, binfo, nonnull)
offset = BINFO_OFFSET (binfo);
- if (v_binfo && !fixed_type_p)
+ if (v_binfo && fixed_type_p <= 0)
{
/* Going via virtual base V_BINFO. We need the static offset
from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
@@ -324,7 +320,17 @@ build_base_path (code, expr, binfo, nonnull)
size_diffop (offset, BINFO_OFFSET (v_binfo)));
if (!integer_zerop (offset))
- offset = build (code, ptrdiff_type_node, v_offset, offset);
+ v_offset = build (code, ptrdiff_type_node, v_offset, offset);
+
+ if (fixed_type_p < 0)
+ /* Negative fixed_type_p means this is a constructor or destructor;
+ virtual base layout is fixed in in-charge [cd]tors, but not in
+ base [cd]tors. */
+ offset = build (COND_EXPR, ptrdiff_type_node,
+ build (EQ_EXPR, boolean_type_node,
+ current_in_charge_parm, integer_zero_node),
+ v_offset,
+ BINFO_OFFSET (binfo));
else
offset = v_offset;
}
@@ -351,7 +357,7 @@ build_base_path (code, expr, binfo, nonnull)
expr = build (COND_EXPR, target_type, null_test,
build1 (NOP_EXPR, target_type, integer_zero_node),
expr);
-
+
return expr;
}
@@ -785,61 +791,6 @@ set_vindex (decl, vfuns_p)
? TARGET_VTABLE_USES_DESCRIPTORS : 1);
DECL_VINDEX (decl) = build_shared_int_cst (vindex);
}
-
-/* Add a virtual function to all the appropriate vtables for the class
- T. DECL_VINDEX(X) should be error_mark_node, if we want to
- allocate a new slot in our table. If it is error_mark_node, we
- know that no other function from another vtable is overridden by X.
- VFUNS_P keeps track of how many virtuals there are in our
- main vtable for the type, and we build upon the NEW_VIRTUALS list
- and return it. */
-
-static void
-add_virtual_function (new_virtuals_p, overridden_virtuals_p,
- vfuns_p, fndecl, t)
- tree *new_virtuals_p;
- tree *overridden_virtuals_p;
- int *vfuns_p;
- tree fndecl;
- tree t; /* Structure type. */
-{
- tree new_virtual;
-
- /* If this function doesn't override anything from a base class, we
- can just assign it a new DECL_VINDEX now. Otherwise, if it does
- override something, we keep it around and assign its DECL_VINDEX
- later, in modify_all_vtables. */
- if (TREE_CODE (DECL_VINDEX (fndecl)) == INTEGER_CST)
- /* We've already dealt with this function. */
- return;
-
- new_virtual = make_node (TREE_LIST);
- BV_FN (new_virtual) = fndecl;
- BV_DELTA (new_virtual) = integer_zero_node;
-
- if (DECL_VINDEX (fndecl) == error_mark_node)
- {
- /* FNDECL is a new virtual function; it doesn't override any
- virtual function in a base class. */
-
- /* We remember that this was the base sub-object for rtti. */
- CLASSTYPE_RTTI (t) = t;
-
- /* Now assign virtual dispatch information. */
- set_vindex (fndecl, vfuns_p);
- DECL_VIRTUAL_CONTEXT (fndecl) = t;
-
- /* Save the state we've computed on the NEW_VIRTUALS list. */
- TREE_CHAIN (new_virtual) = *new_virtuals_p;
- *new_virtuals_p = new_virtual;
- }
- else
- {
- /* FNDECL overrides a function from a base class. */
- TREE_CHAIN (new_virtual) = *overridden_virtuals_p;
- *overridden_virtuals_p = new_virtual;
- }
-}
/* Add method METHOD to class TYPE. If ERROR_P is true, we are adding
the method after the class has already been defined because a
@@ -966,69 +917,67 @@ add_method (type, method, error_p)
fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
-
+ tree parms1;
+ tree parms2;
+ bool same = 1;
+
if (TREE_CODE (fn) != TREE_CODE (method))
continue;
- if (TREE_CODE (method) != TEMPLATE_DECL)
+ /* [over.load] Member function declarations with the
+ same name and the same parameter types cannot be
+ overloaded if any of them is a static member
+ function declaration.
+
+ [namespace.udecl] When a using-declaration brings names
+ from a base class into a derived class scope, member
+ functions in the derived class override and/or hide member
+ functions with the same name and parameter types in a base
+ class (rather than conflicting). */
+ parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
+
+ /* Compare the quals on the 'this' parm. Don't compare
+ the whole types, as used functions are treated as
+ coming from the using class in overload resolution. */
+ if (! DECL_STATIC_FUNCTION_P (fn)
+ && ! DECL_STATIC_FUNCTION_P (method)
+ && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
+ != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
+ same = 0;
+
+ /* For templates, the template parms must be identical. */
+ if (TREE_CODE (fn) == TEMPLATE_DECL
+ && !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
+ DECL_TEMPLATE_PARMS (method)))
+ same = 0;
+
+ if (! DECL_STATIC_FUNCTION_P (fn))
+ parms1 = TREE_CHAIN (parms1);
+ if (! DECL_STATIC_FUNCTION_P (method))
+ parms2 = TREE_CHAIN (parms2);
+
+ if (same && compparms (parms1, parms2)
+ && (!DECL_CONV_FN_P (fn)
+ || same_type_p (TREE_TYPE (TREE_TYPE (fn)),
+ TREE_TYPE (TREE_TYPE (method)))))
{
- /* [over.load] Member function declarations with the
- same name and the same parameter types cannot be
- overloaded if any of them is a static member
- function declaration.
-
- [namespace.udecl] When a using-declaration brings names
- from a base class into a derived class scope, member
- functions in the derived class override and/or hide member
- functions with the same name and parameter types in a base
- class (rather than conflicting). */
- if ((DECL_STATIC_FUNCTION_P (fn)
- != DECL_STATIC_FUNCTION_P (method))
- || using)
+ if (using && DECL_CONTEXT (fn) == type)
+ /* Defer to the local function. */
+ return;
+ else
{
- tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
- tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
- int same = 1;
-
- /* Compare the quals on the 'this' parm. Don't compare
- the whole types, as used functions are treated as
- coming from the using class in overload resolution. */
- if (using
- && ! DECL_STATIC_FUNCTION_P (fn)
- && ! DECL_STATIC_FUNCTION_P (method)
- && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
- != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
- same = 0;
- if (! DECL_STATIC_FUNCTION_P (fn))
- parms1 = TREE_CHAIN (parms1);
- if (! DECL_STATIC_FUNCTION_P (method))
- parms2 = TREE_CHAIN (parms2);
-
- if (same && compparms (parms1, parms2))
- {
- if (using && DECL_CONTEXT (fn) == type)
- /* Defer to the local function. */
- return;
- else
- error ("`%#D' and `%#D' cannot be overloaded",
- fn, method);
- }
+ cp_error_at ("`%#D' and `%#D' cannot be overloaded",
+ method, fn, method);
+
+ /* We don't call duplicate_decls here to merge
+ the declarations because that will confuse
+ things if the methods have inline
+ definitions. In particular, we will crash
+ while processing the definitions. */
+ return;
}
}
-
- if (!decls_match (fn, method))
- continue;
-
- /* There has already been a declaration of this method
- or member template. */
- cp_error_at ("`%D' has already been declared in `%T'",
- method, type);
-
- /* We don't call duplicate_decls here to merge the
- declarations because that will confuse things if the
- methods have inline definitions. In particular, we
- will crash while processing the definitions. */
- return;
}
}
@@ -1208,9 +1157,12 @@ handle_using_decl (using_decl, t)
tree flist = NULL_TREE;
tree old_value;
- binfo = binfo_or_else (ctype, t);
+ binfo = lookup_base (t, ctype, ba_any, NULL);
if (! binfo)
- return;
+ {
+ error_not_base_type (t, ctype);
+ return;
+ }
if (name == constructor_name (ctype)
|| name == constructor_name_full (ctype))
@@ -1396,6 +1348,8 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
+ |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
}
}
@@ -1843,17 +1797,11 @@ finish_struct_bits (t)
}
}
- /* If this type has a copy constructor, force its mode to be BLKmode, and
- force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to
- be passed by invisible reference and prevent it from being returned in
- a register.
-
- Also do this if the class has BLKmode but can still be returned in
- registers, since function_cannot_inline_p won't let us inline
- functions returning such a type. This affects the HP-PA. */
- if (! TYPE_HAS_TRIVIAL_INIT_REF (t)
- || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)
- && CLASSTYPE_NON_AGGREGATE (t)))
+ /* If this type has a copy constructor or a destructor, force its mode to
+ be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero. This
+ will cause it to be passed by invisible reference and prevent it from
+ being returned in a register. */
+ if (! TYPE_HAS_TRIVIAL_INIT_REF (t) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
{
tree variants;
DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
@@ -2518,6 +2466,10 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
if (overrider == error_mark_node)
return;
+ /* Check for unsupported covariant returns again now that we've
+ calculated the base offsets. */
+ check_final_overrider (TREE_PURPOSE (overrider), fn);
+
/* Assume that we will produce a thunk that convert all the way to
the final overrider, and not to an intermediate virtual base. */
virtual_base = NULL_TREE;
@@ -2640,18 +2592,18 @@ dfs_modify_vtables (binfo, data)
/* Update all of the primary and secondary vtables for T. Create new
vtables as required, and initialize their RTTI information. Each
- of the functions in OVERRIDDEN_VIRTUALS overrides a virtual
- function from a base class; find and modify the appropriate entries
- to point to the overriding functions. Returns a list, in
- declaration order, of the functions that are overridden in this
- class, but do not appear in the primary base class vtable, and
- which should therefore be appended to the end of the vtable for T. */
+ of the functions in VIRTUALS is declared in T and may override a
+ virtual function from a base class; find and modify the appropriate
+ entries to point to the overriding functions. Returns a list, in
+ declaration order, of the virtual functions that are declared in T,
+ but do not appear in the primary base class vtable, and which
+ should therefore be appended to the end of the vtable for T. */
static tree
-modify_all_vtables (t, vfuns_p, overridden_virtuals)
+modify_all_vtables (t, vfuns_p, virtuals)
tree t;
int *vfuns_p;
- tree overridden_virtuals;
+ tree virtuals;
{
tree binfo = TYPE_BINFO (t);
tree *fnsp;
@@ -2663,14 +2615,16 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
t);
dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
- /* Include overriding functions for secondary vtables in our primary
- vtable. */
- for (fnsp = &overridden_virtuals; *fnsp; )
+ /* Add virtual functions not already in our primary vtable. These
+ will be both those introduced by this class, and those overridden
+ from secondary bases. It does not include virtuals merely
+ inherited from secondary bases. */
+ for (fnsp = &virtuals; *fnsp; )
{
tree fn = TREE_VALUE (*fnsp);
- if (!BINFO_VIRTUALS (binfo)
- || !value_member (fn, BINFO_VIRTUALS (binfo)))
+ if (!value_member (fn, BINFO_VIRTUALS (binfo))
+ || DECL_VINDEX (fn) == error_mark_node)
{
/* Set the vtable index. */
set_vindex (fn, vfuns_p);
@@ -2683,8 +2637,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
BV_DELTA (*fnsp) = integer_zero_node;
BV_VCALL_INDEX (*fnsp) = NULL_TREE;
- /* This is an overridden function not already in our
- vtable. Keep it. */
+ /* This is a function not already in our vtable. Keep it. */
fnsp = &TREE_CHAIN (*fnsp);
}
else
@@ -2692,7 +2645,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
*fnsp = TREE_CHAIN (*fnsp);
}
- return overridden_virtuals;
+ return virtuals;
}
/* Here, we already know that they match in every respect.
@@ -2762,16 +2715,14 @@ check_for_override (decl, ctype)
|| IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)))
&& look_for_overrides (ctype, decl)
&& !DECL_STATIC_FUNCTION_P (decl))
- {
- /* Set DECL_VINDEX to a value that is neither an
- INTEGER_CST nor the error_mark_node so that
- add_virtual_function will realize this is an
- overriding function. */
- DECL_VINDEX (decl) = decl;
- }
+ /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
+ the error_mark_node so that we know it is an overriding
+ function. */
+ DECL_VINDEX (decl) = decl;
+
if (DECL_VIRTUAL_P (decl))
{
- if (DECL_VINDEX (decl) == NULL_TREE)
+ if (!DECL_VINDEX (decl))
DECL_VINDEX (decl) = error_mark_node;
IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
}
@@ -3298,10 +3249,18 @@ check_field_decls (t, access_decls, empty_p,
;
else
{
+ tree element_type;
+
/* The class is non-empty. */
*empty_p = 0;
/* The class is not even nearly empty. */
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ /* If one of the data members contains an empty class,
+ so does T. */
+ element_type = strip_array_types (type);
+ if (CLASS_TYPE_P (element_type)
+ && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
}
}
@@ -3383,7 +3342,7 @@ check_field_decls (t, access_decls, empty_p,
{
CLASSTYPE_NON_POD_P (t) = 1;
if (DECL_INITIAL (x) == NULL_TREE)
- CLASSTYPE_REF_FIELDS_NEED_INIT (t) = 1;
+ SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
/* ARM $12.6.2: [A member initializer list] (or, for an
aggregate, initialization by a brace-enclosed list) is the
@@ -3409,12 +3368,15 @@ check_field_decls (t, access_decls, empty_p,
to be allowed in POD structs. */
CLASSTYPE_NON_POD_P (t) = 1;
+ if (! zero_init_p (type))
+ CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
+
/* If any field is const, the structure type is pseudo-const. */
if (CP_TYPE_CONST_P (type))
{
C_TYPE_FIELDS_READONLY (t) = 1;
if (DECL_INITIAL (x) == NULL_TREE)
- CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = 1;
+ SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
/* ARM $12.6.2: [A member initializer list] (or, for an
aggregate, initialization by a brace-enclosed list) is the
@@ -3430,8 +3392,9 @@ check_field_decls (t, access_decls, empty_p,
else if (IS_AGGR_TYPE (type))
{
C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type);
- CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
- |= CLASSTYPE_READONLY_FIELDS_NEED_INIT (type);
+ SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t,
+ CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
+ | CLASSTYPE_READONLY_FIELDS_NEED_INIT (type));
}
/* Core issue 80: A nonstatic data member is required to have a
@@ -3565,6 +3528,10 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
tree field;
int i;
+ /* Avoid recursing into objects that are not interesting. */
+ if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+ return 0;
+
/* Record the location of TYPE. */
r = (*f) (type, offset, offsets);
if (r)
@@ -3610,9 +3577,15 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
}
else if (TREE_CODE (type) == ARRAY_TYPE)
{
+ tree element_type = strip_array_types (type);
tree domain = TYPE_DOMAIN (type);
tree index;
+ /* Avoid recursing into objects that are not interesting. */
+ if (!CLASS_TYPE_P (element_type)
+ || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
+ return 0;
+
/* Step through each of the elements in the array. */
for (index = size_zero_node;
INT_CST_LT (index, TYPE_MAX_VALUE (domain));
@@ -3835,6 +3808,8 @@ build_base_field (rli, binfo, empty_p, offsets, t)
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
+ /* Tell the backend not to round up to TYPE_ALIGN. */
+ DECL_PACKED (decl) = 1;
if (!integer_zerop (DECL_SIZE (decl)))
{
@@ -4323,6 +4298,7 @@ check_bases_and_members (t, empty_p)
/* Assume that the class is nearly empty; we'll clear this flag if
it turns out not to be nearly empty. */
CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
/* Check all the base-classes. */
check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor,
@@ -4388,31 +4364,37 @@ check_bases_and_members (t, empty_p)
accordingly. If a new vfield was created (because T doesn't have a
primary base class), then the newly created field is returned. It
is not added to the TYPE_FIELDS list; it is the caller's
- responsibility to do that. */
+ responsibility to do that. Accumulate declared virtual functions
+ on VIRTUALS_P. */
static tree
-create_vtable_ptr (t, empty_p, vfuns_p,
- new_virtuals_p, overridden_virtuals_p)
+create_vtable_ptr (t, empty_p, vfuns_p, virtuals_p)
tree t;
int *empty_p;
int *vfuns_p;
- tree *new_virtuals_p;
- tree *overridden_virtuals_p;
+ tree *virtuals_p;
{
tree fn;
- /* Loop over the virtual functions, adding them to our various
- vtables. */
+ /* Collect the virtual functions declared in T. */
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
- if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
- add_virtual_function (new_virtuals_p, overridden_virtuals_p,
- vfuns_p, fn, t);
+ if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
+ && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
+ {
+ tree new_virtual = make_node (TREE_LIST);
+
+ BV_FN (new_virtual) = fn;
+ BV_DELTA (new_virtual) = integer_zero_node;
+ TREE_CHAIN (new_virtual) = *virtuals_p;
+ *virtuals_p = new_virtual;
+ }
+
/* If we couldn't find an appropriate base class, create a new field
here. Even if there weren't any new virtual functions, we might need a
new virtual function table if we're supposed to include vptrs in
all classes that need them. */
- if (!TYPE_VFIELD (t) && (*vfuns_p || TYPE_CONTAINS_VPTR_P (t)))
+ if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))
{
/* We build this decl with vtbl_ptr_type_node, which is a
`vtable_entry_type*'. It might seem more precise to use
@@ -4605,9 +4587,9 @@ layout_virtual_bases (t, offsets)
tree t;
splay_tree offsets;
{
- tree vbases;
- unsigned HOST_WIDE_INT dsize;
+ tree vbases, dsize;
unsigned HOST_WIDE_INT eoc;
+ bool first_vbase = true;
if (CLASSTYPE_N_BASECLASSES (t) == 0)
return;
@@ -4619,7 +4601,7 @@ layout_virtual_bases (t, offsets)
#endif
/* DSIZE is the size of the class without the virtual bases. */
- dsize = tree_low_cst (TYPE_SIZE (t), 1);
+ dsize = TYPE_SIZE (t);
/* Make every class have alignment of at least one. */
TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT);
@@ -4635,13 +4617,14 @@ layout_virtual_bases (t, offsets)
if (!TREE_VIA_VIRTUAL (vbases))
continue;
+
vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
if (!BINFO_PRIMARY_P (vbase))
{
/* This virtual base is not a primary base of any class in the
hierarchy, so we have to add space for it. */
- tree basetype;
+ tree basetype, usize;
unsigned int desired_align;
basetype = BINFO_TYPE (vbase);
@@ -4651,19 +4634,20 @@ layout_virtual_bases (t, offsets)
/* Add padding so that we can put the virtual base class at an
appropriately aligned offset. */
- dsize = CEIL (dsize, desired_align) * desired_align;
+ dsize = round_up (dsize, desired_align);
+ usize = size_binop (CEIL_DIV_EXPR, dsize, bitsize_unit_node);
/* We try to squish empty virtual bases in just like
ordinary empty bases. */
if (is_empty_class (basetype))
layout_empty_base (vbase,
- size_int (CEIL (dsize, BITS_PER_UNIT)),
+ convert (sizetype, usize),
offsets, t);
else
{
tree offset;
- offset = ssize_int (CEIL (dsize, BITS_PER_UNIT));
+ offset = convert (ssizetype, usize);
offset = size_diffop (offset,
convert (ssizetype,
BINFO_OFFSET (vbase)));
@@ -4673,15 +4657,35 @@ layout_virtual_bases (t, offsets)
/* Every virtual baseclass takes a least a UNIT, so that
we can take it's address and get something different
for each base. */
- dsize += MAX (BITS_PER_UNIT,
- tree_low_cst (CLASSTYPE_SIZE (basetype), 0));
+ dsize = size_binop (PLUS_EXPR, dsize,
+ size_binop (MAX_EXPR, bitsize_unit_node,
+ CLASSTYPE_SIZE (basetype)));
}
+ /* If the first virtual base might have been placed at a
+ lower address, had we started from CLASSTYPE_SIZE, rather
+ than TYPE_SIZE, issue a warning. There can be both false
+ positives and false negatives from this warning in rare
+ cases; to deal with all the possibilities would probably
+ require performing both layout algorithms and comparing
+ the results which is not particularly tractable. */
+ if (warn_abi
+ && first_vbase
+ && tree_int_cst_lt (size_binop (CEIL_DIV_EXPR,
+ round_up (CLASSTYPE_SIZE (t),
+ desired_align),
+ bitsize_unit_node),
+ BINFO_OFFSET (vbase)))
+ warning ("offset of virtual base `%T' is not ABI-compliant and may change in a future version of GCC",
+ basetype);
+
/* Keep track of the offsets assigned to this virtual base. */
record_subobject_offsets (BINFO_TYPE (vbase),
BINFO_OFFSET (vbase),
offsets,
/*vbases_p=*/0);
+
+ first_vbase = false;
}
}
@@ -4696,13 +4700,12 @@ layout_virtual_bases (t, offsets)
class, we didn't update DSIZE above; we were hoping to overlay
multiple such bases at the same location. */
eoc = end_of_class (t, /*include_virtuals_p=*/1);
- if (eoc * BITS_PER_UNIT > dsize)
- dsize = eoc * BITS_PER_UNIT;
+ dsize = size_binop (MAX_EXPR, dsize, bitsize_int (eoc * BITS_PER_UNIT));
/* Now, make sure that the total size of the type is a multiple of
its alignment. */
- dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t);
- TYPE_SIZE (t) = bitsize_int (dsize);
+ dsize = round_up (dsize, TYPE_ALIGN (t));
+ TYPE_SIZE (t) = dsize;
TYPE_SIZE_UNIT (t) = convert (sizetype,
size_binop (CEIL_DIV_EXPR, TYPE_SIZE (t),
bitsize_unit_node));
@@ -4803,16 +4806,14 @@ splay_tree_compare_integer_csts (k1, k2)
/* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate
BINFO_OFFSETs for all of the base-classes. Position the vtable
- pointer. */
+ pointer. Accumulate declared virtual functions on VIRTUALS_P. */
static void
-layout_class_type (t, empty_p, vfuns_p,
- new_virtuals_p, overridden_virtuals_p)
+layout_class_type (t, empty_p, vfuns_p, virtuals_p)
tree t;
int *empty_p;
int *vfuns_p;
- tree *new_virtuals_p;
- tree *overridden_virtuals_p;
+ tree *virtuals_p;
{
tree non_static_data_members;
tree field;
@@ -4822,6 +4823,8 @@ layout_class_type (t, empty_p, vfuns_p,
/* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of
types that appear at that offset. */
splay_tree empty_base_offsets;
+ /* True if the last field layed out was a bit-field. */
+ bool last_field_was_bitfield = false;
/* Keep track of the first non-static data member. */
non_static_data_members = TYPE_FIELDS (t);
@@ -4834,8 +4837,7 @@ layout_class_type (t, empty_p, vfuns_p,
determine_primary_base (t, vfuns_p);
/* Create a pointer to our virtual function table. */
- vptr = create_vtable_ptr (t, empty_p, vfuns_p,
- new_virtuals_p, overridden_virtuals_p);
+ vptr = create_vtable_ptr (t, empty_p, vfuns_p, virtuals_p);
/* The vptr is always the first thing in the class. */
if (vptr)
@@ -4861,6 +4863,18 @@ layout_class_type (t, empty_p, vfuns_p,
if (TREE_CODE (field) != FIELD_DECL)
{
place_field (rli, field);
+ /* If the static data member has incomplete type, keep track
+ of it so that it can be completed later. (The handling
+ of pending statics in finish_record_layout is
+ insufficient; consider:
+
+ struct S1;
+ struct S2 { static S1 s1; };
+
+ At this point, finish_record_layout will be called, but
+ S1 is still incomplete.) */
+ if (TREE_CODE (field) == VAR_DECL)
+ maybe_register_incomplete_var (field);
continue;
}
@@ -4900,6 +4914,18 @@ layout_class_type (t, empty_p, vfuns_p,
layout_nonempty_base_or_field (rli, field, NULL_TREE,
empty_base_offsets, t);
+ /* If a bit-field does not immediately follow another bit-field,
+ and yet it starts in the middle of a byte, we have failed to
+ comply with the ABI. */
+ if (warn_abi
+ && DECL_C_BIT_FIELD (field)
+ && !last_field_was_bitfield
+ && !integer_zerop (size_binop (TRUNC_MOD_EXPR,
+ DECL_FIELD_BIT_OFFSET (field),
+ bitsize_unit_node)))
+ cp_warning_at ("offset of `%D' is not ABI-compliant and may change in a future version of GCC",
+ field);
+
/* If we needed additional padding after this field, add it
now. */
if (padding)
@@ -4917,6 +4943,8 @@ layout_class_type (t, empty_p, vfuns_p,
NULL_TREE,
empty_base_offsets, t);
}
+
+ last_field_was_bitfield = DECL_C_BIT_FIELD (field);
}
/* It might be the case that we grew the class to allocate a
@@ -4963,6 +4991,12 @@ layout_class_type (t, empty_p, vfuns_p,
CLASSTYPE_SIZE (t) = bitsize_zero_node;
CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
}
+ /* If this is a POD, we can't reuse its tail padding. */
+ else if (!CLASSTYPE_NON_POD_P (t))
+ {
+ CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
+ CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t);
+ }
else
{
CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
@@ -4972,6 +5006,10 @@ layout_class_type (t, empty_p, vfuns_p,
CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t);
+ /* Every empty class contains an empty class. */
+ if (*empty_p)
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+
/* Set the TYPE_DECL for this type to contain the right
value for DECL_OFFSET, so that we can use it as part
of a COMPONENT_REF for multiple inheritance. */
@@ -5024,15 +5062,8 @@ finish_struct_1 (t)
{
tree x;
int vfuns;
- /* The NEW_VIRTUALS is a TREE_LIST. The TREE_VALUE of each node is
- a FUNCTION_DECL. Each of these functions is a virtual function
- declared in T that does not override any virtual function from a
- base class. */
- tree new_virtuals = NULL_TREE;
- /* The OVERRIDDEN_VIRTUALS list is like the NEW_VIRTUALS list,
- except that each declaration here overrides the declaration from
- a base class. */
- tree overridden_virtuals = NULL_TREE;
+ /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
+ tree virtuals = NULL_TREE;
int n_fields = 0;
tree vfield;
int empty = 1;
@@ -5062,8 +5093,7 @@ finish_struct_1 (t)
check_bases_and_members (t, &empty);
/* Layout the class itself. */
- layout_class_type (t, &empty, &vfuns,
- &new_virtuals, &overridden_virtuals);
+ layout_class_type (t, &empty, &vfuns, &virtuals);
/* Make sure that we get our own copy of the vfield FIELD_DECL. */
vfield = TYPE_VFIELD (t);
@@ -5087,8 +5117,7 @@ finish_struct_1 (t)
else
my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726);
- overridden_virtuals
- = modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals));
+ virtuals = modify_all_vtables (t, &vfuns, nreverse (virtuals));
/* If we created a new vtbl pointer for this class, add it to the
list. */
@@ -5097,9 +5126,8 @@ finish_struct_1 (t)
= chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
/* If necessary, create the primary vtable for this class. */
- if (new_virtuals || overridden_virtuals || TYPE_CONTAINS_VPTR_P (t))
+ if (virtuals || TYPE_CONTAINS_VPTR_P (t))
{
- new_virtuals = nreverse (new_virtuals);
/* We must enter these virtuals into the table. */
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
build_primary_vtable (NULL_TREE, t);
@@ -5112,7 +5140,6 @@ finish_struct_1 (t)
constructors might clobber the virtual function table. But
they don't if the derived class shares the exact vtable of the base
class. */
-
CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
}
/* If we didn't need a new vtable, see if we should copy one from
@@ -5138,14 +5165,8 @@ finish_struct_1 (t)
20000116);
CLASSTYPE_VSIZE (t) = vfuns;
- /* Entries for virtual functions defined in the primary base are
- followed by entries for new functions unique to this class. */
- TYPE_BINFO_VIRTUALS (t)
- = chainon (TYPE_BINFO_VIRTUALS (t), new_virtuals);
- /* Finally, add entries for functions that override virtuals
- from non-primary bases. */
- TYPE_BINFO_VIRTUALS (t)
- = chainon (TYPE_BINFO_VIRTUALS (t), overridden_virtuals);
+ /* Add entries for virtual functions introduced by this class. */
+ TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), virtuals);
}
finish_struct_bits (t);
@@ -5154,7 +5175,7 @@ finish_struct_1 (t)
working on. */
for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x))
if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x)
- && TREE_TYPE (x) == t)
+ && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
DECL_MODE (x) = TYPE_MODE (t);
/* Done with FIELDS...now decide whether to sort these for
@@ -5203,7 +5224,7 @@ finish_struct_1 (t)
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1)) == NULL_TREE)
warning ("`%#T' has virtual functions but non-virtual destructor", t);
- hack_incomplete_structures (t);
+ complete_vars (t);
if (warn_overloaded_virtual)
warn_hidden (t);
@@ -6295,7 +6316,8 @@ get_vfield_name (type)
type = BINFO_TYPE (binfo);
buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
+ TYPE_NAME_LENGTH (type) + 2);
- sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type));
+ sprintf (buf, VFIELD_NAME_FORMAT,
+ IDENTIFIER_POINTER (constructor_name (type)));
return get_identifier (buf);
}