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.c998
1 files changed, 547 insertions, 451 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index db8cfa75920..7afe27317c6 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -115,7 +115,6 @@ static void delete_duplicate_fields PARAMS ((tree));
static void finish_struct_bits PARAMS ((tree));
static int alter_access PARAMS ((tree, tree, tree));
static void handle_using_decl PARAMS ((tree, tree));
-static int strictly_overrides PARAMS ((tree, tree));
static void check_for_override PARAMS ((tree, tree));
static tree dfs_modify_vtables PARAMS ((tree, void *));
static tree modify_all_vtables PARAMS ((tree, int *, tree));
@@ -134,24 +133,22 @@ static tree build_vtbl_initializer PARAMS ((tree, tree, tree, tree, int *));
static int count_fields PARAMS ((tree));
static int add_fields_to_vec PARAMS ((tree, tree, int));
static void check_bitfield_decl PARAMS ((tree));
-static void check_field_decl PARAMS ((tree, tree, int *, int *, int *, int *));
-static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *,
- int *));
-static bool build_base_field PARAMS ((record_layout_info, tree, int *,
- splay_tree, tree));
-static bool build_base_fields PARAMS ((record_layout_info, int *,
- splay_tree, tree));
+static void check_field_decl (tree, tree, int *, int *, int *, int *);
+static void check_field_decls (tree, tree *, int *, int *, int *);
+static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
+static void build_base_fields (record_layout_info, splay_tree, tree *);
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 *, tree *));
-static void layout_class_type PARAMS ((tree, int *, int *, tree *));
+static void check_bases_and_members (tree);
+static tree create_vtable_ptr (tree, tree *);
+static void include_empty_classes (record_layout_info);
+static void layout_class_type (tree, 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 *));
static void propagate_binfo_offsets PARAMS ((tree, tree, tree));
-static void layout_virtual_bases PARAMS ((tree, splay_tree));
+static void layout_virtual_bases (record_layout_info, splay_tree);
static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
static void build_vbase_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *));
static void add_vcall_offset_vtbl_entries_r PARAMS ((tree, vtbl_init_data *));
@@ -171,9 +168,8 @@ static tree build_vtable PARAMS ((tree, tree, tree));
static void initialize_vtable PARAMS ((tree, tree));
static void initialize_array PARAMS ((tree, tree));
static void layout_nonempty_base_or_field PARAMS ((record_layout_info,
- tree, tree,
- splay_tree, tree));
-static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
+ tree, tree, splay_tree));
+static tree end_of_class PARAMS ((tree, int));
static bool layout_empty_base PARAMS ((tree, tree, splay_tree, tree));
static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree));
static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree,
@@ -208,8 +204,11 @@ static void record_subobject_offsets PARAMS ((tree, tree, splay_tree, int));
static int layout_conflict_p PARAMS ((tree, tree, splay_tree, int));
static int splay_tree_compare_integer_csts PARAMS ((splay_tree_key k1,
splay_tree_key k2));
-static void warn_about_ambiguous_direct_bases PARAMS ((tree));
+static void warn_about_ambiguous_bases PARAMS ((tree));
static bool type_requires_array_cookie PARAMS ((tree));
+static bool contains_empty_class_p (tree);
+static tree dfs_base_derived_from (tree, void *);
+static bool base_derived_from (tree, tree);
/* Macros for dfs walking during vtt construction. See
dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits
@@ -532,7 +531,7 @@ build_vtable (class_type, name, vtable_type)
/* Get the VAR_DECL of the vtable for TYPE. TYPE need not be polymorphic,
or even complete. If this does not exist, create it. If COMPLETE is
- non-zero, then complete the definition of it -- that will render it
+ nonzero, then complete the definition of it -- that will render it
impossible to actually build the vtable, but is useful to get at those
which are known to exist in the runtime. */
@@ -593,7 +592,7 @@ copy_virtuals (binfo)
/* Build the primary virtual function table for TYPE. If BINFO is
non-NULL, build the vtable starting with the initial approximation
that it is the same as the one which is the head of the association
- list. Returns a non-zero value if a new vtable is actually
+ list. Returns a nonzero value if a new vtable is actually
created. */
static int
@@ -645,7 +644,7 @@ build_primary_vtable (binfo, type)
FOR_TYPE is the most derived type which caused this table to
be needed.
- Returns non-zero if we haven't met BINFO before.
+ Returns nonzero if we haven't met BINFO before.
The order in which vtables are built (by calling this function) for
an object must remain the same, otherwise a binary incompatibility
@@ -676,7 +675,7 @@ build_secondary_vtable (binfo, for_type)
}
/* Create a new vtable for BINFO which is the hierarchy dominated by
- T. Return non-zero if we actually created a new vtable. */
+ T. Return nonzero if we actually created a new vtable. */
static int
make_new_vtable (t, binfo)
@@ -828,7 +827,7 @@ add_method (type, method, error_p)
&& DECL_TEMPLATE_CONV_FN_P (m));
/* If we need to move things up, see if there's
- space. */
+ space. */
if (!have_template_convs_p)
{
slot = len - 1;
@@ -952,6 +951,13 @@ add_method (type, method, error_p)
&& (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))
@@ -1157,9 +1163,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 (constructor_name_p (name, ctype))
{
@@ -1181,7 +1190,7 @@ handle_using_decl (using_decl, t)
}
if (BASELINK_P (fdecl))
- /* Ignore base type this came from. */
+ /* Ignore base type this came from. */
fdecl = BASELINK_FUNCTIONS (fdecl);
old_value = IDENTIFIER_CLASS_VALUE (name);
@@ -1314,7 +1323,7 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
}
if (TREE_VIA_VIRTUAL (base_binfo))
- /* A virtual base does not effect nearly emptiness. */
+ /* A virtual base does not effect nearly emptiness. */
;
else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
{
@@ -1323,7 +1332,7 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
derived class is not nearly empty either. */
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
else
- /* Remember we've seen one. */
+ /* Remember we've seen one. */
seen_non_virtual_nearly_empty_base_p = 1;
}
else if (!is_empty_class (basetype))
@@ -1470,7 +1479,7 @@ mark_primary_virtual_base (base_binfo, type)
/* If BINFO is an unmarked virtual binfo for a class with a primary virtual
base, then BINFO has no primary base in this graph. Called from
- mark_primary_bases. DATA is the most derived type. */
+ mark_primary_bases. DATA is the most derived type. */
static tree dfs_unshared_virtual_bases (binfo, data)
tree binfo;
@@ -1503,11 +1512,11 @@ static tree dfs_unshared_virtual_bases (binfo, data)
if (binfo != TYPE_BINFO (t))
/* The vtable fields will have been copied when duplicating the
base binfos. That information is bogus, make sure we don't try
- and use it. */
+ and use it. */
BINFO_VTABLE (binfo) = NULL_TREE;
/* If this is a virtual primary base, make sure its offset matches
- that which it is primary for. */
+ that which it is primary for. */
if (BINFO_PRIMARY_P (binfo) && TREE_VIA_VIRTUAL (binfo) &&
binfo_for_vbase (BINFO_TYPE (binfo), t) == binfo)
{
@@ -1536,7 +1545,7 @@ mark_primary_bases (type)
tree base_binfo;
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
- /* Not a dynamic base. */
+ /* Not a dynamic base. */
continue;
base_binfo = get_primary_binfo (binfo);
@@ -2158,7 +2167,7 @@ layout_vtable_decl (binfo, n)
layout_decl (vtable, 0);
/* At one time the vtable info was grabbed 2 words at a time. This
- fails on Sparc unless you have 8-byte alignment. */
+ fails on SPARC unless you have 8-byte alignment. */
DECL_ALIGN (vtable) = MAX (TYPE_ALIGN (double_type_node),
DECL_ALIGN (vtable));
}
@@ -2196,6 +2205,29 @@ same_signature_p (fndecl, base_fndecl)
return 0;
}
+/* Called from base_derived_from via dfs_walk. */
+
+static tree
+dfs_base_derived_from (tree binfo, void *data)
+{
+ tree base = (tree) data;
+
+ if (same_type_p (TREE_TYPE (base), TREE_TYPE (binfo))
+ && tree_int_cst_equal (BINFO_OFFSET (base), BINFO_OFFSET (binfo)))
+ return error_mark_node;
+
+ return NULL_TREE;
+}
+
+/* Returns TRUE if DERIVED is a binfo containing the binfo BASE as a
+ subobject. */
+
+static bool
+base_derived_from (tree derived, tree base)
+{
+ return dfs_walk (derived, dfs_base_derived_from, NULL, base) != NULL_TREE;
+}
+
typedef struct find_final_overrider_data_s {
/* The function for which we are trying to find a final overrider. */
tree fn;
@@ -2203,14 +2235,8 @@ typedef struct find_final_overrider_data_s {
tree declaring_base;
/* The most derived class in the hierarchy. */
tree most_derived_type;
- /* The final overriding function. */
- tree overriding_fn;
- /* The functions that we thought might be final overriders, but
- aren't. */
+ /* The candidate overriders. */
tree candidates;
- /* The BINFO for the class in which the final overriding function
- appears. */
- tree overriding_base;
} find_final_overrider_data;
/* Called from find_final_overrider via dfs_walk. */
@@ -2235,118 +2261,41 @@ dfs_find_final_overrider (binfo, data)
/* We've found a path to the declaring base. Walk down the path
looking for an overrider for FN. */
for (path = reverse_path (binfo);
- path;
+ path;
path = TREE_CHAIN (path))
{
method = look_for_overrides_here (BINFO_TYPE (TREE_VALUE (path)),
ffod->fn);
if (method)
- break;
+ {
+ path = TREE_VALUE (path);
+ break;
+ }
}
/* If we found an overrider, record the overriding function, and
the base from which it came. */
if (path)
{
- tree base;
-
- /* Assume the path is non-virtual. See if there are any
- virtual bases from (but not including) the overrider up
- to and including the base where the function is
- defined. */
- for (base = TREE_CHAIN (path); base; base = TREE_CHAIN (base))
- if (TREE_VIA_VIRTUAL (TREE_VALUE (base)))
- {
- base = ffod->declaring_base;
- break;
- }
+ tree *candidate;
- /* If we didn't already have an overrider, or any
- candidates, then this function is the best candidate so
- far. */
- if (!ffod->overriding_fn && !ffod->candidates)
- {
- ffod->overriding_fn = method;
- ffod->overriding_base = TREE_VALUE (path);
- }
- else if (ffod->overriding_fn)
+ /* Remove any candidates overridden by this new function. */
+ candidate = &ffod->candidates;
+ while (*candidate)
{
- /* We had a best overrider; let's see how this compares. */
-
- if (ffod->overriding_fn == method
- && (tree_int_cst_equal
- (BINFO_OFFSET (TREE_VALUE (path)),
- BINFO_OFFSET (ffod->overriding_base))))
- /* We found the same overrider we already have, and in the
- same place; it's still the best. */;
- else if (strictly_overrides (ffod->overriding_fn, method))
- /* The old function overrides this function; it's still the
- best. */;
- else if (strictly_overrides (method, ffod->overriding_fn))
- {
- /* The new function overrides the old; it's now the
- best. */
- ffod->overriding_fn = method;
- ffod->overriding_base = TREE_VALUE (path);
- }
+ /* If *CANDIDATE overrides METHOD, then METHOD
+ cannot override anything else on the list. */
+ if (base_derived_from (TREE_VALUE (*candidate), path))
+ return NULL_TREE;
+ /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
+ if (base_derived_from (path, TREE_VALUE (*candidate)))
+ *candidate = TREE_CHAIN (*candidate);
else
- {
- /* Ambiguous. */
- ffod->candidates
- = build_tree_list (NULL_TREE,
- ffod->overriding_fn);
- if (method != ffod->overriding_fn)
- ffod->candidates
- = tree_cons (NULL_TREE, method, ffod->candidates);
- ffod->overriding_fn = NULL_TREE;
- ffod->overriding_base = NULL_TREE;
- }
+ candidate = &TREE_CHAIN (*candidate);
}
- else
- {
- /* We had a list of ambiguous overrides; let's see how this
- new one compares. */
-
- tree candidates;
- bool incomparable = false;
-
- /* If there were previous candidates, and this function
- overrides all of them, then it is the new best
- candidate. */
- for (candidates = ffod->candidates;
- candidates;
- candidates = TREE_CHAIN (candidates))
- {
- /* If the candidate overrides the METHOD, then we
- needn't worry about it any further. */
- if (strictly_overrides (TREE_VALUE (candidates),
- method))
- {
- method = NULL_TREE;
- break;
- }
-
- /* If the METHOD doesn't override the candidate,
- then it is incomporable. */
- if (!strictly_overrides (method,
- TREE_VALUE (candidates)))
- incomparable = true;
- }
- /* If METHOD overrode all the candidates, then it is the
- new best candidate. */
- if (!candidates && !incomparable)
- {
- ffod->overriding_fn = method;
- ffod->overriding_base = TREE_VALUE (path);
- ffod->candidates = NULL_TREE;
- }
- /* If METHOD didn't override all the candidates, then it
- is another candidate. */
- else if (method && incomparable)
- ffod->candidates
- = tree_cons (NULL_TREE, method, ffod->candidates);
- }
+ /* Add the new function. */
+ ffod->candidates = tree_cons (method, path, ffod->candidates);
}
}
@@ -2387,8 +2336,6 @@ find_final_overrider (t, binfo, fn)
ffod.fn = fn;
ffod.declaring_base = binfo;
ffod.most_derived_type = t;
- ffod.overriding_fn = NULL_TREE;
- ffod.overriding_base = NULL_TREE;
ffod.candidates = NULL_TREE;
dfs_walk (TYPE_BINFO (t),
@@ -2397,13 +2344,13 @@ find_final_overrider (t, binfo, fn)
&ffod);
/* If there was no winner, issue an error message. */
- if (!ffod.overriding_fn)
+ if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
{
error ("no unique final overrider for `%D' in `%T'", fn, t);
return error_mark_node;
}
- return build_tree_list (ffod.overriding_fn, ffod.overriding_base);
+ return ffod.candidates;
}
/* Returns the function from the BINFO_VIRTUALS entry in T which matches
@@ -2642,24 +2589,6 @@ modify_all_vtables (t, vfuns_p, virtuals)
return virtuals;
}
-/* Here, we already know that they match in every respect.
- All we have to check is where they had their declarations.
-
- Return non-zero iff FNDECL1 is declared in a class which has a
- proper base class containing FNDECL2. We don't care about
- ambiguity or accessibility. */
-
-static int
-strictly_overrides (fndecl1, fndecl2)
- tree fndecl1, fndecl2;
-{
- base_kind kind;
-
- return (lookup_base (DECL_CONTEXT (fndecl1), DECL_CONTEXT (fndecl2),
- ba_ignore | ba_quiet, &kind)
- && kind != bk_same_type);
-}
-
/* Get the base virtual function declarations in T that have the
indicated NAME. */
@@ -2756,11 +2685,11 @@ warn_hidden (t)
base_fndecls);
}
- /* If there are no functions to hide, continue. */
+ /* If there are no functions to hide, continue. */
if (!base_fndecls)
continue;
- /* Remove any overridden functions. */
+ /* Remove any overridden functions. */
for (fns = TREE_VEC_ELT (method_vec, i); fns; fns = OVL_NEXT (fns))
{
fndecl = OVL_CURRENT (fns);
@@ -3200,15 +3129,10 @@ check_field_decl (field, t, cant_have_const_ctor,
fields can be added by adding to this chain. */
static void
-check_field_decls (t, access_decls, empty_p,
- cant_have_default_ctor_p, cant_have_const_ctor_p,
- no_const_asn_ref_p)
- tree t;
- tree *access_decls;
- int *empty_p;
- int *cant_have_default_ctor_p;
- int *cant_have_const_ctor_p;
- int *no_const_asn_ref_p;
+check_field_decls (tree t, tree *access_decls,
+ int *cant_have_default_ctor_p,
+ int *cant_have_const_ctor_p,
+ int *no_const_asn_ref_p)
{
tree *field;
tree *next;
@@ -3244,7 +3168,7 @@ check_field_decls (t, access_decls, empty_p,
else
{
/* The class is non-empty. */
- *empty_p = 0;
+ CLASSTYPE_EMPTY_P (t) = 0;
/* The class is not even nearly empty. */
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
}
@@ -3337,7 +3261,8 @@ check_field_decls (t, access_decls, empty_p,
*cant_have_default_ctor_p = 1;
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
- if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
+ if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
+ && extra_warnings)
cp_warning_at ("non-static reference `%#D' in class without a constructor", x);
}
@@ -3371,7 +3296,8 @@ check_field_decls (t, access_decls, empty_p,
*cant_have_default_ctor_p = 1;
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
- if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
+ if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
+ && extra_warnings)
cp_warning_at ("non-static const member `%#D' in class without a constructor", x);
}
/* A field that is pseudo-const makes the structure likewise. */
@@ -3454,7 +3380,7 @@ record_subobject_offset (type, offset, offsets)
return 0;
}
-/* Returns non-zero if TYPE is an empty class type and there is
+/* Returns nonzero if TYPE is an empty class type and there is
already an entry in OFFSETS for the same TYPE as the same OFFSET. */
static int
@@ -3483,13 +3409,13 @@ check_subobject_offset (type, offset, offsets)
/* Walk through all the subobjects of TYPE (located at OFFSET). Call
F for every subobject, passing it the type, offset, and table of
- OFFSETS. If VBASES_P is non-zero, then even virtual non-primary
+ OFFSETS. If VBASES_P is nonzero, then even virtual non-primary
bases should be traversed; otherwise, they are ignored.
If MAX_OFFSET is non-NULL, then subobjects with an offset greater
than MAX_OFFSET will not be walked.
- If F returns a non-zero value, the traversal ceases, and that value
+ If F returns a nonzero value, the traversal ceases, and that value
is returned. Otherwise, returns zero. */
static int
@@ -3511,6 +3437,7 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
if (CLASS_TYPE_P (type))
{
tree field;
+ tree binfo;
int i;
/* Record the location of TYPE. */
@@ -3521,7 +3448,11 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
/* Iterate through the direct base classes of TYPE. */
for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); ++i)
{
- tree binfo = BINFO_BASETYPE (TYPE_BINFO (type), i);
+ binfo = BINFO_BASETYPE (TYPE_BINFO (type), i);
+
+ if (abi_version_at_least (2)
+ && TREE_VIA_VIRTUAL (binfo))
+ continue;
if (!vbases_p
&& TREE_VIA_VIRTUAL (binfo)
@@ -3535,20 +3466,54 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
BINFO_OFFSET (binfo)),
offsets,
max_offset,
- vbases_p);
+ (abi_version_at_least (2)
+ ? /*vbases_p=*/0 : vbases_p));
if (r)
return r;
}
+ /* Iterate through the virtual base classes of TYPE. In G++
+ 3.2, we included virtual bases in the direct base class loop
+ above, which results in incorrect results; the correct
+ offsets for virtual bases are only known when working with
+ the most derived type. */
+ if (abi_version_at_least (2) && vbases_p)
+ {
+ tree vbase;
+
+ for (vbase = CLASSTYPE_VBASECLASSES (type);
+ vbase;
+ vbase = TREE_CHAIN (vbase))
+ {
+ binfo = TREE_VALUE (vbase);
+ r = walk_subobject_offsets (BINFO_TYPE (binfo),
+ f,
+ size_binop (PLUS_EXPR,
+ offset,
+ BINFO_OFFSET (binfo)),
+ offsets,
+ max_offset,
+ /*vbases_p=*/0);
+ }
+ }
+
/* Iterate through the fields of TYPE. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- if (TREE_CODE (field) == FIELD_DECL)
+ if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field))
{
+ tree field_offset;
+
+ if (abi_version_at_least (2))
+ field_offset = byte_position (field);
+ else
+ /* In G++ 3.2, DECL_FIELD_OFFSET was used. */
+ field_offset = DECL_FIELD_OFFSET (field);
+
r = walk_subobject_offsets (TREE_TYPE (field),
f,
size_binop (PLUS_EXPR,
offset,
- DECL_FIELD_OFFSET (field)),
+ field_offset),
offsets,
max_offset,
/*vbases_p=*/1);
@@ -3562,8 +3527,11 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
tree index;
/* Step through each of the elements in the array. */
- for (index = size_zero_node;
- INT_CST_LT (index, TYPE_MAX_VALUE (domain));
+ for (index = size_zero_node;
+ /* G++ 3.2 had an off-by-one error here. */
+ (abi_version_at_least (2)
+ ? !INT_CST_LT (TYPE_MAX_VALUE (domain), index)
+ : INT_CST_LT (index, TYPE_MAX_VALUE (domain)));
index = size_binop (PLUS_EXPR, index, size_one_node))
{
r = walk_subobject_offsets (TREE_TYPE (type),
@@ -3588,7 +3556,7 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
}
/* Record all of the empty subobjects of TYPE (located at OFFSET) in
- OFFSETS. If VBASES_P is non-zero, virtual bases of TYPE are
+ OFFSETS. If VBASES_P is nonzero, virtual bases of TYPE are
examined. */
static void
@@ -3602,8 +3570,8 @@ record_subobject_offsets (type, offset, offsets, vbases_p)
offsets, /*max_offset=*/NULL_TREE, vbases_p);
}
-/* Returns non-zero if any of the empty subobjects of TYPE (located at
- OFFSET) conflict with entries in OFFSETS. If VBASES_P is non-zero,
+/* Returns nonzero if any of the empty subobjects of TYPE (located at
+ OFFSET) conflict with entries in OFFSETS. If VBASES_P is nonzero,
virtual bases of TYPE are examined. */
static int
@@ -3631,22 +3599,34 @@ layout_conflict_p (type, offset, offsets, vbases_p)
/* DECL is a FIELD_DECL corresponding either to a base subobject of a
non-static data member of the type indicated by RLI. BINFO is the
binfo corresponding to the base subobject, OFFSETS maps offsets to
- types already located at those offsets. T is the most derived
- type. This function determines the position of the DECL. */
+ types already located at those offsets. This function determines
+ the position of the DECL. */
static void
-layout_nonempty_base_or_field (rli, decl, binfo, offsets, t)
- record_layout_info rli;
- tree decl;
- tree binfo;
- splay_tree offsets;
- tree t;
+layout_nonempty_base_or_field (record_layout_info rli,
+ tree decl,
+ tree binfo,
+ splay_tree offsets)
{
+ tree t = rli->t;
tree offset = NULL_TREE;
- tree type = TREE_TYPE (decl);
- /* If we are laying out a base class, rather than a field, then
- DECL_ARTIFICIAL will be set on the FIELD_DECL. */
- int field_p = !DECL_ARTIFICIAL (decl);
+ bool field_p;
+ tree type;
+
+ if (binfo)
+ {
+ /* For the purposes of determining layout conflicts, we want to
+ use the class type of BINFO; TREE_TYPE (DECL) will be the
+ CLASSTYPE_AS_BASE version, which does not contain entries for
+ zero-sized bases. */
+ type = TREE_TYPE (binfo);
+ field_p = false;
+ }
+ else
+ {
+ type = TREE_TYPE (decl);
+ field_p = true;
+ }
/* Try to place the field. It may take more than one try if we have
a hard time placing the field without putting two objects of the
@@ -3671,13 +3651,10 @@ layout_nonempty_base_or_field (rli, decl, binfo, offsets, t)
offset zero -- its S component would be at the same address
as the S we already allocated. So, we have to skip ahead.
Since all data members, including those whose type is an
- empty class, have non-zero size, any overlap can happen only
+ empty class, have nonzero size, any overlap can happen only
with a direct or indirect base-class -- it can't happen with
a data member. */
- if (layout_conflict_p (TREE_TYPE (decl),
- offset,
- offsets,
- field_p))
+ if (layout_conflict_p (type, offset, offsets, field_p))
{
/* Strip off the size allocated to this field. That puts us
at the first place we could have put the field with
@@ -3700,15 +3677,22 @@ layout_nonempty_base_or_field (rli, decl, binfo, offsets, t)
/* Now that we know where it will be placed, update its
BINFO_OFFSET. */
if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
+ /* Indirect virtual bases may have a non-zero BINFO_OFFSET at
+ this point because their BINFO_OFFSET is copied from another
+ hierarchy. Therefore, we may not need to add the entire
+ OFFSET. */
propagate_binfo_offsets (binfo,
- convert (ssizetype, offset), t);
+ size_diffop (convert (ssizetype, offset),
+ convert (ssizetype,
+ BINFO_OFFSET (binfo))),
+ t);
}
/* Layout the empty base BINFO. EOC indicates the byte currently just
past the end of the class, and should be correctly aligned for a
class of the type indicated by BINFO; OFFSETS gives the offsets of
the empty bases allocated so far. T is the most derived
- type. Return non-zero iff we added it at the end. */
+ type. Return nonzero iff we added it at the end. */
static bool
layout_empty_base (binfo, eoc, offsets, t)
@@ -3720,10 +3704,17 @@ layout_empty_base (binfo, eoc, offsets, t)
tree alignment;
tree basetype = BINFO_TYPE (binfo);
bool atend = false;
-
+
/* This routine should only be used for empty classes. */
my_friendly_assert (is_empty_class (basetype), 20000321);
alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype));
+
+ if (abi_version_at_least (2))
+ BINFO_OFFSET (binfo) = size_zero_node;
+ if (warn_abi && !integer_zerop (BINFO_OFFSET (binfo)))
+ warning ("offset of empty base `%T' may not be ABI-compliant and may"
+ "change in a future version of GCC",
+ BINFO_TYPE (binfo));
/* This is an empty base class. We first try to put it at offset
zero. */
@@ -3752,60 +3743,77 @@ layout_empty_base (binfo, eoc, offsets, t)
return atend;
}
-/* Build a FIELD_DECL for the base given by BINFO in the class
- indicated by RLI. If the new object is non-empty, clear *EMPTY_P.
- *BASE_ALIGN is a running maximum of the alignments of any base
- class. OFFSETS gives the location of empty base subobjects. T is
- the most derived type. Return non-zero if the new object cannot be
- nearly-empty. */
+/* Layout the the base given by BINFO in the class indicated by RLI.
+ *BASE_ALIGN is a running maximum of the alignments of
+ any base class. OFFSETS gives the location of empty base
+ subobjects. T is the most derived type. Return nonzero if the new
+ object cannot be nearly-empty. A new FIELD_DECL is inserted at
+ *NEXT_FIELD, unless BINFO is for an empty base class.
-static bool
-build_base_field (rli, binfo, empty_p, offsets, t)
- record_layout_info rli;
- tree binfo;
- int *empty_p;
- splay_tree offsets;
- tree t;
+ Returns the location at which the next field should be inserted. */
+
+static tree *
+build_base_field (record_layout_info rli, tree binfo,
+ splay_tree offsets, tree *next_field)
{
+ tree t = rli->t;
tree basetype = BINFO_TYPE (binfo);
- tree decl;
- bool atend = false;
if (!COMPLETE_TYPE_P (basetype))
/* This error is now reported in xref_tag, thus giving better
location information. */
- return atend;
-
- decl = build_decl (FIELD_DECL, NULL_TREE, basetype);
- DECL_ARTIFICIAL (decl) = 1;
- DECL_FIELD_CONTEXT (decl) = rli->t;
- DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
- 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;
+ return next_field;
- if (!integer_zerop (DECL_SIZE (decl)))
+ /* Place the base class. */
+ if (!is_empty_class (basetype))
{
+ tree decl;
+
/* The containing class is non-empty because it has a non-empty
base class. */
- *empty_p = 0;
-
+ CLASSTYPE_EMPTY_P (t) = 0;
+
+ /* Create the FIELD_DECL. */
+ decl = build_decl (FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_FIELD_CONTEXT (decl) = t;
+ DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
+ 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;
+
/* Try to place the field. It may take more than one try if we
have a hard time placing the field without putting two
objects of the same type at the same address. */
- layout_nonempty_base_or_field (rli, decl, binfo, offsets, t);
+ layout_nonempty_base_or_field (rli, decl, binfo, offsets);
+ /* Add the new FIELD_DECL to the list of fields for T. */
+ TREE_CHAIN (decl) = *next_field;
+ *next_field = decl;
+ next_field = &TREE_CHAIN (decl);
}
else
{
- unsigned HOST_WIDE_INT eoc;
+ tree eoc;
/* On some platforms (ARM), even empty classes will not be
byte-aligned. */
- eoc = tree_low_cst (rli_size_unit_so_far (rli), 0);
- eoc = CEIL (eoc, DECL_ALIGN_UNIT (decl)) * DECL_ALIGN_UNIT (decl);
- atend |= layout_empty_base (binfo, size_int (eoc), offsets, t);
+ eoc = round_up (rli_size_unit_so_far (rli),
+ CLASSTYPE_ALIGN_UNIT (basetype));
+ if (layout_empty_base (binfo, eoc, offsets, t))
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+
+ /* We do not create a FIELD_DECL for empty base classes because
+ it might overlap some other field. We want to be able to
+ create CONSTRUCTORs for the class by iterating over the
+ FIELD_DECLs, and the back end does not handle overlapping
+ FIELD_DECLs. */
+
+ /* An empty virtual base causes a class to be non-empty
+ -- but in that case we do not need to clear CLASSTYPE_EMPTY_P
+ here because that was already done when the virtual table
+ pointer was created. */
}
/* Record the offsets of BINFO and its base subobjects. */
@@ -3813,42 +3821,41 @@ build_base_field (rli, binfo, empty_p, offsets, t)
BINFO_OFFSET (binfo),
offsets,
/*vbases_p=*/0);
- return atend;
+
+ return next_field;
}
/* Layout all of the non-virtual base classes. Record empty
- subobjects in OFFSETS. T is the most derived type. Return
- non-zero if the type cannot be nearly empty. */
+ subobjects in OFFSETS. T is the most derived type. Return nonzero
+ if the type cannot be nearly empty. The fields created
+ corresponding to the base classes will be inserted at
+ *NEXT_FIELD. */
-static bool
-build_base_fields (rli, empty_p, offsets, t)
- record_layout_info rli;
- int *empty_p;
- splay_tree offsets;
- tree t;
+static void
+build_base_fields (record_layout_info rli,
+ splay_tree offsets, tree *next_field)
{
/* Chain to hold all the new FIELD_DECLs which stand in for base class
subobjects. */
- tree rec = rli->t;
- int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
+ tree t = rli->t;
+ int n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
int i;
- bool atend = 0;
/* The primary base class is always allocated first. */
- if (CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
- build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (rec),
- empty_p, offsets, t);
+ if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
+ next_field = build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (t),
+ offsets, next_field);
/* Now allocate the rest of the bases. */
for (i = 0; i < n_baseclasses; ++i)
{
tree base_binfo;
- base_binfo = BINFO_BASETYPE (TYPE_BINFO (rec), i);
+ base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i);
/* The primary base was already allocated above, so we don't
need to allocate it again here. */
- if (base_binfo == CLASSTYPE_PRIMARY_BINFO (rec))
+ if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))
continue;
/* A primary virtual base class is allocated just like any other
@@ -3858,9 +3865,9 @@ build_base_fields (rli, empty_p, offsets, t)
&& !BINFO_PRIMARY_P (base_binfo))
continue;
- atend |= build_base_field (rli, base_binfo, empty_p, offsets, t);
+ next_field = build_base_field (rli, base_binfo,
+ offsets, next_field);
}
- return atend;
}
/* Go through the TYPE_METHODS of T issuing any appropriate
@@ -4018,7 +4025,7 @@ build_clone (fn, name)
}
/* Produce declarations for all appropriate clones of FN. If
- UPDATE_METHOD_VEC_P is non-zero, the clones are added to the
+ UPDATE_METHOD_VEC_P is nonzero, the clones are added to the
CLASTYPE_METHOD_VEC as well. */
void
@@ -4080,7 +4087,7 @@ clone_function_decl (fn, update_method_vec_p)
declared. An out-of-class definition can specify additional default
arguments. As it is the clones that are involved in overload
resolution, we must propagate the information from the DECL to its
- clones. */
+ clones. */
void
adjust_clone_args (decl)
@@ -4097,7 +4104,7 @@ adjust_clone_args (decl)
clone_parms = orig_clone_parms;
- /* Skip the 'this' parameter. */
+ /* Skip the 'this' parameter. */
orig_clone_parms = TREE_CHAIN (orig_clone_parms);
orig_decl_parms = TREE_CHAIN (orig_decl_parms);
@@ -4120,7 +4127,7 @@ adjust_clone_args (decl)
if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms))
{
/* A default parameter has been added. Adjust the
- clone's parameters. */
+ clone's parameters. */
tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
tree type;
@@ -4249,9 +4256,7 @@ type_requires_array_cookie (type)
level: i.e., independently of the ABI in use. */
static void
-check_bases_and_members (t, empty_p)
- tree t;
- int *empty_p;
+check_bases_and_members (tree t)
{
/* Nonzero if we are not allowed to generate a default constructor
for this case. */
@@ -4270,16 +4275,12 @@ check_bases_and_members (t, empty_p)
cant_have_const_ctor = 0;
no_const_asn_ref = 0;
- /* 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;
-
- /* Check all the base-classes. */
+ /* Check all the base-classes. */
check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor,
&no_const_asn_ref);
/* Check all the data member declarations. */
- check_field_decls (t, &access_decls, empty_p,
+ check_field_decls (t, &access_decls,
&cant_have_default_ctor,
&cant_have_const_ctor,
&no_const_asn_ref);
@@ -4342,9 +4343,8 @@ check_bases_and_members (t, empty_p)
on VIRTUALS_P. */
static tree
-create_vtable_ptr (t, empty_p, virtuals_p)
+create_vtable_ptr (t, virtuals_p)
tree t;
- int *empty_p;
tree *virtuals_p;
{
tree fn;
@@ -4402,7 +4402,7 @@ create_vtable_ptr (t, empty_p, virtuals_p)
TYPE_VFIELD (t) = field;
/* This class is non-empty. */
- *empty_p = 0;
+ CLASSTYPE_EMPTY_P (t) = 0;
if (CLASSTYPE_N_BASECLASSES (t))
/* If there were any baseclasses, they can't possibly be at
@@ -4551,32 +4551,41 @@ dfs_set_offset_for_unshared_vbases (binfo, data)
return NULL_TREE;
}
-/* Set BINFO_OFFSET for all of the virtual bases for T. Update
+/* Set BINFO_OFFSET for all of the virtual bases for RLI->T. Update
TYPE_ALIGN and TYPE_SIZE for T. OFFSETS gives the location of
empty subobjects of T. */
static void
-layout_virtual_bases (t, offsets)
- tree t;
- splay_tree offsets;
+layout_virtual_bases (record_layout_info rli, splay_tree offsets)
{
- tree vbases, dsize;
- unsigned HOST_WIDE_INT eoc;
+ tree vbases;
+ tree t = rli->t;
+ bool first_vbase = true;
+ tree *next_field;
if (CLASSTYPE_N_BASECLASSES (t) == 0)
return;
+ if (!abi_version_at_least(2))
+ {
+ /* In G++ 3.2, we incorrectly rounded the size before laying out
+ the virtual bases. */
+ finish_record_layout (rli, /*free_p=*/false);
#ifdef STRUCTURE_SIZE_BOUNDARY
- /* Packed structures don't need to have minimum size. */
- if (! TYPE_PACKED (t))
- TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), STRUCTURE_SIZE_BOUNDARY);
+ /* Packed structures don't need to have minimum size. */
+ if (! TYPE_PACKED (t))
+ TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), STRUCTURE_SIZE_BOUNDARY);
#endif
+ rli->offset = TYPE_SIZE_UNIT (t);
+ rli->bitpos = bitsize_zero_node;
+ rli->record_align = TYPE_ALIGN (t);
+ }
- /* DSIZE is the size of the class without the virtual bases. */
- dsize = TYPE_SIZE (t);
-
- /* Make every class have alignment of at least one. */
- TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT);
+ /* Find the last field. The artificial fields created for virtual
+ bases will go after the last extant field to date. */
+ next_field = &TYPE_FIELDS (t);
+ while (*next_field)
+ next_field = &TREE_CHAIN (*next_field);
/* Go through the virtual bases, allocating space for each virtual
base that is not already a primary base class. These are
@@ -4589,56 +4598,37 @@ layout_virtual_bases (t, offsets)
if (!TREE_VIA_VIRTUAL (vbases))
continue;
+
vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
if (!BINFO_PRIMARY_P (vbase))
{
+ tree basetype = TREE_TYPE (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, usize;
- unsigned int desired_align;
-
- basetype = BINFO_TYPE (vbase);
-
- desired_align = CLASSTYPE_ALIGN (basetype);
- TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), desired_align);
-
- /* Add padding so that we can put the virtual base class at an
- appropriately aligned offset. */
- 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,
- convert (sizetype, usize),
- offsets, t);
- else
- {
- tree offset;
-
- offset = convert (ssizetype, usize);
- offset = size_diffop (offset,
- convert (ssizetype,
- BINFO_OFFSET (vbase)));
-
- /* And compute the offset of the virtual base. */
- propagate_binfo_offsets (vbase, offset, t);
- /* Every virtual baseclass takes a least a UNIT, so that
- we can take it's address and get something different
- for each base. */
- dsize = size_binop (PLUS_EXPR, dsize,
- size_binop (MAX_EXPR, bitsize_unit_node,
- CLASSTYPE_SIZE (basetype)));
- }
-
- /* Keep track of the offsets assigned to this virtual base. */
- record_subobject_offsets (BINFO_TYPE (vbase),
- BINFO_OFFSET (vbase),
- offsets,
- /*vbases_p=*/0);
+ next_field = build_base_field (rli, vbase,
+ offsets, next_field);
+
+ /* 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),
+ CLASSTYPE_ALIGN (basetype)),
+ 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);
+
+ first_vbase = false;
}
}
@@ -4648,45 +4638,18 @@ layout_virtual_bases (t, offsets)
in lookup_base depend on the BINFO_OFFSETs being set
correctly. */
dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t);
-
- /* If we had empty base classes that protruded beyond the end of the
- 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);
- 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 = 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));
-
- /* Check for ambiguous virtual bases. */
- if (extra_warnings)
- for (vbases = CLASSTYPE_VBASECLASSES (t);
- vbases;
- vbases = TREE_CHAIN (vbases))
- {
- tree basetype = BINFO_TYPE (TREE_VALUE (vbases));
-
- if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
- warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
- basetype, t);
- }
}
/* Returns the offset of the byte just past the end of the base class
with the highest offset in T. If INCLUDE_VIRTUALS_P is zero, then
only non-virtual bases are included. */
-static unsigned HOST_WIDE_INT
+static tree
end_of_class (t, include_virtuals_p)
tree t;
int include_virtuals_p;
{
- unsigned HOST_WIDE_INT result = 0;
+ tree result = size_zero_node;
int i;
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i)
@@ -4694,7 +4657,6 @@ end_of_class (t, include_virtuals_p)
tree base_binfo;
tree offset;
tree size;
- unsigned HOST_WIDE_INT end_of_base;
base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i);
@@ -4713,15 +4675,14 @@ end_of_class (t, include_virtuals_p)
offset = size_binop (PLUS_EXPR,
BINFO_OFFSET (base_binfo),
size);
- end_of_base = tree_low_cst (offset, /*pos=*/1);
- if (end_of_base > result)
- result = end_of_base;
+ if (INT_CST_LT_UNSIGNED (result, offset))
+ result = offset;
}
return result;
}
-/* Warn about direct bases of T that are inaccessible because they are
+/* Warn about bases of T that are inaccessible because they are
ambiguous. For example:
struct S {};
@@ -4732,19 +4693,35 @@ end_of_class (t, include_virtuals_p)
subobjects of U. */
static void
-warn_about_ambiguous_direct_bases (t)
+warn_about_ambiguous_bases (t)
tree t;
{
int i;
+ tree vbases;
+ tree basetype;
+ /* Check direct bases. */
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i)
{
- tree basetype = TYPE_BINFO_BASETYPE (t, i);
+ basetype = TYPE_BINFO_BASETYPE (t, i);
if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
- basetype, t);
+ basetype, t);
}
+
+ /* Check for ambiguous virtual bases. */
+ if (extra_warnings)
+ for (vbases = CLASSTYPE_VBASECLASSES (t);
+ vbases;
+ vbases = TREE_CHAIN (vbases))
+ {
+ basetype = BINFO_TYPE (TREE_VALUE (vbases));
+
+ if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
+ warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
+ basetype, t);
+ }
}
/* Compare two INTEGER_CSTs K1 and K2. */
@@ -4757,25 +4734,49 @@ splay_tree_compare_integer_csts (k1, k2)
return tree_int_cst_compare ((tree) k1, (tree) k2);
}
+/* Increase the size indicated in RLI to account for empty classes
+ that are "off the end" of the class. */
+
+static void
+include_empty_classes (record_layout_info rli)
+{
+ tree eoc;
+
+ /* It might be the case that we grew the class to allocate a
+ zero-sized base class. That won't be reflected in RLI, yet,
+ because we are willing to overlay multiple bases at the same
+ offset. However, now we need to make sure that RLI is big enough
+ to reflect the entire class. */
+ eoc = end_of_class (rli->t,
+ CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
+ if (TREE_CODE (rli_size_unit_so_far (rli)) == INTEGER_CST
+ && INT_CST_LT_UNSIGNED (rli_size_unit_so_far (rli), eoc))
+ {
+ rli->offset = size_binop (MAX_EXPR, rli->offset, eoc);
+ rli->bitpos = bitsize_zero_node;
+ }
+}
+
/* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate
BINFO_OFFSETs for all of the base-classes. Position the vtable
- pointer. Accumulate declared virtual functions on VIRTUALS_P. */
+ pointer. Accumulate declared virtual functions on VIRTUALS_P. */
static void
-layout_class_type (t, empty_p, vfuns_p, virtuals_p)
- tree t;
- int *empty_p;
- int *vfuns_p;
- tree *virtuals_p;
+layout_class_type (tree t, int *vfuns_p, tree *virtuals_p)
{
tree non_static_data_members;
tree field;
tree vptr;
record_layout_info rli;
- unsigned HOST_WIDE_INT eoc;
/* 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;
+ /* The location at which the next field should be inserted. */
+ tree *next_field;
+ /* T, as a base class. */
+ tree base_t;
/* Keep track of the first non-static data member. */
non_static_data_members = TYPE_FIELDS (t);
@@ -4788,20 +4789,23 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
determine_primary_base (t, vfuns_p);
/* Create a pointer to our virtual function table. */
- vptr = create_vtable_ptr (t, empty_p, virtuals_p);
+ vptr = create_vtable_ptr (t, virtuals_p);
/* The vptr is always the first thing in the class. */
if (vptr)
{
- TYPE_FIELDS (t) = chainon (vptr, TYPE_FIELDS (t));
+ TREE_CHAIN (vptr) = TYPE_FIELDS (t);
+ TYPE_FIELDS (t) = vptr;
+ next_field = &TREE_CHAIN (vptr);
place_field (rli, vptr);
}
+ else
+ next_field = &TYPE_FIELDS (t);
/* Build FIELD_DECLs for all of the non-virtual base-types. */
empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts,
NULL, NULL);
- if (build_base_fields (rli, empty_p, empty_base_offsets, t))
- CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ build_base_fields (rli, empty_base_offsets, next_field);
/* Layout the non-static data members. */
for (field = non_static_data_members; field; field = TREE_CHAIN (field))
@@ -4853,8 +4857,21 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
field. We have to back up by one to find the largest
type that fits. */
integer_type = integer_types[itk - 1];
- padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
- TYPE_SIZE (integer_type));
+
+ if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
+ /* In a union, the padding field must have the full width
+ of the bit-field; all fields start at offset zero. */
+ padding = DECL_SIZE (field);
+ else
+ {
+ if (warn_abi && TREE_CODE (t) == UNION_TYPE)
+ warning ("size assigned to `%T' may not be "
+ "ABI-compliant and may change in a future "
+ "version of GCC",
+ t);
+ padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
+ TYPE_SIZE (integer_type));
+ }
DECL_SIZE (field) = TYPE_SIZE (integer_type);
DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
@@ -4863,7 +4880,30 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
padding = NULL_TREE;
layout_nonempty_base_or_field (rli, field, NULL_TREE,
- empty_base_offsets, t);
+ empty_base_offsets);
+
+ /* 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);
+
+ /* G++ used to use DECL_FIELD_OFFSET as if it were the byte
+ offset of the field. */
+ if (warn_abi
+ && !tree_int_cst_equal (DECL_FIELD_OFFSET (field),
+ byte_position (field))
+ && contains_empty_class_p (TREE_TYPE (field)))
+ cp_warning_at ("`%D' contains empty classes which may cause base "
+ "classes to be placed at different locations in a "
+ "future version of GCC",
+ field);
/* If we needed additional padding after this field, add it
now. */
@@ -4880,68 +4920,73 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
DECL_USER_ALIGN (padding_field) = 0;
layout_nonempty_base_or_field (rli, padding_field,
NULL_TREE,
- empty_base_offsets, t);
+ empty_base_offsets);
}
- }
- /* It might be the case that we grew the class to allocate a
- zero-sized base class. That won't be reflected in RLI, yet,
- because we are willing to overlay multiple bases at the same
- offset. However, now we need to make sure that RLI is big enough
- to reflect the entire class. */
- eoc = end_of_class (t, /*include_virtuals_p=*/0);
- if (TREE_CODE (rli_size_unit_so_far (rli)) == INTEGER_CST
- && compare_tree_int (rli_size_unit_so_far (rli), eoc) < 0)
- {
- rli->offset = size_binop (MAX_EXPR, rli->offset, size_int (eoc));
- rli->bitpos = bitsize_zero_node;
+ last_field_was_bitfield = DECL_C_BIT_FIELD (field);
}
- /* We make all structures have at least one element, so that they
- have non-zero size. The class may be empty even if it has
- basetypes. Therefore, we add the fake field after all the other
- fields; if there are already FIELD_DECLs on the list, their
- offsets will not be disturbed. */
- if (!eoc && *empty_p)
- {
- tree padding;
-
- padding = build_decl (FIELD_DECL, NULL_TREE, char_type_node);
- place_field (rli, padding);
- }
+ if (abi_version_at_least (2) && !integer_zerop (rli->bitpos))
+ /* Make sure that we are on a byte boundary so that the size of
+ the class without virtual bases will always be a round number
+ of bytes. */
+ rli->bitpos = round_up (rli->bitpos, BITS_PER_UNIT);
- /* Let the back-end lay out the type. Note that at this point we
- have only included non-virtual base-classes; we will lay out the
- virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after
- this call are not necessarily correct; they are just the size and
- alignment when no virtual base clases are used. */
- finish_record_layout (rli);
+ /* Make sure that empty classes are reflected in RLI at this
+ point. */
+ include_empty_classes(rli);
/* Delete all zero-width bit-fields from the list of fields. Now
that the type is laid out they are no longer important. */
remove_zero_width_bit_fields (t);
- /* Remember the size and alignment of the class before adding
- the virtual bases. */
- if (*empty_p)
+ /* Create the version of T used for virtual bases. We do not use
+ make_aggr_type for this version; this is an artificial type. For
+ a POD type, we just reuse T. */
+ if (CLASSTYPE_NON_POD_P (t) || CLASSTYPE_EMPTY_P (t))
{
- 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);
+ base_t = make_node (TREE_CODE (t));
+
+ /* Set the size and alignment for the new type. In G++ 3.2, all
+ empty classes were considered to have size zero when used as
+ base classes. */
+ if (!abi_version_at_least (2) && CLASSTYPE_EMPTY_P (t))
+ {
+ TYPE_SIZE (base_t) = bitsize_zero_node;
+ TYPE_SIZE_UNIT (base_t) = size_zero_node;
+ if (warn_abi && !integer_zerop (rli_size_unit_so_far (rli)))
+ warning ("layout of classes derived from empty class `%T' "
+ "may change in a future version of GCC",
+ t);
+ }
+ else
+ {
+ TYPE_SIZE (base_t) = rli_size_so_far (rli);
+ TYPE_SIZE_UNIT (base_t) = rli_size_unit_so_far (rli);
+ }
+ TYPE_ALIGN (base_t) = rli->record_align;
+ TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t);
+
+ /* Copy the fields from T. */
+ next_field = &TYPE_FIELDS (base_t);
+ for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ *next_field = build_decl (FIELD_DECL,
+ DECL_NAME (field),
+ TREE_TYPE (field));
+ DECL_CONTEXT (*next_field) = base_t;
+ DECL_FIELD_OFFSET (*next_field) = DECL_FIELD_OFFSET (field);
+ DECL_FIELD_BIT_OFFSET (*next_field)
+ = DECL_FIELD_BIT_OFFSET (field);
+ next_field = &TREE_CHAIN (*next_field);
+ }
+
+ /* Record the base version of the type. */
+ CLASSTYPE_AS_BASE (t) = base_t;
}
else
- {
- CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
- CLASSTYPE_SIZE_UNIT (t) = TYPE_BINFO_SIZE_UNIT (t);
- }
-
- CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
- CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t);
+ CLASSTYPE_AS_BASE (t) = t;
/* Set the TYPE_DECL for this type to contain the right
value for DECL_OFFSET, so that we can use it as part
@@ -4952,11 +4997,22 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
around. We must get these done before we try to lay out the
virtual function table. As a side-effect, this will remove the
base subobject fields. */
- layout_virtual_bases (t, empty_base_offsets);
+ layout_virtual_bases (rli, empty_base_offsets);
+
+ /* Make sure that empty classes are reflected in RLI at this
+ point. */
+ include_empty_classes(rli);
+
+ /* Make sure not to create any structures with zero size. */
+ if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
+ place_field (rli,
+ build_decl (FIELD_DECL, NULL_TREE, char_type_node));
- /* Warn about direct bases that can't be talked about due to
- ambiguity. */
- warn_about_ambiguous_direct_bases (t);
+ /* Let the back-end lay out the type. */
+ finish_record_layout (rli, /*free_p=*/true);
+
+ /* Warn about bases that can't be talked about due to ambiguity. */
+ warn_about_ambiguous_bases (t);
/* Clean up. */
splay_tree_delete (empty_base_offsets);
@@ -4995,11 +5051,10 @@ finish_struct_1 (t)
{
tree x;
int vfuns;
- /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
+ /* 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;
if (COMPLETE_TYPE_P (t))
{
@@ -5021,12 +5076,17 @@ finish_struct_1 (t)
fixup_inline_methods (t);
+ /* Assume that the class is both empty and nearly empty; we'll clear
+ these flag if necessary. */
+ CLASSTYPE_EMPTY_P (t) = 1;
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
+
/* Do end-of-class semantic processing: checking the validity of the
bases and members and add implicitly generated methods. */
- check_bases_and_members (t, &empty);
+ check_bases_and_members (t);
/* Layout the class itself. */
- layout_class_type (t, &empty, &vfuns, &virtuals);
+ layout_class_type (t, &vfuns, &virtuals);
/* Make sure that we get our own copy of the vfield FIELD_DECL. */
vfield = TYPE_VFIELD (t);
@@ -5037,7 +5097,7 @@ finish_struct_1 (t)
my_friendly_assert (same_type_p (DECL_FIELD_CONTEXT (vfield),
BINFO_TYPE (primary)),
20010726);
- /* The vtable better be at the start. */
+ /* The vtable better be at the start. */
my_friendly_assert (integer_zerop (DECL_FIELD_OFFSET (vfield)),
20010726);
my_friendly_assert (integer_zerop (BINFO_OFFSET (primary)),
@@ -5336,7 +5396,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
if (nonnull)
*nonnull = 1;
- /* if we're in a ctor or dtor, we know our type. */
+ /* if we're in a ctor or dtor, we know our type. */
if (DECL_LANG_SPECIFIC (current_function_decl)
&& (DECL_CONSTRUCTOR_P (current_function_decl)
|| DECL_DESTRUCTOR_P (current_function_decl)))
@@ -5364,7 +5424,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
}
}
-/* Return non-zero if the dynamic type of INSTANCE is known, and
+/* Return nonzero if the dynamic type of INSTANCE is known, and
equivalent to the static type. We also handle the case where
INSTANCE is really a pointer. Return negative if this is a
ctor/dtor. There the dynamic type is known, but this might not be
@@ -5678,7 +5738,7 @@ push_lang_context (name)
/* DECL_IGNORED_P is initially set for these types, to avoid clutter.
(See record_builtin_java_type in decl.c.) However, that causes
incorrect debug entries if these types are actually used.
- So we re-enable debug output after extern "Java". */
+ So we re-enable debug output after extern "Java". */
DECL_IGNORED_P (TYPE_NAME (java_byte_type_node)) = 0;
DECL_IGNORED_P (TYPE_NAME (java_short_type_node)) = 0;
DECL_IGNORED_P (TYPE_NAME (java_int_type_node)) = 0;
@@ -5710,7 +5770,7 @@ pop_lang_context ()
/* Given an OVERLOAD and a TARGET_TYPE, return the function that
matches the TARGET_TYPE. If there is no satisfactory match, return
error_mark_node, and issue an error message if COMPLAIN is
- non-zero. Permit pointers to member function if PTRMEM is non-zero.
+ nonzero. Permit pointers to member function if PTRMEM is nonzero.
If TEMPLATE_ONLY, the name of the overloaded function
was a template-id, and EXPLICIT_TARGS are the explicitly provided
template arguments. */
@@ -6102,7 +6162,7 @@ instantiate_type (lhstype, rhs, flags)
/*explicit_targs=*/NULL_TREE);
case TREE_LIST:
- /* Now we should have a baselink. */
+ /* Now we should have a baselink. */
my_friendly_assert (BASELINK_P (rhs), 990412);
return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags);
@@ -6310,7 +6370,38 @@ is_empty_class (type)
if (! IS_AGGR_TYPE (type))
return 0;
- return integer_zerop (CLASSTYPE_SIZE (type));
+ /* In G++ 3.2, whether or not a class was empty was determined by
+ looking at its size. */
+ if (abi_version_at_least (2))
+ return CLASSTYPE_EMPTY_P (type);
+ else
+ return integer_zerop (CLASSTYPE_SIZE (type));
+}
+
+/* Returns true if TYPE contains an empty class. */
+
+static bool
+contains_empty_class_p (tree type)
+{
+ if (is_empty_class (type))
+ return true;
+ if (CLASS_TYPE_P (type))
+ {
+ tree field;
+ int i;
+
+ for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); ++i)
+ if (contains_empty_class_p (TYPE_BINFO_BASETYPE (type, i)))
+ return true;
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL
+ && !DECL_ARTIFICIAL (field)
+ && is_empty_class (TREE_TYPE (field)))
+ return true;
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ return contains_empty_class_p (TREE_TYPE (type));
+ return false;
}
/* Find the enclosing class of the given NODE. NODE can be a *_DECL or
@@ -6444,7 +6535,7 @@ get_vtbl_decl_for_binfo (binfo)
/* Called from get_primary_binfo via dfs_walk. DATA is a TREE_LIST
who's TREE_PURPOSE is the TYPE of the required primary base and
- who's TREE_VALUE is a list of candidate binfos that we fill in. */
+ who's TREE_VALUE is a list of candidate binfos that we fill in. */
static tree
dfs_get_primary_binfo (binfo, data)
@@ -6551,7 +6642,7 @@ get_primary_binfo (binfo)
return result;
}
-/* If INDENTED_P is zero, indent to INDENT. Return non-zero. */
+/* If INDENTED_P is zero, indent to INDENT. Return nonzero. */
static int
maybe_indent_hierarchy (stream, indent, indented_p)
@@ -6841,6 +6932,7 @@ initialize_array (decl, inits)
context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = NULL_TREE;
DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits);
+ TREE_HAS_CONSTRUCTOR (DECL_INITIAL (decl)) = 1;
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context;
}
@@ -6918,7 +7010,7 @@ get_original_base (base_binfo, binfo)
/* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with
PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo,
and CHAIN the vtable pointer for this binfo after construction is
- complete. VALUE can also be another BINFO, in which case we recurse. */
+ complete. VALUE can also be another BINFO, in which case we recurse. */
static tree
binfo_ctor_vtable (binfo)
@@ -7109,7 +7201,7 @@ dfs_build_secondary_vptr_vtt_inits (binfo, data)
{
/* It's a primary virtual base, and this is not the construction
vtable. Find the base this is primary of in the inheritance graph,
- and use that base's vtable now. */
+ and use that base's vtable now. */
while (BINFO_PRIMARY_BASE_OF (binfo))
binfo = BINFO_PRIMARY_BASE_OF (binfo);
}
@@ -7248,7 +7340,7 @@ accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, inits)
BINFO_TYPE (orig_binfo)),
20000517);
- /* If it doesn't have a vptr, we don't do anything. */
+ /* If it doesn't have a vptr, we don't do anything. */
if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
return;
@@ -7465,7 +7557,10 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
int i;
for (i = 1; i < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++i)
- add = tree_cons (NULL_TREE, null_pointer_node, add);
+ add = tree_cons (NULL_TREE,
+ build1 (NOP_EXPR, vtable_entry_type,
+ null_pointer_node),
+ add);
*prev = add;
}
}
@@ -7910,7 +8005,8 @@ add_vcall_offset_vtbl_entries_1 (binfo, vid)
/* The next vcall offset will be found at a more negative
offset. */
- vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1));
+ vid->index = size_binop (MINUS_EXPR, vid->index,
+ ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
/* Keep track of this function. */
VARRAY_PUSH_TREE (vid->fns, derived_virtuals);