]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cp-tree.h (CLEAR_DECL_C_BIT_FIELD): New macro.
authorMark Mitchell <mark@codesourcery.com>
Sun, 19 Mar 2000 05:22:04 +0000 (05:22 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 19 Mar 2000 05:22:04 +0000 (05:22 +0000)
* cp-tree.h (CLEAR_DECL_C_BIT_FIELD): New macro.
* class.c (check_bitfield_decl): Turn illegal bitfields into
non-bitfields.
(dfs_propagate_binfo_offsets): Adjust for new size_binop
semantics.
(dfs_offset_for_unshared_vbases): Likewise.
* cvt.c (cp_convert_to_pointer): Convert NULL to a
pointer-to-member correctly under the new ABI.
* expr.c (cplus_expand_constant): Don't use cp_convert when
turning an offset into a pointer-to-member.
* init.c (resolve_offset_ref): Don't adjust pointers-to-members
when dereferencing them under the new ABI.
* typeck.c (get_member_function_from_ptrfunc): Tweak calculation
of pointers-to-members under the new ABI.

From-SVN: r32631

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/expr.c
gcc/cp/init.c
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.abi/empty.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C

index 892a466bd2ea344ae8144aa3aec75ead0b63f768..fbaaad904ca2754ea2bb4cf7e84854bd6b291f0f 100644 (file)
@@ -1,5 +1,20 @@
 2000-03-18  Mark Mitchell  <mark@codesourcery.com>
 
+       * cp-tree.h (CLEAR_DECL_C_BIT_FIELD): New macro.
+       * class.c (check_bitfield_decl): Turn illegal bitfields into
+       non-bitfields.
+       (dfs_propagate_binfo_offsets): Adjust for new size_binop
+       semantics.
+       (dfs_offset_for_unshared_vbases): Likewise.
+       * cvt.c (cp_convert_to_pointer): Convert NULL to a
+       pointer-to-member correctly under the new ABI.
+       * expr.c (cplus_expand_constant): Don't use cp_convert when
+       turning an offset into a pointer-to-member.
+       * init.c (resolve_offset_ref): Don't adjust pointers-to-members
+       when dereferencing them under the new ABI.
+       * typeck.c (get_member_function_from_ptrfunc): Tweak calculation
+       of pointers-to-members under the new ABI.
+       
        * class.c (check_bitfield_decl): Remove restriction on really long
        bitfields.
        (layout_class_type): Implement new ABI handling of bitfields
index 5475ac4ba9253575bbca85887e528a3c9ce90005..02424928d0d1b6af82f9a9139dd2f351d73c4ca5 100644 (file)
@@ -3616,22 +3616,20 @@ check_bitfield_decl (field)
      tree field;
 {
   tree type = TREE_TYPE (field);
+  tree w = NULL_TREE;
 
-  /* Invalid bit-field size done by grokfield.  */
-  /* Detect invalid bit-field type. Simply checking if TYPE is
-     integral is insufficient, as that is the array core of the field
-     type. If TREE_TYPE (field) is integral, then TYPE must be the same.  */
+  /* Detect invalid bit-field type.  */
   if (DECL_INITIAL (field)
       && ! INTEGRAL_TYPE_P (TREE_TYPE (field)))
     {
       cp_error_at ("bit-field `%#D' with non-integral type", field);
-      DECL_INITIAL (field) = NULL;
+      w = error_mark_node;
     }
 
   /* Detect and ignore out of range field width.  */
   if (DECL_INITIAL (field))
     {
-      tree w = DECL_INITIAL (field);
+      w = DECL_INITIAL (field);
 
       /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs.  */
       STRIP_NOPS (w);
@@ -3646,17 +3644,17 @@ check_bitfield_decl (field)
        {
          cp_error_at ("bit-field `%D' width not an integer constant",
                       field);
-         DECL_INITIAL (field) = NULL_TREE;
+         w = error_mark_node;
        }
       else if (tree_int_cst_sgn (w) < 0)
        {
-         DECL_INITIAL (field) = NULL;
          cp_error_at ("negative width in bit-field `%D'", field);
+         w = error_mark_node;
        }
       else if (integer_zerop (w) && DECL_NAME (field) != 0)
        {
-         DECL_INITIAL (field) = NULL;
          cp_error_at ("zero width for bit-field `%D'", field);
+         w = error_mark_node;
        }
       else if (compare_tree_int (w, TYPE_PRECISION (type)) > 0
               && TREE_CODE (type) != ENUMERAL_TYPE
@@ -3672,30 +3670,37 @@ check_bitfield_decl (field)
                                              TREE_UNSIGNED (type)))))
        cp_warning_at ("`%D' is too small to hold all values of `%#T'",
                       field, type);
+    }
+  
+  /* Remove the bit-field width indicator so that the rest of the
+     compiler does not treat that value as an initializer.  */
+  DECL_INITIAL (field) = NULL_TREE;
 
