target-def.h (TARGET_CXX_GET_COOKIE_SIZE, [...]): Define.
authorPaul Brook <paul@codesourcery.com>
Tue, 29 Jun 2004 14:50:35 +0000 (14:50 +0000)
committerPaul Brook <pbrook@gcc.gnu.org>
Tue, 29 Jun 2004 14:50:35 +0000 (14:50 +0000)
gcc/
* target-def.h (TARGET_CXX_GET_COOKIE_SIZE,
TARGET_CXX_COOKIE_HAS_SIZE): Define.
(TARGET_CXX): Use them.
* target.h (struct gcc_target): Add cxx.get_cookie_size and
cxx.cookie_has_size.
* targhooks.c (default_cxx_get_cookie_size): New fucntion.
* targhooks.h (default_cxx_get_cookie_size): Add prototype.
* config/arm/arm.c (TARGET_CXX_GET_COOKIE_SIZE,
TARGET_CXX_COOKIE_HAS_SIZE): Define.
(arm_get_cookie_size, arm_cookie_has_size): New functions.
* Make-lang.in (cp/init.o): Add dependency on $(TARGET_H).
* doc/tm.texi: Document TARGET_CXX_GET_COOKIE_SIZE and
TARGET_CXX_COOKIE_HAS_SIZE.
gcc/cp/
* init.c: Include target.h.
(get_cookie_size): Remove and replace with target hook.
Update callers.
(build_new_1): Store the element size in the cookie.
libstdc++-v3/
* libsupc++/vec.cc (__cxa_vec_new2, __cxa_vec_new3): Store the
element size in the cookie.
testsuite/
* g++.old-deja/g++.abi/arraynew.C: Handle ARM EABI cookies.
* g++.old-deja/g++.abi/cxa_vec.C: Allocate larger cookies for AEABI.

From-SVN: r83854

15 files changed:
gcc/ChangeLog
gcc/config/arm/arm.c
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/init.c
gcc/doc/tm.texi
gcc/target-def.h
gcc/target.h
gcc/targhooks.c
gcc/targhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.abi/arraynew.C
gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C
libstdc++-v3/ChangeLog
libstdc++-v3/libsupc++/vec.cc

index 01c0285f4be01f8df2a67fca63c39151133c1248..3ad291e0a924a18a820988bede589904700d82c5 100644 (file)
@@ -1,3 +1,19 @@
+2004-06-29  Paul Brook  <paul@codesourcery.com>
+
+       * target-def.h (TARGET_CXX_GET_COOKIE_SIZE,
+       TARGET_CXX_COOKIE_HAS_SIZE): Define.
+       (TARGET_CXX): Use them.
+       * target.h (struct gcc_target): Add cxx.get_cookie_size and
+       cxx.cookie_has_size.
+       * targhooks.c (default_cxx_get_cookie_size): New fucntion.
+       * targhooks.h (default_cxx_get_cookie_size): Add prototype.
+       * config/arm/arm.c (TARGET_CXX_GET_COOKIE_SIZE,
+       TARGET_CXX_COOKIE_HAS_SIZE): Define.
+       (arm_get_cookie_size, arm_cookie_has_size): New functions.
+       * Make-lang.in (cp/init.o): Add dependency on $(TARGET_H).
+       * doc/tm.texi: Document TARGET_CXX_GET_COOKIE_SIZE and
+       TARGET_CXX_COOKIE_HAS_SIZE.
+
 2004-06-29  J"orn Rennecke <joern.rennecke@superh.com>
 
        * cfglayout.c (fixup_reorder_chain): Don't do anything for
index a7262f54dd9c9e761142ce8dae692a0ae8e3110b..7cd1573a03c91dad3b69e78e560554c00ff6e1e1 100644 (file)
@@ -164,6 +164,8 @@ static bool arm_align_anon_bitfield (void);
 
 static tree arm_cxx_guard_type (void);
 static bool arm_cxx_guard_mask_bit (void);
+static tree arm_get_cookie_size (tree);
+static bool arm_cookie_has_size (void);
 
 \f
 /* Initialize the GCC target structure.  */
