+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
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. */
#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. */
{
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;
+}
+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
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
#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);
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);
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. */
/* 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. */
/* 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;
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,
/* 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
{
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,
@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
#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. */
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. */
{
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;
+}
extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
extern tree default_cxx_guard_type (void);
+extern tree default_cxx_get_cookie_size (tree);
+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
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);
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>
{
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);
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 {};
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 *)
{
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);
}
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 (...)
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 (...)
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 (...)
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 (...)
+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
{
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
{
{
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
{