-      if (DECL_INITIAL (field))
-       {
-         DECL_INITIAL (field) = NULL_TREE;
-         DECL_SIZE (field) = convert (bitsizetype, w);
-         DECL_BIT_FIELD (field) = 1;
+  if (w != error_mark_node)
+    {
+      DECL_SIZE (field) = convert (bitsizetype, w);
+      DECL_BIT_FIELD (field) = 1;
 
-         if (integer_zerop (w))
-           {
+      if (integer_zerop (w))
+       {
 #ifdef EMPTY_FIELD_BOUNDARY
-             DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
-                                       EMPTY_FIELD_BOUNDARY);
+         DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
+                                   EMPTY_FIELD_BOUNDARY);
 #endif
 #ifdef PCC_BITFIELD_TYPE_MATTERS
-             if (PCC_BITFIELD_TYPE_MATTERS)
-               DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
-                                         TYPE_ALIGN (type));
+         if (PCC_BITFIELD_TYPE_MATTERS)
+           DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
+                                     TYPE_ALIGN (type));
 #endif
-           }
        }
     }
   else
-    /* Non-bit-fields are aligned for their type.  */
-    DECL_ALIGN (field) = MAX (DECL_ALIGN (field), TYPE_ALIGN (type));
+    {
+      /* Non-bit-fields are aligned for their type.  */
+      DECL_BIT_FIELD (field) = 0;
+      CLEAR_DECL_C_BIT_FIELD (field);
+      DECL_ALIGN (field) = MAX (DECL_ALIGN (field), TYPE_ALIGN (type));
+    }
 }
 
 /* FIELD is a non bit-field.  We are finishing the processing for its
@@ -4678,7 +4683,10 @@ dfs_propagate_binfo_offsets (binfo, data)
   tree offset = (tree) data;
 
   /* Update the BINFO_OFFSET for this base.  */
-  BINFO_OFFSET (binfo) = size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), offset);
+  BINFO_OFFSET (binfo) = fold (build (PLUS_EXPR,
+                                     sizetype,
+                                     BINFO_OFFSET (binfo), 
+                                     offset));
 
   SET_BINFO_MARKED (binfo);
 
@@ -4744,8 +4752,7 @@ dfs_set_offset_for_unshared_vbases (binfo, data)
       tree offset;
       
       vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), t);
-      offset = size_binop (MINUS_EXPR, 
-                          BINFO_OFFSET (vbase), BINFO_OFFSET (binfo));
+      offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo));
       propagate_binfo_offsets (binfo, offset);
     }
 
index fd87926fd03f057522940c630089c70ea562380b..3e6f1c98066fd00fcb5591f75bb782efeb266e87 100644 (file)
@@ -2347,6 +2347,8 @@ extern int flag_new_for_scope;
    && DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield)
 #define SET_DECL_C_BIT_FIELD(NODE) \
   (DECL_LANG_SPECIFIC (FIELD_DECL_CHECK (NODE))->decl_flags.bitfield = 1)
+#define CLEAR_DECL_C_BIT_FIELD(NODE) \
+  (DECL_LANG_SPECIFIC (FIELD_DECL_CHECK (NODE))->decl_flags.bitfield = 0)
 
 /* In a FUNCTION_DECL, nonzero if the function cannot be inlined.  */
 #define DECL_UNINLINABLE(NODE) \
index 9743f3753d5cf33bb1f65d05b647d92451418ad5..d3c24093b63d38ea4bbd3d8a494bc745556ca2bf 100644 (file)
@@ -240,7 +240,13 @@ cp_convert_to_pointer (type, expr)
     {
       if (TYPE_PTRMEMFUNC_P (type))
        return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0);
-      expr = build_int_2 (0, 0);
+
+      if (flag_new_abi && TYPE_PTRMEM_P (type))
+       /* Under the new ABI, a NULL pointer-to-member is represented
+          by -1, not by zero.  */
+       expr = build_int_2 (-1, -1);
+      else
+       expr = build_int_2 (0, 0);
       TREE_TYPE (expr) = type;
       return expr;
     }
index e97a65d55e8f3e121b89a1798d204606a395b7c3..230fa6a154b068d72e1637baaa8ef40537b9ab4b 100644 (file)
@@ -65,11 +65,18 @@ cplus_expand_constant (cst)
                                          bit_position (member),
                                          bitsize_int (BITS_PER_UNIT)));
 