@@ -273,6 +275,12 @@ static bool arm_cxx_guard_mask_bit (void);
 #undef TARGET_CXX_GUARD_MASK_BIT
 #define TARGET_CXX_GUARD_MASK_BIT arm_cxx_guard_mask_bit
 
+#undef TARGET_CXX_GET_COOKIE_SIZE
+#define TARGET_CXX_GET_COOKIE_SIZE arm_get_cookie_size
+
+#undef TARGET_CXX_COOKIE_HAS_SIZE
+#define TARGET_CXX_COOKIE_HAS_SIZE arm_cookie_has_size
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
@@ -14564,3 +14572,28 @@ arm_cxx_guard_mask_bit (void)
 {
   return TARGET_AAPCS_BASED;
 }
+
+
+/* The EABI specifies that all array cookies are 8 bytes long.  */
+
+static tree
+arm_get_cookie_size (tree type)
+{
+  tree size;
+
+  if (!TARGET_AAPCS_BASED)
+    return default_cxx_get_cookie_size (type);
+
+  size = build_int_2 (8, 0);
+  TREE_TYPE (size) = sizetype;
+  return size;
+}
+
+
+/* The EABI says that array cookies should also contain the element size.  */
+
+static bool
+arm_cookie_has_size (void)
+{
+  return TARGET_AAPCS_BASED;
+}
index 532180d82c25cecc19cc85596790662b6ec90a5f..203c36a24cba59b6b8c103f87f8407e2753ac337 100644 (file)
@@ -1,3 +1,10 @@
+2004-06-29  Paul Brook  <paul@codesourcery.com>
+
+       * init.c: Include target.h.
+       (get_cookie_size): Remove and replace with target hook.
+       Update callers.
+       (build_new_1): Store the element size in the cookie.
+
 2004-06-29  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/16260
index 997b8aac4a8926a67eb83cf0b0cc69099d57a44a..34fb529fbc8c98a7d5d62397a497adb7b014de5f 100644 (file)
@@ -235,7 +235,7 @@ cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \
      diagnostic.h intl.h gt-cp-call.h convert.h target.h
 cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
 cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
-  except.h
+  except.h $(TARGET_H)
 cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \
   $(TM_P_H) $(TARGET_H) gt-cp-method.h
 cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h
index c96e14d8070b620213a14140f494aa4b75a8a23e..4e02b9d2baeb4de89432183c42fdee134c838cdd 100644 (file)
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "except.h"
 #include "toplev.h"
+#include "target.h"
 
 static bool begin_init_stmts (tree *, tree *);
 static tree finish_init_stmts (bool, tree, tree);
@@ -52,7 +53,6 @@ static tree get_temp_regvar (tree, tree);
 static tree dfs_initialize_vtbl_ptrs (tree, void *);
 static tree build_default_init (tree, tree);
 static tree build_new_1        (tree);
-static tree get_cookie_size (tree);
 static tree build_dtor_call (tree, special_function_kind, int);
 static tree build_field_list (tree, tree, int *);
 static tree build_vtbl_address (tree);
@@ -1756,29 +1756,6 @@ build_java_class_ref (tree type)
   return class_decl;
 }
 
-/* Returns the size of the cookie to use when allocating an array
-   whose elements have the indicated TYPE.  Assumes that it is already
-   known that a cookie is needed.  */
-
-static tree
-get_cookie_size (tree type)
-{
-  tree cookie_size;
-
-  /* We need to allocate an additional max (sizeof (size_t), alignof
-     (true_type)) bytes.  */
-  tree sizetype_size;
-  tree type_align;
-  
-  sizetype_size = size_in_bytes (sizetype);
-  type_align = size_int (TYPE_ALIGN_UNIT (type));
-  if (INT_CST_LT_UNSIGNED (type_align, sizetype_size))
-    cookie_size = sizetype_size;
-  else
-    cookie_size = type_align;
-
-  return cookie_size;
-}
 
 /* Called from cplus_expand_expr when expanding a NEW_EXPR.  The return
    value is immediately handed to expand_expr.  */
