diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-10-22 05:04:48 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-10-22 05:04:48 +0000 |
commit | 64f10f70b459140b86edfb3101a5c6d3f8715a08 (patch) | |
tree | 4b99387bab5f35027f255ee22e338f0031a4d558 /gcc | |
parent | 0725d7debf0dc1956b9fdcda2f1ff8ca48f97a30 (diff) | |
download | gcc-64f10f70b459140b86edfb3101a5c6d3f8715a08.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58397 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/class.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/vbase13.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/vbase14.C | 6 |
5 files changed, 75 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6fa961f6ad5..ed176188426 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 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. (layout_class_type): Likewise. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4923b00fb8a..1439833b209 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -209,6 +209,7 @@ 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); +static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree); /* Macros for dfs walking during vtt construction. See 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, 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. */ + /* 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)) { /* Strip off the size allocated to this field. That puts us @@ -3708,6 +3713,16 @@ layout_nonempty_base_or_field (record_layout_info rli, 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 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 @@ -3816,14 +3831,37 @@ build_base_field (record_layout_info rli, tree binfo, else { tree eoc; + bool atend; /* On some platforms (ARM), even empty classes will not be byte-aligned. */ 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; - + atend = layout_empty_base (binfo, eoc, offsets, t); + /* 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 it might overlap some other field. We want to be able to create CONSTRUCTORs for the class by iterating over the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4fc092cc836..314b222aa40 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +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> * gcc.dg/tls/pic-1.c: New test. diff --git a/gcc/testsuite/g++.dg/abi/vbase13.C b/gcc/testsuite/g++.dg/abi/vbase13.C new file mode 100644 index 00000000000..6a0bff484d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/vbase13.C @@ -0,0 +1,17 @@ +// { 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; +} diff --git a/gcc/testsuite/g++.dg/abi/vbase14.C b/gcc/testsuite/g++.dg/abi/vbase14.C new file mode 100644 index 00000000000..99290b85720 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/vbase14.C @@ -0,0 +1,6 @@ +// { 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" } |