aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2004-06-29 14:50:35 +0000
committerPaul Brook <pbrook@gcc.gnu.org>2004-06-29 14:50:35 +0000
commit46e995e0e40e16ca159d6f5b116829700bbc269f (patch)
treef6a9a6cf28955476ec2789692fe97c33db01c297
parent50a2de961ffa6022ac3084c94f76d1462be04845 (diff)
downloadgcc-46e995e0e40e16ca159d6f5b116829700bbc269f.zip
gcc-46e995e0e40e16ca159d6f5b116829700bbc269f.tar.gz
gcc-46e995e0e40e16ca159d6f5b116829700bbc269f.tar.bz2
target-def.h (TARGET_CXX_GET_COOKIE_SIZE, [...]): Define.
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
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/arm/arm.c33
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/cp/init.c48
-rw-r--r--gcc/doc/tm.texi13
-rw-r--r--gcc/target-def.h12
-rw-r--r--gcc/target.h5
-rw-r--r--gcc/targhooks.c25
-rw-r--r--gcc/targhooks.h1
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.abi/arraynew.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C23
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/libsupc++/vec.cc8
15 files changed, 188 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 01c0285..3ad291e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a7262f5..7cd1573 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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);
/* 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;
/* 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;
+}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 532180d..203c36a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 997b8aa..34fb529 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -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
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index c96e14d..4e02b9d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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,
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index d01993f..944477d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 72fda5b..0761a06 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -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. */
diff --git a/gcc/target.h b/gcc/target.h
index 2c4b530..da37fcd 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -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. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 5d2a75f..a2745c4 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -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;
+}
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 427334f..fba17f8 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3fe71ec..1bc2671 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C b/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C
index 3b11796..273d137 100644
--- a/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C
+++ b/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C
@@ -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 {};
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C b/gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C
index ed5a7de..a6fdc44 100644
--- a/gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C
+++ b/gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C
@@ -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 (...)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 1de45fb..e433113 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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
diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc
index 86d41d9..eb7851b 100644
--- a/libstdc++-v3/libsupc++/vec.cc
+++ b/libstdc++-v3/libsupc++/vec.cc
@@ -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
{