@@ -1925,7 +1902,7 @@ build_new_1 (tree exp)
          /* If a cookie is required, add some extra space.  */
          if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
            {
-             cookie_size = get_cookie_size (true_type);
+             cookie_size = targetm.cxx.get_cookie_size (true_type);
              size = size_binop (PLUS_EXPR, size, cookie_size);
            }
          /* Create the argument list.  */
@@ -1948,7 +1925,7 @@ build_new_1 (tree exp)
          /* Use a global operator new.  */
          /* See if a cookie might be required.  */
          if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
-           cookie_size = get_cookie_size (true_type);
+           cookie_size = targetm.cxx.get_cookie_size (true_type);
          else
            cookie_size = NULL_TREE;
 
@@ -2019,6 +1996,7 @@ build_new_1 (tree exp)
   if (cookie_size)
     {
       tree cookie;
+      tree cookie_ptr;
 
       /* Adjust so we're pointing to the start of the object.  */
       data_addr = get_target_expr (build (PLUS_EXPR, full_pointer_type,
@@ -2027,11 +2005,23 @@ build_new_1 (tree exp)
       /* Store the number of bytes allocated so that we can know how
         many elements to destroy later.  We use the last sizeof
         (size_t) bytes to store the number of elements.  */
-      cookie = build (MINUS_EXPR, build_pointer_type (sizetype),
+      cookie_ptr = build (MINUS_EXPR, build_pointer_type (sizetype),
                      data_addr, size_in_bytes (sizetype));
-      cookie = build_indirect_ref (cookie, NULL);
+      cookie = build_indirect_ref (cookie_ptr, NULL);
 
       cookie_expr = build (MODIFY_EXPR, sizetype, cookie, nelts);
+
+      if (targetm.cxx.cookie_has_size ())
+       {
+         /* Also store the element size.  */
+         cookie_ptr = build (MINUS_EXPR, build_pointer_type (sizetype),
+                             cookie_ptr, size_in_bytes (sizetype));
+         cookie = build_indirect_ref (cookie_ptr, NULL);
+         cookie = build (MODIFY_EXPR, sizetype, cookie,
+                         size_in_bytes(true_type));
+         cookie_expr = build (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
+                              cookie, cookie_expr);
+       }
       data_addr = TARGET_EXPR_SLOT (data_addr);
     }
   else
@@ -2278,7 +2268,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
        {
          tree cookie_size;
 
-         cookie_size = get_cookie_size (type);
+         cookie_size = targetm.cxx.get_cookie_size (type);
          base_tbd 
            = cp_convert (ptype,
                          cp_build_binary_op (MINUS_EXPR,
index d01993f3a680d6153584ccf33de3116a1d0d77b6..944477def10e4af2c5f094393ed67be22d3097d6 100644 (file)
@@ -8477,6 +8477,19 @@ This hook determines how guard variables are used.  It should return
 @code{true} indicates the least significant bit should be used.
 @end deftypefn
 
+@deftypefn {Target Hook} tree TARGET_CXX_GET_COOKIE_SIZE (tree @var{type})
+This hook returns the size of the cookie to use when allocating an array
+whose elements have the indicated @var{type}.  Assumes that it is already
+known that a cookie is needed.  The default is
+@code{max(sizeof (size_t), alignof(type))}, as defined in section 2.7 of the
+IA64/Generic C++ ABI.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_CXX_COOKIE_HAS_SIZE (void)
+This hook should return @code{true} if the element size should be stored in
+array cookies.  The default is to return @code{false}.
+@end deftypefn
+
 @node Misc
 @section Miscellaneous Parameters
 @cindex parameters, miscellaneous
index 72fda5b2ab53724abb84fbfdac1f80a46489f8c5..0761a06f7169f10179c364840a9f9fb34aba6342 100644 (file)
@@ -400,10 +400,20 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #define TARGET_CXX_GUARD_MASK_BIT hook_bool_void_false
 #endif
 
+#ifndef TARGET_CXX_GET_COOKIE_SIZE
+#define TARGET_CXX_GET_COOKIE_SIZE default_cxx_get_cookie_size
+#endif
+
+#ifndef TARGET_CXX_COOKIE_HAS_SIZE
+#define TARGET_CXX_COOKIE_HAS_SIZE hook_bool_void_false
+#endif
+
 #define TARGET_CXX             \
   {                            \
     TARGET_CXX_GUARD_TYPE,     \
-    TARGET_CXX_GUARD_MASK_BIT  \
+    TARGET_CXX_GUARD_MASK_BIT, \
+    TARGET_CXX_GET_COOKIE_SIZE,        \
+    TARGET_CXX_COOKIE_HAS_SIZE \
   }
 
 /* The whole shebang.  */
index 2c4b5300ec4026c8c9305323e57b744564bb1f7a..da37fcd23bdccb4bef8e1ce5ad1699908140d851 100644 (file)
@@ -482,6 +482,11 @@ struct gcc_target
     tree (*guard_type) (void);
     /* Return true if only the low bit of the guard should be tested.  */
     bool (*guard_mask_bit) (void);
+    /* Returns the size of the array cookie for an array of type.  */
+    tree (*get_cookie_size) (tree);
+    /* Returns true if the element size should be stored in the
+       array cookie.  */
+    bool (*cookie_has_size) (void);
   } cxx;
 
   /* Leave the boolean fields at the end.  */
index 5d2a75fe3154accd369891bdf5e9edf8de5048b9..a2745c4cbcd3c5b969a36ff60907102f3eae20af 100644 (file)
@@ -143,3 +143,28 @@ default_cxx_guard_type (void)
 {
   return long_long_integer_type_node;
 }
+
+
+/* Returns the size of the cookie to use when allocating an array
+   whose elements have the indicated TYPE.  Assumes that it is already
+   known that a cookie is needed.  */
+
+tree
+default_cxx_get_cookie_size (tree type)
+{
+  tree cookie_size;
+
+  /* We need to allocate an additional max (sizeof (size_t), alignof
+     (true_type)) bytes.  */
+  tree sizetype_size;
+  tree type_align;
+  
+  sizetype_size = size_in_bytes (sizetype);
+  type_align = size_int (TYPE_ALIGN_UNIT (type));
+  if (INT_CST_LT_UNSIGNED (type_align, sizetype_size))
+    cookie_size = sizetype_size;
+  else
+    cookie_size = type_align;
+
+  return cookie_size;
+}
index 427334f02c15bce84514ff28d00548a19f283031..fba17f82001c640d29945c70b2a8cd266e138c67 100644 (file)
@@ -33,3 +33,4 @@ extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
 
 extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
 extern tree default_cxx_guard_type (void);
+extern tree default_cxx_get_cookie_size (tree);
index 3fe71ecf5dbd3d4313ff7494d0661dff1b8371ec..1bc26719b394d371e90eac0366421b85fc85ba0c 100644 (file)
@@ -1,3 +1,8 @@
+2004-06-29  Paul Brook  <paul@codesourcery.com>
+
+       * g++.old-deja/g++.abi/arraynew.C: Handle ARM EABI cookies.
+       * g++.old-deja/g++.abi/cxa_vec.C: Allocate larger cookies for AEABI.
+
 2004-06-29  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/16260
index 3b11796c2719adea6013132be13bc2d4b313bd35..273d137b85e64004cc8a05084b5274eb678c60d1 100644 (file)
@@ -36,11 +36,16 @@ template <typename T>
 void check_cookie (int i)
 {
   void* a = new T[11];
+  size_t x;
   
   // Compute the cookie location manually.
-  size_t x = __alignof__ (T);
+#ifdef __ARM_EABI__
+  x = 8;
+#else
+  x = __alignof__ (T);
   if (x < sizeof (size_t))
     x = sizeof (size_t);
+#endif
   if ((char *) a - x != (char *) p)
     exit (i);
 
@@ -48,6 +53,12 @@ void check_cookie (int i)
   size_t *sp = ((size_t *) a) - 1;
   if (*sp != 11)
     exit (i);
+
+#ifdef __ARM_EABI__
+  size_t *sp = ((size_t *) a) - 2;
+  if (*sp != sizeof (T))
+    exit (i);
+#endif
 }
 
 template <typename T>
@@ -55,11 +66,16 @@ void check_placement_cookie (int i)
 {
   p = malloc (sizeof (T) * 11 + 100);
   void* a = new (p) T[11];
+  size_t x;
   
   // Compute the cookie location manually.
-  size_t x = __alignof__ (T);
+#ifdef __ARM_EABI__
+  x = 8;
+#else
+  x = __alignof__ (T);
   if (x < sizeof (size_t))
     x = sizeof (size_t);
+#endif
   if ((char *) a - x != (char *) p)
     exit (i);
 
@@ -67,6 +83,12 @@ void check_placement_cookie (int i)
   size_t *sp = ((size_t *) a) - 1;
   if (*sp != 11)
     exit (i);
+
+#ifdef __ARM_EABI__
+  size_t *sp = ((size_t *) a) - 2;
+  if (*sp != sizeof (T))
+    exit (i);
+#endif
 }
 
 struct X {};
index ed5a7de77e7379c99a36fa8f01bc80a8f6a52d5a..a6fdc44e597fcf1eea6f71d919a8455a7819f32d 100644 (file)
@@ -14,6 +14,13 @@ static int ctor_count = 0;
 static int dtor_count = 0;
 static bool dtor_repeat = false;
 
+// Allocate enough padding to hold an array cookie.
+#ifdef __ARM_EABI__
+#define padding 8
+#else
+#define padding (sizeof (std::size_t))
+#endif
+
 // our pseudo ctors and dtors
 static void ctor (void *)
 {
@@ -71,8 +78,8 @@ void test0 ()
       
       try
         {
-          void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
-          abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor);
+          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
+          abi::__cxa_vec_delete (ary, 1, padding, dtor);
           if (ctor_count || dtor_count || blocks)
             longjmp (jump, 1);
         }
@@ -105,7 +112,7 @@ void test1 ()
       ctor_count = 4;
       try
         {
-          void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
+          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
           longjmp (jump, 1);
         }
       catch (...)
@@ -138,8 +145,8 @@ void test2 ()
       dtor_count = 3;
       try
         {
-          void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
-          abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor);
+          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
+          abi::__cxa_vec_delete (ary, 1, padding, dtor);
           longjmp (jump, 1);
         }
       catch (...)
@@ -174,8 +181,8 @@ void test3 ()
       dtor_repeat = true;
       try
         {
-          void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
-          abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor);
+          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
+          abi::__cxa_vec_delete (ary, 1, padding, dtor);
           longjmp (jump, 1);
         }
       catch (...)
@@ -212,7 +219,7 @@ void test4 ()
       dtor_count = 2;
       try
         {
-          void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
+          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
           longjmp (jump, 1);
         }
       catch (...)
index 1de45fbd4f6d3cff834c58a3a787e612abb5b7be..e433113f1f2b9641251c8cd38e404d8c46afd020 100644 (file)
@@ -1,3 +1,8 @@
+2004-06-29  Paul Brook  <paul@codesourcery.com>
+
+       * libsupc++/vec.cc (__cxa_vec_new2, __cxa_vec_new3): Store the
+       element size in the cookie.
+
 2004-06-28  Paolo Carlini  <pcarlini@suse.de>
 
        * include/bits/cpp_type_traits.h: Move the additions to
index 86d41d9ea98b4a49dc868b6898d1cfc86b7a9043..eb7851b0588b71bc33fdef944f5d8ac370a32cd1 100644 (file)
@@ -96,6 +96,10 @@ namespace __cxxabiv1
       {
        base += padding_size;
        reinterpret_cast <std::size_t *> (base)[-1] = element_count;
+#ifdef __ARM_EABI__
+       // ARM EABI array cookies also contain the element size.
+       reinterpret_cast <std::size_t *> (base)[-2] = element_size;
+#endif
       }
     try
       {
@@ -131,6 +135,10 @@ namespace __cxxabiv1
       {
        base += padding_size;
        reinterpret_cast<std::size_t *>(base)[-1] = element_count;
+#ifdef __ARM_EABI__
+       // ARM EABI array cookies also contain the element size.
+       reinterpret_cast <std::size_t *> (base)[-2] = element_size;
+#endif
       }
     try
       {