init.c (init_init_processing): Go back to aligning like double_type_node for old ABI.
* init.c (init_init_processing): Go back to aligning like double_type_node for old ABI. (get_cookie_size): Make cookie larger if we get a type that needs more alignment. (build_vec_delete): Call it. * typeck.c (qualify_type_recursive): New fn. (composite_pointer_type): Use it. (build_binary_op): Use composite_pointer_type. * typeck.c (check_return_expr): Don't complain about returning NULL from operator new if -fcheck-new. * cp-tree.h: Declare flag_check_new here. * init.c: Not here. From-SVN: r34824
This commit is contained in:
parent
792a328b3b
commit
708cae9771
20695
gcc/cp/ChangeLog
20695
gcc/cp/ChangeLog
File diff suppressed because it is too large
Load Diff
@ -1223,6 +1223,11 @@ extern int flag_enforce_eh_specs;
|
||||
|
||||
extern int flag_access_control;
|
||||
|
||||
/* Nonzero if we want to check the return value of new and avoid calling
|
||||
constructors if it is a null pointer. */
|
||||
|
||||
extern int flag_check_new;
|
||||
|
||||
/* If this variable is defined to a non-NULL value, it will be called
|
||||
after the file has been completely parsed. The argument will be
|
||||
the GLOBAL_NAMESPACE. */
|
||||
|
@ -58,7 +58,7 @@ static tree build_vtbl_address PARAMS ((tree));
|
||||
/* Set up local variable for this file. MUST BE CALLED AFTER
|
||||
INIT_DECL_PROCESSING. */
|
||||
|
||||
static tree BI_header_type, BI_header_size;
|
||||
static tree BI_header_type;
|
||||
|
||||
void init_init_processing ()
|
||||
{
|
||||
@ -71,16 +71,10 @@ void init_init_processing ()
|
||||
BI_header_type = make_aggr_type (RECORD_TYPE);
|
||||
fields[0] = build_decl (FIELD_DECL, nelts_identifier, sizetype);
|
||||
|
||||
/* Use the biggest alignment supported by the target to prevent operator
|
||||
new from returning misaligned pointers. */
|
||||
TYPE_ALIGN (BI_header_type) = BIGGEST_ALIGNMENT;
|
||||
TYPE_USER_ALIGN (BI_header_type) = 0;
|
||||
finish_builtin_type (BI_header_type, "__new_cookie", fields,
|
||||
0, BI_header_type);
|
||||
BI_header_size = size_in_bytes (BI_header_type);
|
||||
0, double_type_node);
|
||||
|
||||
ggc_add_tree_root (&BI_header_type, 1);
|
||||
ggc_add_tree_root (&BI_header_size, 1);
|
||||
}
|
||||
|
||||
/* We are about to generate some complex initialization code.
|
||||
@ -1975,8 +1969,6 @@ build_builtin_delete_call (addr)
|
||||
|
||||
PLACEMENT is the `placement' list for user-defined operator new (). */
|
||||
|
||||
extern int flag_check_new;
|
||||
|
||||
tree
|
||||
build_new (placement, decl, init, use_global_new)
|
||||
tree placement;
|
||||
@ -2205,7 +2197,12 @@ get_cookie_size (type)
|
||||
cookie_size = type_align;
|
||||
}
|
||||
else
|
||||
cookie_size = BI_header_size;
|
||||
{
|
||||
if (TYPE_ALIGN (type) > TYPE_ALIGN (BI_header_type))
|
||||
return size_int (TYPE_ALIGN_UNIT (type));
|
||||
else
|
||||
return size_in_bytes (BI_header_type);
|
||||
}
|
||||
|
||||
return cookie_size;
|
||||
}
|
||||
@ -2385,8 +2382,8 @@ build_new_1 (exp)
|
||||
else
|
||||
alloc_expr = NULL_TREE;
|
||||
|
||||
/* if rval is NULL_TREE I don't have to allocate it, but are we totally
|
||||
sure we have some extra bytes in that case for the BI_header_size
|
||||
/* if rval is NULL_TREE I don't have to allocate it, but are we
|
||||
totally sure we have some extra bytes in that case for the
|
||||
cookies? And how does that interact with the code below? (mrs) */
|
||||
/* Finish up some magic for new'ed arrays */
|
||||
if (use_cookie && rval != NULL_TREE)
|
||||
@ -2633,7 +2630,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
|
||||
goto no_destructor;
|
||||
}
|
||||
|
||||
/* The below is short by BI_header_size */
|
||||
/* The below is short by the cookie size. */
|
||||
virtual_size = size_binop (MULT_EXPR, size_exp,
|
||||
convert (sizetype, maxindex));
|
||||
|
||||
@ -2676,7 +2673,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
|
||||
{
|
||||
tree base_tbd;
|
||||
|
||||
/* The below is short by BI_header_size */
|
||||
/* The below is short by the cookie size. */
|
||||
virtual_size = size_binop (MULT_EXPR, size_exp,
|
||||
convert (sizetype, maxindex));
|
||||
|
||||
@ -3378,6 +3375,7 @@ build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete)
|
||||
/* Step back one from start of vector, and read dimension. */
|
||||
tree cookie_addr;
|
||||
|
||||
type = strip_array_types (TREE_TYPE (type));
|
||||
if (flag_new_abi)
|
||||
{
|
||||
cookie_addr = build (MINUS_EXPR,
|
||||
@ -3391,13 +3389,11 @@ build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete)
|
||||
tree cookie;
|
||||
|
||||
cookie_addr = build (MINUS_EXPR, build_pointer_type (BI_header_type),
|
||||
base, BI_header_size);
|
||||
base, get_cookie_size (type));
|
||||
cookie = build_indirect_ref (cookie_addr, NULL_PTR);
|
||||
maxindex = build_component_ref (cookie, nelts_identifier,
|
||||
NULL_TREE, 0);
|
||||
}
|
||||
|
||||
type = strip_array_types (TREE_TYPE (type));
|
||||
}
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
|
145
gcc/cp/typeck.c
145
gcc/cp/typeck.c
@ -61,6 +61,7 @@ static tree lookup_anon_field PARAMS ((tree, tree));
|
||||
static tree pointer_diff PARAMS ((tree, tree, tree));
|
||||
static tree build_component_addr PARAMS ((tree, tree));
|
||||
static tree qualify_type PARAMS ((tree, tree));
|
||||
static tree qualify_type_recursive PARAMS ((tree, tree));
|
||||
static tree get_delta_difference PARAMS ((tree, tree, int));
|
||||
static int comp_cv_target_types PARAMS ((tree, tree, int));
|
||||
static void casts_away_constness_r PARAMS ((tree *, tree *));
|
||||
@ -209,6 +210,44 @@ qualify_type (type, like)
|
||||
return cp_build_qualified_type (type, (CP_TYPE_QUALS (type)
|
||||
| CP_TYPE_QUALS (like)));
|
||||
}
|
||||
|
||||
/* Return a pointer or pointer to member type similar to T1, with a
|
||||
cv-qualification signature that is the union of the cv-qualification
|
||||
signatures of T1 and T2: [expr.rel], [expr.eq]. */
|
||||
|
||||
static tree
|
||||
qualify_type_recursive (t1, t2)
|
||||
tree t1, t2;
|
||||
{
|
||||
if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
|
||||
|| (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2)))
|
||||
{
|
||||
tree tt1 = TREE_TYPE (t1);
|
||||
tree tt2 = TREE_TYPE (t2);
|
||||
tree b1;
|
||||
int type_quals;
|
||||
tree target;
|
||||
tree attributes = merge_machine_type_attributes (t1, t2);
|
||||
|
||||
if (TREE_CODE (tt1) == OFFSET_TYPE)
|
||||
{
|
||||
b1 = TYPE_OFFSET_BASETYPE (tt1);
|
||||
tt1 = TREE_TYPE (tt1);
|
||||
tt2 = TREE_TYPE (tt2);
|
||||
}
|
||||
else
|
||||
b1 = NULL_TREE;
|
||||
|
||||
type_quals = (CP_TYPE_QUALS (tt1) | CP_TYPE_QUALS (tt2));
|
||||
target = qualify_type_recursive (tt1, tt2);
|
||||
target = cp_build_qualified_type (target, type_quals);
|
||||
if (b1)
|
||||
target = build_offset_type (b1, target);
|
||||
t1 = build_pointer_type (target);
|
||||
t1 = build_type_attribute_variant (t1, attributes);
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
/* Return the common type of two parameter lists.
|
||||
We assume that comptypes has already been done and returned 1;
|
||||
@ -441,49 +480,35 @@ composite_pointer_type (t1, t2, arg1, arg2, location)
|
||||
if (TYPE_PTRMEMFUNC_P (t2))
|
||||
t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
|
||||
|
||||
if (comp_target_types (t1, t2, 1))
|
||||
result_type = common_type (t1, t2);
|
||||
else if (VOID_TYPE_P (TREE_TYPE (t1)))
|
||||
if (VOID_TYPE_P (TREE_TYPE (t1)))
|
||||
{
|
||||
if (pedantic && TREE_CODE (t2) == FUNCTION_TYPE)
|
||||
if (pedantic && TYPE_PTRFN_P (t2))
|
||||
pedwarn ("ISO C++ forbids %s between pointer of type `void *' and pointer-to-function", location);
|
||||
result_type = qualify_type (t1, t2);
|
||||
}
|
||||
else if (VOID_TYPE_P (TREE_TYPE (t2)))
|
||||
{
|
||||
if (pedantic && TREE_CODE (t1) == FUNCTION_TYPE)
|
||||
if (pedantic && TYPE_PTRFN_P (t1))
|
||||
pedwarn ("ISO C++ forbids %s between pointer of type `void *' and pointer-to-function", location);
|
||||
result_type = qualify_type (t2, t1);
|
||||
}
|
||||
/* C++ */
|
||||
else if (same_or_base_type_p (t2, t1))
|
||||
result_type = t2;
|
||||
else if (IS_AGGR_TYPE (TREE_TYPE (t1))
|
||||
&& IS_AGGR_TYPE (TREE_TYPE (t2))
|
||||
&& (result_type = common_base_type (TREE_TYPE (t1),
|
||||
TREE_TYPE (t2))))
|
||||
{
|
||||
if (result_type == error_mark_node)
|
||||
{
|
||||
cp_error ("common base type of types `%T' and `%T' is ambiguous",
|
||||
TREE_TYPE (t1), TREE_TYPE (t2));
|
||||
result_type = ptr_type_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pedantic
|
||||
&& result_type != TREE_TYPE (t1)
|
||||
&& result_type != TREE_TYPE (t2))
|
||||
cp_pedwarn ("types `%T' and `%T' converted to `%T *' in %s",
|
||||
t1, t2, result_type, location);
|
||||
|
||||
result_type = build_pointer_type (result_type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cp_pedwarn ("pointer type mismatch in %s", location);
|
||||
result_type = ptr_type_node;
|
||||
tree full1 = qualify_type_recursive (t1, t2);
|
||||
tree full2 = qualify_type_recursive (t2, t1);
|
||||
|
||||
int val = comp_target_types (full1, full2, 1);
|
||||
|
||||
if (val > 0)
|
||||
result_type = full1;
|
||||
else if (val < 0)
|
||||
result_type = full2;
|
||||
else
|
||||
{
|
||||
cp_pedwarn ("%s between distinct pointer types `%T' and `%T' lacks a cast",
|
||||
location, t1, t2);
|
||||
result_type = ptr_type_node;
|
||||
}
|
||||
}
|
||||
|
||||
return result_type;
|
||||
@ -3578,33 +3603,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
||||
|| code1 == COMPLEX_TYPE))
|
||||
short_compare = 1;
|
||||
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
|
||||
{
|
||||
register tree tt0 = TYPE_MAIN_VARIANT (TREE_TYPE (type0));
|
||||
register tree tt1 = TYPE_MAIN_VARIANT (TREE_TYPE (type1));
|
||||
|
||||
if (comp_target_types (type0, type1, 1))
|
||||
result_type = common_type (type0, type1);
|
||||
else if (VOID_TYPE_P (tt0))
|
||||
{
|
||||
if (pedantic && TREE_CODE (tt1) == FUNCTION_TYPE
|
||||
&& tree_int_cst_lt (TYPE_SIZE (type0), TYPE_SIZE (type1)))
|
||||
pedwarn ("ISO C++ forbids comparison of `void *' with function pointer");
|
||||
else if (TREE_CODE (tt1) == OFFSET_TYPE)
|
||||
pedwarn ("ISO C++ forbids conversion of a pointer to member to `void *'");
|
||||
}
|
||||
else if (VOID_TYPE_P (tt1))
|
||||
{
|
||||
if (pedantic && TREE_CODE (tt0) == FUNCTION_TYPE
|
||||
&& tree_int_cst_lt (TYPE_SIZE (type1), TYPE_SIZE (type0)))
|
||||
pedwarn ("ISO C++ forbids comparison of `void *' with function pointer");
|
||||
}
|
||||
else
|
||||
cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
|
||||
type0, type1);
|
||||
|
||||
if (result_type == NULL_TREE)
|
||||
result_type = ptr_type_node;
|
||||
}
|
||||
result_type = composite_pointer_type (type0, type1, op0, op1,
|
||||
"comparison");
|
||||
else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1))
|
||||
result_type = type0;
|
||||
else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0))
|
||||
@ -3723,16 +3723,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
||||
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
|
||||
shorten = 1;
|
||||
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
|
||||
{
|
||||
if (comp_target_types (type0, type1, 1))
|
||||
result_type = common_type (type0, type1);
|
||||
else
|
||||
{
|
||||
cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
|
||||
type0, type1);
|
||||
result_type = ptr_type_node;
|
||||
}
|
||||
}
|
||||
result_type = composite_pointer_type (type0, type1, op0, op1,
|
||||
"comparison");
|
||||
break;
|
||||
|
||||
case LE_EXPR:
|
||||
@ -3744,16 +3736,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
||||
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
|
||||
short_compare = 1;
|
||||
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
|
||||
{
|
||||
if (comp_target_types (type0, type1, 1))
|
||||
result_type = common_type (type0, type1);
|
||||
else
|
||||
{
|
||||
cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
|
||||
type0, type1);
|
||||
result_type = ptr_type_node;
|
||||
}
|
||||
}
|
||||
result_type = composite_pointer_type (type0, type1, op0, op1,
|
||||
"comparison");
|
||||
else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
|
||||
&& integer_zerop (op1))
|
||||
result_type = type0;
|
||||
@ -6844,8 +6828,9 @@ check_return_expr (retval)
|
||||
if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR
|
||||
|| DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR)
|
||||
&& !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
|
||||
&& ! flag_check_new
|
||||
&& null_ptr_cst_p (retval))
|
||||
cp_warning ("`operator new' should throw an exception, not return NULL");
|
||||
cp_warning ("`operator new' must not return NULL unless it is declared `throw()' (or -fcheck-new is in effect)");
|
||||
|
||||
/* Effective C++ rule 15. See also start_function. */
|
||||
if (warn_ecpp
|
||||
|
@ -11,7 +11,7 @@ struct A {
|
||||
void * operator new (__SIZE_TYPE__ s)
|
||||
{
|
||||
if (ena)
|
||||
return 0; // WARNING - returning NULL
|
||||
return 0;
|
||||
return malloc (s);
|
||||
}
|
||||
};
|
||||
|
@ -6,5 +6,5 @@ void *vp;
|
||||
|
||||
void example ()
|
||||
{
|
||||
vp != fp; // gets bogus error - nuttin' wrong wit dat
|
||||
vp != fp; // ERROR - no conversion from pfn to void*
|
||||
}
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
|
||||
// simplified from bug report by Paul Burchard <burchard@pobox.com>
|
||||
// crash test - XFAIL *-*-*
|
||||
|
||||
template<class> struct A {};
|
||||
template<template<class> class T> struct B {
|
||||
B() {
|
||||
T<B>(); // gets bogus error - conversion from int to non-scalar - XFAIL *-*-*
|
||||
T<B>(); // gets bogus error - conversion from int to non-scalar
|
||||
}
|
||||
};
|
||||
B<A> foo;
|
||||
|
@ -11,18 +11,18 @@ int main ()
|
||||
// The composite type is `A const *'
|
||||
A* ap = &b;
|
||||
const B* bp = &b;
|
||||
if (ap != bp) // gets bogus error - distinct types XFAIL *-*-*
|
||||
if (ap != bp) // gets bogus error - distinct types
|
||||
return 1;
|
||||
|
||||
// The composite type is `B const *const *'
|
||||
B *const * p = 0;
|
||||
B const * * q = 0;
|
||||
if (p != q) // gets bogus error - distinct types XFAIL *-*-*
|
||||
if (p != q) // gets bogus error - distinct types
|
||||
return 1;
|
||||
|
||||
// The common type is `int const B::*'
|
||||
const int A::*apm = &A::i;
|
||||
int B::*bpm = &A::i;
|
||||
if (apm != bpm) // gets bogus error - distinct types XFAIL *-*-*
|
||||
if (apm != bpm) // gets bogus error - distinct types
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user