empty11.C: New test.
authorMark Mitchell <mark@codesourcery.com>
Tue, 26 Nov 2002 07:20:13 +0000 (07:20 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 26 Nov 2002 07:20:13 +0000 (07:20 +0000)
* testsuite/g++.dg/abi/empty11.C: New test.
* testsuite/g++.dg/rtti/cv1.C: New test.

* 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.

From-SVN: r59497

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/empty11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/rtti/cv1.C [new file with mode: 0644]

index bdda5b0..5557d2b 100644 (file)
@@ -1,5 +1,12 @@
 2002-11-25  Mark Mitchell  <mark@codesourcery.com>
 
+       * 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.
 
index 4d54376..fdd9c47 100644 (file)
@@ -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.  */
index 4b1142b..b101ac6 100644 (file)
@@ -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
index 27d4824..70ada4e 100644 (file)
@@ -1,3 +1,8 @@
+2002-11-25  Mark Mitchell  <mark@codesourcery.com>
+
+       * testsuite/g++.dg/abi/empty11.C: New test.
+       * testsuite/g++.dg/rtti/cv1.C: New test.
+
 2002-11-25  Hans-Peter Nilsson  <hp@bitrange.com>
 
        * 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 (file)
index 0000000..b35363f
--- /dev/null
@@ -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 (file)
index 0000000..59dd659
--- /dev/null
@@ -0,0 +1,17 @@
+// { dg-do run }
+
+#include <typeinfo>
+#include <string.h>
+
+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;
+}