diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bdda5b04c7a..5557d2bb5b1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2002-11-25 Mark Mitchell + * tree.c (cp_build_qualified_type_real): Correct handling of + array types. + * class.c (walk_subobject_offsets): Fix thinko. + (build_base_field): Record offsets of empty bases in primary + virtual bases. + (layout_class_type): Record offsets of empty bases in fields. + * search.c (is_subobject_of_p_1): Fix thinko. (lookup_field_queue_p): Likewise. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4d54376fb96..fdd9c479a83 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3391,8 +3391,8 @@ 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 nonzero, then even virtual non-primary - bases should be traversed; otherwise, they are ignored. + OFFSETS. If VBASES_P is one, then virtual non-primary bases should + be traversed. If MAX_OFFSET is non-NULL, then subobjects with an offset greater than MAX_OFFSET will not be walked. @@ -3480,6 +3480,8 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p) offsets, max_offset, /*vbases_p=*/0); + if (r) + return r; } } @@ -3851,6 +3853,27 @@ build_base_field (record_layout_info rli, tree binfo, offsets, /*vbases_p=*/0); + if (abi_version_at_least (2)) + { + /* If BINFO has a primary virtual base that is really going to + be located at the same offset as binfo, it will have been + skipped -- but we should record empty bases from there too. */ + while (true) + { + tree b; + + b = get_primary_binfo (binfo); + if (!b || BINFO_PRIMARY_BASE_OF (b) != binfo) + break; + if (TREE_VIA_VIRTUAL (b)) + record_subobject_offsets (BINFO_TYPE (b), + BINFO_OFFSET (b), + offsets, + /*vbases_p=*/0); + binfo = b; + } + } + return next_field; } @@ -4940,6 +4963,13 @@ layout_class_type (tree t, tree *virtuals_p) layout_nonempty_base_or_field (rli, field, NULL_TREE, empty_base_offsets); + /* Remember the location of any empty classes in FIELD. */ + if (abi_version_at_least (2)) + record_subobject_offsets (TREE_TYPE (field), + byte_position(field), + empty_base_offsets, + /*vbases_p=*/1); + /* 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. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 4b1142b1154..b101ac6ba04 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -650,17 +650,10 @@ cp_build_qualified_type_real (type, type_quals, complain) if (element_type == error_mark_node) return error_mark_node; - /* See if we already have an identically qualified type. */ - t = get_qualified_type (type, type_quals); - - /* If we didn't already have it, create it now. */ - if (!t) - { - /* Make a new array type, just like the old one, but with the - appropriately qualified element type. */ - t = build_type_copy (type); - TREE_TYPE (t) = element_type; - } + /* Make a new array type, just like the old one, but with the + appropriately qualified element type. */ + t = build_type_copy (type); + TREE_TYPE (t) = element_type; /* Even if we already had this variant, we update TYPE_NEEDS_CONSTRUCTING and TYPE_HAS_NONTRIVIAL_DESTRUCTOR in case diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 27d4824da2c..70ada4e3047 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2002-11-25 Mark Mitchell + + * testsuite/g++.dg/abi/empty11.C: New test. + * testsuite/g++.dg/rtti/cv1.C: New test. + 2002-11-25 Hans-Peter Nilsson * lib/prune.exp: Prune more -fpic/-fPIC warnings. diff --git a/gcc/testsuite/g++.dg/abi/empty11.C b/gcc/testsuite/g++.dg/abi/empty11.C new file mode 100644 index 00000000000..b35363f5bf6 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/empty11.C @@ -0,0 +1,19 @@ +// { dg-do run } +// { dg-options "-w -fabi-version=0" } + +struct E {}; +struct E2 : public E {}; +struct E3 : public E, public E2 {}; +struct E4 : public E, public E2, public E3 { }; +struct E5 : public E, public E2, public E3, public E4 {}; + +struct S : public virtual E5 { + E e; +}; + +S s; + +int main () { + if ((char*)(E4*)&s - (char*)&s == 0) + return 1; +} diff --git a/gcc/testsuite/g++.dg/rtti/cv1.C b/gcc/testsuite/g++.dg/rtti/cv1.C new file mode 100644 index 00000000000..59dd6592c9d --- /dev/null +++ b/gcc/testsuite/g++.dg/rtti/cv1.C @@ -0,0 +1,17 @@ +// { dg-do run } + +#include +#include + +struct S {}; + +typedef S volatile T[4]; + +T t[3]; + +const std::type_info& ti = typeid (t); + +int main () { + if (strcmp (ti.name (), "A3_A4_1S") != 0) + return 1; +}