-           /* We offset all pointer to data members by 1 so that we
-              can distinguish between a null pointer to data member
-              and the first data member of a structure.  */
-           offset = size_binop (PLUS_EXPR, offset, size_one_node);
-           cst = cp_convert (type, offset);
+           if (flag_new_abi)
+             /* Under the new ABI, we use -1 to represent the NULL
+                pointer; non-NULL values simply contain the offset of
+                the data member.  */
+             ;
+           else
+             /* We offset all pointer to data members by 1 so that we
+                can distinguish between a null pointer to data member
+                and the first data member of a structure.  */
+             offset = size_binop (PLUS_EXPR, offset, size_one_node);
+
+           cst = fold (build1 (NOP_EXPR, type, offset));
          }
        else
          {
index 960f46b0ac3def934ed90b3a5345dbb172a0a7e4..8994f604239271e26d6864c567cd37caf226293f 100644 (file)
@@ -1821,11 +1821,13 @@ resolve_offset_ref (exp)
       addr = convert_pointer_to (basetype, addr);
       member = cp_convert (ptrdiff_type_node, member);
 
-      /* Pointer to data members are offset by one, so that a null
-        pointer with a real value of 0 is distinguishable from an
-        offset of the first member of a structure.  */
-      member = build_binary_op (MINUS_EXPR, member,
-                               cp_convert (ptrdiff_type_node, integer_one_node));
+      if (!flag_new_abi)
+       /* Pointer to data members are offset by one, so that a null
+          pointer with a real value of 0 is distinguishable from an
+          offset of the first member of a structure.  */
+       member = build_binary_op (MINUS_EXPR, member,
+                                 cp_convert (ptrdiff_type_node, 
+                                             integer_one_node));
 
       return build1 (INDIRECT_REF, type,
                     build (PLUS_EXPR, build_pointer_type (type),
index a92c1febfcf78c6122c93c89e3131bdd6b9f7343..43bd1bc4952048f602835043ba25b8838b7178d3 100644 (file)
@@ -2858,7 +2858,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
        {
          idx = build_binary_op (TRUNC_DIV_EXPR, 
                                 build1 (NOP_EXPR, vtable_index_type, e3),
-                                integer_two_node);
+                                TYPE_SIZE_UNIT (vtable_entry_type));
          e1 = build_binary_op (BIT_AND_EXPR,
                                build1 (NOP_EXPR, vtable_index_type, e3),
                                integer_one_node);
@@ -6332,11 +6332,12 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
        }
       else
        {
-         /* Under the new ABI, we set PFN to twice the index, plus
-            one.  */
+         /* Under the new ABI, we set PFN to the vtable offset, plus
+            one, at which the function can be found.  */
          *idx = NULL_TREE;
          *pfn = fold (build (MULT_EXPR, integer_type_node,
-                             DECL_VINDEX (fn), integer_two_node));
+                             DECL_VINDEX (fn), 
+                             TYPE_SIZE_UNIT (vtable_entry_type)));
          *pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn,
                              integer_one_node));
          *pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/empty.C b/gcc/testsuite/g++.old-deja/g++.abi/empty.C
new file mode 100644 (file)
index 0000000..b7a791f
--- /dev/null
@@ -0,0 +1,68 @@
+// Special g++ Options: -w
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
+
+struct S0
+{
+};
+
+struct S1 : public S0
+{
+};
+
+struct S2 : public S1
+{
+  char c;
+};
+
+// In S3, the S1 instance is allocated first at offset zero.  The S2
+// instance has to be allocated at a subsequent offset; it's first
+// part is also an S1.
+
+struct S3 : public S1, public S2
+{
+};
+
+struct S4 
+{
+  int i;
+};
+
+// In S4, in contrast to S3, S2 is allocated first, and S1 can be
+// allocated on top of S4.
+
+struct S5 : public S2, public S1, public S4
+{
+};
+
+// The T classes are by-hand layouts that should be equivalent to the
+// S classes.
+
+struct T3
+{
+  S1 s1;
+  S2 s2;
+};
+
+struct T5
+{
+  S2 s2;
+  S4 s4;
+};
+
+int main ()
+{
+  if (sizeof (S3) != sizeof (T3))
+    return 1;
+  else if (sizeof (S5) != sizeof (T5))
+    return 2;
+}
+
+#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
+
+int main () 
+{
+}
+
+#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
index 8dc3ee46a5cf75fcc305052b6cd51f5a38b101c4..975d9397ded8540ce0946b15308559b970971768 100644 (file)
@@ -82,16 +82,16 @@ main ()
   if (xp->adj != delta)
     return 8;
 
-  // For a virtual function, we should see twice the vtable index,
-  // plus one.  `T::h' is in the third slot: there's the RTTI entry,
-  // then the two virtual functions.
+  // For a virtual function, we should see the vtable offset, plus
+  // one.  `T::h' is in the second slot: the vtable pointer points to
+  // the first virtual function.
   y = &T::h;
-  if ((ptrdiff_t) yp->ptr != 7)
+  if ((ptrdiff_t) yp->ptr != sizeof (void *) + 1)
     return 9;
   if (yp->adj != 0)
     return 10;
   x = (sp) y;
-  if ((ptrdiff_t) xp->ptr != 7)
+  if ((ptrdiff_t) xp->ptr != sizeof (void *) + 1)
     return 11;
   if (xp->adj != delta)
     return 12;
@@ -103,9 +103,14 @@ main ()
   if (__alignof__ (sdp) != __alignof__ (ptrdiff_t))
     return 14;
 
+  // The value of a pointer-to-data member should be the offset from
+  // the start of the structure.
   sdp z = &S::j;
-  if ((char *) &s.j - (char *) &s != *((ptrdiff_t *) &z) - 1)
+  if ((char *) &s.j - (char *) &s != *((ptrdiff_t *) &z))
     return 15;
+  z = 0;
+  if (*((ptrdiff_t *) &z) != -1)
+    return 16;
 }
 
 #else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */