Commit 7ba539c6 by Mark Mitchell Committed by Mark Mitchell

class.c (empty_base_at_nonzero_offset_p): New function.

	* class.c (empty_base_at_nonzero_offset_p): New function.
	(layout_nonempty_base_or_field): Do not check for conflicts when
	laying out a virtual base using the GCC 3.2 ABI.
	(build_base_field): Correct checking for presence of empty classes
	at non-zero offsets when clearing CLASSTYPE_NEARLY_EMPTY_P.

	* g++.dg/abi/vbase13.C: New test.
	* g++.dg/abi/vbase14.C: Likewise.

From-SVN: r58397
parent 5e26e5a2
2002-10-21 Mark Mitchell <mark@codesourcery.com> 2002-10-21 Mark Mitchell <mark@codesourcery.com>
* class.c (empty_base_at_nonzero_offset_p): New function.
(layout_nonempty_base_or_field): Do not check for conflicts when
laying out a virtual base using the GCC 3.2 ABI.
(build_base_field): Correct checking for presence of empty classes
at non-zero offsets when clearing CLASSTYPE_NEARLY_EMPTY_P.
* class.c (include_empty_classes): Use normalize_rli. * class.c (include_empty_classes): Use normalize_rli.
(layout_class_type): Likewise. (layout_class_type): Likewise.
......
...@@ -209,6 +209,7 @@ static bool type_requires_array_cookie PARAMS ((tree)); ...@@ -209,6 +209,7 @@ static bool type_requires_array_cookie PARAMS ((tree));
static bool contains_empty_class_p (tree); static bool contains_empty_class_p (tree);
static tree dfs_base_derived_from (tree, void *); static tree dfs_base_derived_from (tree, void *);
static bool base_derived_from (tree, tree); static bool base_derived_from (tree, tree);
static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
/* Macros for dfs walking during vtt construction. See /* Macros for dfs walking during vtt construction. See
dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits
...@@ -3674,6 +3675,10 @@ layout_nonempty_base_or_field (record_layout_info rli, ...@@ -3674,6 +3675,10 @@ layout_nonempty_base_or_field (record_layout_info rli,
empty class, have nonzero 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 with a direct or indirect base-class -- it can't happen with
a data member. */ a data member. */
/* G++ 3.2 did not check for overlaps when placing a non-empty
virtual base. */
if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo))
break;
if (layout_conflict_p (type, offset, offsets, field_p)) if (layout_conflict_p (type, offset, offsets, field_p))
{ {
/* Strip off the size allocated to this field. That puts us /* Strip off the size allocated to this field. That puts us
...@@ -3708,6 +3713,16 @@ layout_nonempty_base_or_field (record_layout_info rli, ...@@ -3708,6 +3713,16 @@ layout_nonempty_base_or_field (record_layout_info rli,
t); t);
} }
/* Returns true if TYPE is empty and OFFSET is non-zero. */
static int
empty_base_at_nonzero_offset_p (tree type,
tree offset,
splay_tree offsets ATTRIBUTE_UNUSED)
{
return is_empty_class (type) && !integer_zerop (offset);
}
/* Layout the empty base BINFO. EOC indicates the byte currently just /* Layout the empty base BINFO. EOC indicates the byte currently just
past the end of the class, and should be correctly aligned for a 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 class of the type indicated by BINFO; OFFSETS gives the offsets of
...@@ -3816,14 +3831,37 @@ build_base_field (record_layout_info rli, tree binfo, ...@@ -3816,14 +3831,37 @@ build_base_field (record_layout_info rli, tree binfo,
else else
{ {
tree eoc; tree eoc;
bool atend;
/* On some platforms (ARM), even empty classes will not be /* On some platforms (ARM), even empty classes will not be
byte-aligned. */ byte-aligned. */
eoc = round_up (rli_size_unit_so_far (rli), eoc = round_up (rli_size_unit_so_far (rli),
CLASSTYPE_ALIGN_UNIT (basetype)); CLASSTYPE_ALIGN_UNIT (basetype));
if (layout_empty_base (binfo, eoc, offsets, t)) atend = layout_empty_base (binfo, eoc, offsets, t);
CLASSTYPE_NEARLY_EMPTY_P (t) = 0; /* A nearly-empty class "has no proper base class that is empty,
not morally virtual, and at an offset other than zero." */
if (!TREE_VIA_VIRTUAL (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
{
if (atend)
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
/* The check above (used in G++ 3.2) is insufficient because
an empty class placed at offset zero might itself have an
empty base at a non-zero offset. */
else if (walk_subobject_offsets (basetype,
empty_base_at_nonzero_offset_p,
size_zero_node,
/*offsets=*/NULL,
/*max_offset=*/NULL_TREE,
/*vbases_p=*/true))
{
if (abi_version_at_least (2))
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
else if (warn_abi)
warning ("class `%T' will be considered nearly empty in a "
"future version of GCC", t);
}
}
/* We do not create a FIELD_DECL for empty base classes because /* We do not create a FIELD_DECL for empty base classes because
it might overlap some other field. We want to be able to it might overlap some other field. We want to be able to
create CONSTRUCTORs for the class by iterating over the create CONSTRUCTORs for the class by iterating over the
......
2002-10-21 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/vbase13.C: New test.
* g++.dg/abi/vbase14.C: Likewise.
2002-10-21 Jakub Jelinek <jakub@redhat.com> 2002-10-21 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/tls/pic-1.c: New test. * gcc.dg/tls/pic-1.c: New test.
......
// { dg-do run }
// { dg-options "-fabi-version=0 -w" }
struct E1 {};
struct E2 : public E1 {};
struct E : public E1, public E2 {};
struct N : public E { virtual void f () {} };
struct X : virtual public N {
};
int main () {
X x;
/* N should not be the primary base of X; it is not nearly empty. */
if ((void*)&x == (void*)(N*)&x)
return 1;
}
// { dg-options "-Wabi" }
struct E1 {};
struct E2 : public E1 {}; // { dg-warning "layout" }
struct E : public E1, public E2 {}; // { dg-warning "layout|ambiguity" }
struct N : public E { virtual void f () {} }; // { dg-warning "nearly" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment