c-tree.h: Add argument to c_objc_common_truthvalue_conversion, parser_build_binary_op.

* c-tree.h: Add argument to c_objc_common_truthvalue_conversion,
        parser_build_binary_op.
        * c-decl.c (build_enumerator): Pass location to build_binary_op.
        * c-typeck.c (build_array_ref): Same.
        (parser_build_unary_op): New location argument.
        (pointer_diff): Pass location to build_binary_op,
        c_objc_common_truthvalue_conversion.
        (build_modify_expr): Same.
        (build_unary_op): New location argument.
        (build_binary_op): New location argument.
        (c_objc_common_truthvalue_conversion): Pass location to
        c_*common_truthvalue_conversion.
        * c-convert.c (convert): Same.
        * c-common.c (binary_op_error): New location argument.
        (pointer_int_sum): Pass location to build_binary_op.
        (c_common_truthvalue_conversion): New location argument.
        (warn_for_sign_compare): Same.
        * c-common.h: Add location argument to c_common_truthvalue_conversion,
        binary_op_error, build_binary_op, warn_for_sign_compare.
        * c-parser.c (c_parser_condition): Pass location to
        c_*common_truthvalue_conversion.
        (c_parser_conditional_expression): Save condition's location and pass
        it on down.
        (c_parser_binary_expression): Same, but for the binary operator's
        location.
        (c_parser_omp_for_loop): Pass location to
        c_objc_common_truthvalue_conversion.
objc/
        * objc-act.c (next_sjlj_build_enter_and_setjmp): Call
        c_common_truthvalue_conversion with location.
        (next_sjlj_build_catch_list): Same.
        (next_sjlj_build_try_catch_finally): Same.
testsuite/
        * gcc.dg/Walways-true-1.c: Test column numbers.
        * gcc.dg/c90-const-expr-5.c: Same.
        * gcc.dg/compare4.c: Same.
        * gcc.dg/Werror-1.c: Same.
cp/
        * typeck.c (build_array_ref): Pass location to cp_build_binary_op.
        (get_member_function_from_ptrfunc): Same.
        (build_x_binary_op): Same.
        (build_binary_op): Same.
        (cp_build_binary_op): New location argument.
        (pointer_diff): Pass location to cp_build_binary_op.
        (cp_truthvalue_conversion): Pass location to build_binary_op.
        (convert_ptrmem): Pass location to cp_build_binary_op.
        (cp_build_modify_expr): Same.
        (build_ptrmemfunc): Same.
        * init.c (expand_cleanup_for_base): Pass location to
        c_common_truthvalue_conversion.
        (build_new_1): Pass location to cp_build_binary_op.
        (build_vec_delete_1): Pass location to *build_binary_op,
        c_common_truthvalue_conversion.
        (build_vec_init): Same.
        (build_delete): Same.
        * decl.c (compute_array_index_type): Same.
        * call.c (build_new_op): Same.
        * rtti.c (build_dynamic_cast_1): Same.
        * cp-tree.h: Add argument to cp_build_binary_op.
        * semantics.c (handle_omp_for_class_iterator): Pass location to
        *build_binary_op, c_common_truthvalue_conversion.
        * decl2.c (get_guard_cond): Same.

From-SVN: r140598
This commit is contained in:
Aldy Hernandez 2008-09-23 14:55:14 +00:00
parent f0ac18b799
commit ba47d38d4c
25 changed files with 395 additions and 188 deletions

View File

@ -1,3 +1,33 @@
2008-09-23 Aldy Hernandez <aldyh@redhat.com>
* c-tree.h: Add argument to c_objc_common_truthvalue_conversion,
parser_build_binary_op.
* c-decl.c (build_enumerator): Pass location to build_binary_op.
* c-typeck.c (build_array_ref): Same.
(parser_build_unary_op): New location argument.
(pointer_diff): Pass location to build_binary_op,
c_objc_common_truthvalue_conversion.
(build_modify_expr): Same.
(build_unary_op): New location argument.
(build_binary_op): New location argument.
(c_objc_common_truthvalue_conversion): Pass location to
c_*common_truthvalue_conversion.
* c-convert.c (convert): Same.
* c-common.c (binary_op_error): New location argument.
(pointer_int_sum): Pass location to build_binary_op.
(c_common_truthvalue_conversion): New location argument.
(warn_for_sign_compare): Same.
* c-common.h: Add location argument to c_common_truthvalue_conversion,
binary_op_error, build_binary_op, warn_for_sign_compare.
* c-parser.c (c_parser_condition): Pass location to
c_*common_truthvalue_conversion.
(c_parser_conditional_expression): Save condition's location and pass
it on down.
(c_parser_binary_expression): Same, but for the binary operator's
location.
(c_parser_omp_for_loop): Pass location to
c_objc_common_truthvalue_conversion.
2008-09-23 Martin Jambor <mjambor@suse.cz>
* cgraph.c (cgraph_free_edge): Use sizeof(*e).

View File

@ -2849,10 +2849,12 @@ min_precision (tree value, int unsignedp)
}
/* Print an error message for invalid operands to arith operation
CODE with TYPE0 for operand 0, and TYPE1 for operand 1. */
CODE with TYPE0 for operand 0, and TYPE1 for operand 1.
LOCATION is the location of the message. */
void
binary_op_error (enum tree_code code, tree type0, tree type1)
binary_op_error (location_t location, enum tree_code code,
tree type0, tree type1)
{
const char *opname;
@ -2903,8 +2905,9 @@ binary_op_error (enum tree_code code, tree type0, tree type1)
default:
gcc_unreachable ();
}
error ("invalid operands to binary %s (have %qT and %qT)", opname,
type0, type1);
error_at (location,
"invalid operands to binary %s (have %qT and %qT)", opname,
type0, type1);
}
/* Subroutine of build_binary_op, used for comparison operations.
@ -3320,7 +3323,8 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
/* Convert both subexpression types to the type of intop,
because weird cases involving pointer arithmetic
can result in a sum or difference with different type args. */
ptrop = build_binary_op (subcode, ptrop,
ptrop = build_binary_op (EXPR_LOCATION (TREE_OPERAND (intop, 1)),
subcode, ptrop,
convert (int_type, TREE_OPERAND (intop, 1)), 1);
intop = convert (int_type, TREE_OPERAND (intop, 0));
}
@ -3336,7 +3340,8 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
Do this multiplication as signed, then convert to the appropriate
type for the pointer operation. */
intop = convert (sizetype,
build_binary_op (MULT_EXPR, intop,
build_binary_op (EXPR_LOCATION (intop),
MULT_EXPR, intop,
convert (TREE_TYPE (intop), size_exp), 1));
/* Create the sum or difference. */
@ -3367,6 +3372,8 @@ decl_with_nonnull_addr_p (const_tree expr)
have been validated to be of suitable type; otherwise, a bad
diagnostic may result.
The EXPR is located at LOCATION.
This preparation consists of taking the ordinary
representation of an expression expr and producing a valid tree
boolean expression describing whether expr is nonzero. We could
@ -3376,7 +3383,7 @@ decl_with_nonnull_addr_p (const_tree expr)
The resulting type should always be `truthvalue_type_node'. */
tree
c_common_truthvalue_conversion (tree expr)
c_common_truthvalue_conversion (location_t location, tree expr)
{
switch (TREE_CODE (expr))
{
@ -3397,14 +3404,17 @@ c_common_truthvalue_conversion (tree expr)
if (TREE_TYPE (expr) == truthvalue_type_node)
return expr;
return build2 (TREE_CODE (expr), truthvalue_type_node,
c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)));
c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 0)),
c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 1)));
case TRUTH_NOT_EXPR:
if (TREE_TYPE (expr) == truthvalue_type_node)
return expr;
return build1 (TREE_CODE (expr), truthvalue_type_node,
c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)));
c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 0)));
case ERROR_MARK:
return expr;
@ -3434,9 +3444,10 @@ c_common_truthvalue_conversion (tree expr)
if (decl_with_nonnull_addr_p (inner))
{
/* Common Ada/Pascal programmer's mistake. */
warning (OPT_Waddress,
"the address of %qD will always evaluate as %<true%>",
inner);
warning_at (location,
OPT_Waddress,
"the address of %qD will always evaluate as %<true%>",
inner);
return truthvalue_true_node;
}
@ -3456,17 +3467,20 @@ c_common_truthvalue_conversion (tree expr)
}
case COMPLEX_EXPR:
return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
return build_binary_op (EXPR_LOCATION (expr),
(TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)),
c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 0)),
c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 1)),
0);
case NEGATE_EXPR:
case ABS_EXPR:
case FLOAT_EXPR:
/* These don't change whether an object is nonzero or zero. */
return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
return c_common_truthvalue_conversion (location, TREE_OPERAND (expr, 0));
case LROTATE_EXPR:
case RROTATE_EXPR:
@ -3475,16 +3489,20 @@ c_common_truthvalue_conversion (tree expr)
if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
return build2 (COMPOUND_EXPR, truthvalue_type_node,
TREE_OPERAND (expr, 1),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)));
c_common_truthvalue_conversion
(location, TREE_OPERAND (expr, 0)));
else
return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
return c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 0));
case COND_EXPR:
/* Distribute the conversion into the arms of a COND_EXPR. */
return fold_build3 (COND_EXPR, truthvalue_type_node,
TREE_OPERAND (expr, 0),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 2)));
c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 1)),
c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 2)));
CASE_CONVERT:
/* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
@ -3495,7 +3513,8 @@ c_common_truthvalue_conversion (tree expr)
/* If this is widening the argument, we can ignore it. */
if (TYPE_PRECISION (TREE_TYPE (expr))
>= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
return c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 0));
break;
case MODIFY_EXPR:
@ -3516,10 +3535,13 @@ c_common_truthvalue_conversion (tree expr)
{
tree t = save_expr (expr);
return (build_binary_op
((TREE_SIDE_EFFECTS (expr)
(EXPR_LOCATION (expr),
(TREE_SIDE_EFFECTS (expr)
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
c_common_truthvalue_conversion (build_unary_op (REALPART_EXPR, t, 0)),
c_common_truthvalue_conversion (build_unary_op (IMAGPART_EXPR, t, 0)),
c_common_truthvalue_conversion (location,
build_unary_op (REALPART_EXPR, t, 0)),
c_common_truthvalue_conversion (location,
build_unary_op (IMAGPART_EXPR, t, 0)),
0));
}
@ -3528,10 +3550,12 @@ c_common_truthvalue_conversion (tree expr)
tree fixed_zero_node = build_fixed (TREE_TYPE (expr),
FCONST0 (TYPE_MODE
(TREE_TYPE (expr))));
return build_binary_op (NE_EXPR, expr, fixed_zero_node, 1);
return build_binary_op (EXPR_LOCATION (expr),
NE_EXPR, expr, fixed_zero_node, 1);
}
return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
return build_binary_op (EXPR_LOCATION (expr),
NE_EXPR, expr, integer_zero_node, 1);
}
static void def_builtin_1 (enum built_in_function fncode,
@ -8198,13 +8222,16 @@ warn_for_div_by_zero (tree divisor)
between signed and unsigned quantities that may fail. Do the
checking based on the original operand trees ORIG_OP0 and ORIG_OP1,
so that casts will be considered, but default promotions won't
be.
be.
LOCATION is the location of the comparison operator.
The arguments of this function map directly to local variables
of build_binary_op. */
void
warn_for_sign_compare (tree orig_op0, tree orig_op1,
warn_for_sign_compare (location_t location,
tree orig_op0, tree orig_op1,
tree op0, tree op1,
tree result_type, enum tree_code resultcode)
{
@ -8219,8 +8246,9 @@ warn_for_sign_compare (tree orig_op0, tree orig_op1,
&& TYPE_MAIN_VARIANT (TREE_TYPE (orig_op0))
!= TYPE_MAIN_VARIANT (TREE_TYPE (orig_op1)))
{
warning (OPT_Wsign_compare, "comparison between types %qT and %qT",
TREE_TYPE (orig_op0), TREE_TYPE (orig_op1));
warning_at (location,
OPT_Wsign_compare, "comparison between types %qT and %qT",
TREE_TYPE (orig_op0), TREE_TYPE (orig_op1));
}
/* Do not warn if the comparison is being done in a signed type,
@ -8266,8 +8294,9 @@ warn_for_sign_compare (tree orig_op0, tree orig_op1,
c_common_signed_type (result_type)))
/* OK */;
else
warning (OPT_Wsign_compare,
"comparison between signed and unsigned integer expressions");
warning_at (location,
OPT_Wsign_compare,
"comparison between signed and unsigned integer expressions");
}
/* Warn if two unsigned values are being compared in a size larger
@ -8320,8 +8349,8 @@ warn_for_sign_compare (tree orig_op0, tree orig_op1,
warning (OPT_Wsign_compare,
"promoted ~unsigned is always non-zero");
else
warning (OPT_Wsign_compare,
"comparison of promoted ~unsigned with constant");
warning_at (location, OPT_Wsign_compare,
"comparison of promoted ~unsigned with constant");
}
}
}
@ -8330,7 +8359,7 @@ warn_for_sign_compare (tree orig_op0, tree orig_op1,
< TYPE_PRECISION (result_type))
&& (TYPE_PRECISION (TREE_TYPE (op1))
< TYPE_PRECISION (result_type)))
warning (OPT_Wsign_compare,
warning_at (location, OPT_Wsign_compare,
"comparison of promoted ~unsigned with unsigned");
}
}

View File

@ -714,13 +714,13 @@ extern tree c_common_signed_type (tree);
extern tree c_common_signed_or_unsigned_type (int, tree);
extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
extern bool decl_with_nonnull_addr_p (const_tree);
extern tree c_common_truthvalue_conversion (tree);
extern tree c_common_truthvalue_conversion (location_t, tree);
extern void c_apply_type_quals_to_decl (int, tree);
extern tree c_sizeof_or_alignof_type (tree, bool, int);
extern tree c_alignof_expr (tree);
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error (enum tree_code, tree, tree);
extern void binary_op_error (location_t, enum tree_code, tree, tree);
extern tree fix_string_type (tree);
struct varray_head_tag;
extern void constant_expression_warning (tree);
@ -817,7 +817,7 @@ extern tree build_case_label (tree, tree, tree);
a variant of the C language. They are used in c-common.c. */
extern tree build_unary_op (enum tree_code, tree, int);
extern tree build_binary_op (enum tree_code, tree, tree, int);
extern tree build_binary_op (location_t, enum tree_code, tree, tree, int);
extern tree perform_integral_promotions (tree);
/* These functions must be defined by each front-end which implements
@ -917,7 +917,8 @@ extern void warn_about_parentheses (enum tree_code, enum tree_code,
enum tree_code);
extern void warn_for_unused_label (tree label);
extern void warn_for_div_by_zero (tree divisor);
extern void warn_for_sign_compare (tree orig_op0, tree orig_op1,
extern void warn_for_sign_compare (location_t,
tree orig_op0, tree orig_op1,
tree op0, tree op1,
tree result_type,
enum tree_code resultcode);

View File

@ -100,7 +100,8 @@ convert (tree type, tree expr)
if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
return fold (convert_to_integer (type, e));
if (code == BOOLEAN_TYPE)
return fold_convert (type, c_objc_common_truthvalue_conversion (expr));
return fold_convert
(type, c_objc_common_truthvalue_conversion (input_location, expr));
if (code == POINTER_TYPE || code == REFERENCE_TYPE)
return fold (convert_to_pointer (type, e));
if (code == REAL_TYPE)

View File

@ -6027,8 +6027,10 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
"ISO C restricts enumerator values to range of %<int%>");
/* Set basis for default for next value. */
the_enum->enum_next_value = build_binary_op (PLUS_EXPR, value,
integer_one_node, 0);
the_enum->enum_next_value
= build_binary_op
(EXPR_HAS_LOCATION (value) ? EXPR_LOCATION (value) : input_location,
PLUS_EXPR, value, integer_one_node, 0);
the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value);
/* Now create a declaration for the enum value name. */

View File

@ -3805,7 +3805,7 @@ c_parser_condition (c_parser *parser)
tree cond;
loc = c_parser_peek_token (parser)->location;
cond = c_objc_common_truthvalue_conversion
(c_parser_expression_conv (parser).value);
(loc, c_parser_expression_conv (parser).value);
if (CAN_HAVE_LOCATION_P (cond))
SET_EXPR_LOCATION (cond, loc);
if (warn_sequence_point)
@ -4426,8 +4426,13 @@ static struct c_expr
c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
{
struct c_expr cond, exp1, exp2, ret;
location_t cond_loc;
gcc_assert (!after || c_dialect_objc ());
cond_loc = c_parser_peek_token (parser)->location;
cond = c_parser_binary_expression (parser, after);
if (c_parser_next_token_is_not (parser, CPP_QUERY))
return cond;
cond = default_function_array_conversion (cond);
@ -4438,14 +4443,14 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
"ISO C forbids omitting the middle term of a ?: expression");
/* Make sure first operand is calculated only once. */
exp1.value = save_expr (default_conversion (cond.value));
cond.value = c_objc_common_truthvalue_conversion (exp1.value);
cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
skip_evaluation += cond.value == truthvalue_true_node;
}
else
{
cond.value
= c_objc_common_truthvalue_conversion
(default_conversion (cond.value));
(cond_loc, default_conversion (cond.value));
skip_evaluation += cond.value == truthvalue_false_node;
exp1 = c_parser_expression_conv (parser);
skip_evaluation += ((cond.value == truthvalue_true_node)
@ -4570,6 +4575,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
enum tree_code op;
} stack[NUM_PRECS];
int sp;
/* Location of the binary operator. */
location_t binary_loc;
#define POP \
do { \
switch (stack[sp].op) \
@ -4587,7 +4594,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
= default_function_array_conversion (stack[sp - 1].expr); \
stack[sp].expr \
= default_function_array_conversion (stack[sp].expr); \
stack[sp - 1].expr = parser_build_binary_op (stack[sp].op, \
stack[sp - 1].expr = parser_build_binary_op (binary_loc, \
stack[sp].op, \
stack[sp - 1].expr, \
stack[sp].expr); \
sp--; \
@ -4681,6 +4689,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
expression. */
goto out;
}
binary_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
while (oprec <= stack[sp].prec)
POP;
@ -4690,14 +4699,14 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
stack[sp].expr
= default_function_array_conversion (stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
(default_conversion (stack[sp].expr.value));
(binary_loc, default_conversion (stack[sp].expr.value));
skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
break;
case TRUTH_ORIF_EXPR:
stack[sp].expr
= default_function_array_conversion (stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
(default_conversion (stack[sp].expr.value));
(binary_loc, default_conversion (stack[sp].expr.value));
skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
break;
default:
@ -7602,7 +7611,7 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
{
cond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (cond);
cond = c_objc_common_truthvalue_conversion (input_location, cond);
if (CAN_HAVE_LOCATION_P (cond))
SET_EXPR_LOCATION (cond, input_location);
}

View File

@ -521,7 +521,6 @@ extern struct c_declspecs *finish_declspecs (struct c_declspecs *);
/* in c-objc-common.c */
extern bool c_objc_common_init (void);
extern bool c_missing_noreturn_ok_p (tree);
extern tree c_objc_common_truthvalue_conversion (tree expr);
extern bool c_warn_unused_global_decl (const_tree);
extern void c_initialize_diagnostics (diagnostic_context *);
extern bool c_vla_unspec_p (tree x, tree fn);
@ -540,6 +539,7 @@ extern struct c_switch *c_switch_stack;
extern struct c_label_context_se *label_context_stack_se;
extern struct c_label_context_vm *label_context_stack_vm;
extern tree c_objc_common_truthvalue_conversion (location_t, tree);
extern tree require_complete_type (tree);
extern int same_translation_unit_p (const_tree, const_tree);
extern int comptypes (tree, tree);
@ -557,7 +557,8 @@ extern struct c_expr c_expr_sizeof_expr (struct c_expr);
extern struct c_expr c_expr_sizeof_type (struct c_type_name *);
extern struct c_expr parser_build_unary_op (enum tree_code, struct c_expr,
location_t);
extern struct c_expr parser_build_binary_op (enum tree_code, struct c_expr,
extern struct c_expr parser_build_binary_op (location_t,
enum tree_code, struct c_expr,
struct c_expr);
extern tree build_conditional_expr (tree, tree, tree);
extern tree build_compound_expr (tree, tree);

View File

@ -2163,8 +2163,9 @@ build_array_ref (tree array, tree index, location_t loc)
gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE);
gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0),
"array indexing", loc);
return build_indirect_ref
(build_binary_op (loc, PLUS_EXPR, ar, index, 0),
"array indexing", loc);
}
}
@ -2760,23 +2761,29 @@ parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
in the input. CODE, a tree_code, specifies the binary operator, and
ARG1 and ARG2 are the operands. In addition to constructing the
expression, we check for operands that were written with other binary
operators in a way that is likely to confuse the user. */
operators in a way that is likely to confuse the user.
LOCATION is the location of the binary operator. */
struct c_expr
parser_build_binary_op (enum tree_code code, struct c_expr arg1,
struct c_expr arg2)
parser_build_binary_op (location_t location, enum tree_code code,
struct c_expr arg1, struct c_expr arg2)
{
struct c_expr result;
enum tree_code code1 = arg1.original_code;
enum tree_code code2 = arg2.original_code;
result.value = build_binary_op (code, arg1.value, arg2.value, 1);
result.value = build_binary_op (location, code,
arg1.value, arg2.value, 1);
result.original_code = code;
if (TREE_CODE (result.value) == ERROR_MARK)
return result;
if (location != UNKNOWN_LOCATION)
protected_set_expr_location (result.value, location);
/* Check for cases such as x+y<<z which users are likely
to misinterpret. */
if (warn_parentheses)
@ -2873,7 +2880,8 @@ pointer_diff (tree op0, tree op1)
Do not do default conversions on the minus operator
in case restype is a short type. */
op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
op0 = build_binary_op (input_location,
MINUS_EXPR, convert (restype, op0),
convert (restype, op1), 0);
/* This generates an error if op1 is pointer to incomplete type. */
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1))))
@ -3006,7 +3014,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
error ("wrong type argument to unary exclamation mark");
return error_mark_node;
}
arg = c_objc_common_truthvalue_conversion (arg);
arg = c_objc_common_truthvalue_conversion (input_location, arg);
return invert_truthvalue (arg);
case REALPART_EXPR:
@ -3167,7 +3175,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
tree op0 = TREE_OPERAND (arg, 0);
if (!c_mark_addressable (op0))
return error_mark_node;
return build_binary_op (PLUS_EXPR,
return build_binary_op (EXPR_LOCATION (xarg), PLUS_EXPR,
(TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
? array_to_pointer_conversion (op0)
: op0),
@ -3859,7 +3867,8 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
if (modifycode != NOP_EXPR)
{
lhs = stabilize_reference (lhs);
newrhs = build_binary_op (modifycode, lhs, rhs, 1);
newrhs = build_binary_op (EXPR_LOCATION (lhs),
modifycode, lhs, rhs, 1);
}
/* Give an error for storing in something that is 'const'. */
@ -7914,6 +7923,7 @@ push_cleanup (tree ARG_UNUSED (decl), tree cleanup, bool eh_only)
/* Build a binary-operation expression without default conversions.
CODE is the kind of expression to build.
LOCATION is the operator's location.
This function differs from `build' in several ways:
the data type of the result is computed and recorded in it,
warnings are generated if arg data types are invalid,
@ -7928,8 +7938,8 @@ push_cleanup (tree ARG_UNUSED (decl), tree cleanup, bool eh_only)
the arithmetic is to be done. */
tree
build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
int convert_p)
build_binary_op (location_t location, enum tree_code code,
tree orig_op0, tree orig_op1, int convert_p)
{
tree type0, type1;
enum tree_code code0, code1;
@ -7981,6 +7991,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
/* True means types are compatible as far as ObjC is concerned. */
bool objc_ok;
if (location == UNKNOWN_LOCATION)
location = input_location;
if (convert_p)
{
op0 = default_conversion (orig_op0);
@ -8013,7 +8026,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
if ((invalid_op_diag
= targetm.invalid_binary_op (code, type0, type1)))
{
error (invalid_op_diag);
error_at (location, invalid_op_diag);
return error_mark_node;
}
@ -8131,8 +8144,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
but that does not mean the operands should be
converted to ints! */
result_type = integer_type_node;
op0 = c_common_truthvalue_conversion (op0);
op1 = c_common_truthvalue_conversion (op1);
op0 = c_common_truthvalue_conversion (location, op0);
op1 = c_common_truthvalue_conversion (location, op1);
converted = 1;
}
break;
@ -8197,8 +8210,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
case EQ_EXPR:
case NE_EXPR:
if (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1))
warning (OPT_Wfloat_equal,
"comparing floating point with == or != is unsafe");
warning_at (location,
OPT_Wfloat_equal,
"comparing floating point with == or != is unsafe");
/* Result of comparison is always int,
but don't convert the args to int! */
build_type = integer_type_node;
@ -8222,20 +8236,20 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
whose value is 0 but which isn't a valid null ptr const. */
if (pedantic && !null_pointer_constant_p (orig_op0)
&& TREE_CODE (tt1) == FUNCTION_TYPE)
pedwarn (input_location, OPT_pedantic, "ISO C forbids "
pedwarn (location, OPT_pedantic, "ISO C forbids "
"comparison of %<void *%> with function pointer");
}
else if (VOID_TYPE_P (tt1))
{
if (pedantic && !null_pointer_constant_p (orig_op1)
&& TREE_CODE (tt0) == FUNCTION_TYPE)
pedwarn (input_location, OPT_pedantic, "ISO C forbids "
pedwarn (location, OPT_pedantic, "ISO C forbids "
"comparison of %<void *%> with function pointer");
}
else
/* Avoid warning about the volatile ObjC EH puts on decls. */
if (!objc_ok)
pedwarn (input_location, 0,
pedwarn (location, 0,
"comparison of distinct pointer types lacks a cast");
if (result_type == NULL_TREE)
@ -8245,27 +8259,29 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
{
if (TREE_CODE (op0) == ADDR_EXPR
&& decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
warning (OPT_Waddress, "the address of %qD will never be NULL",
TREE_OPERAND (op0, 0));
warning_at (location,
OPT_Waddress, "the address of %qD will never be NULL",
TREE_OPERAND (op0, 0));
result_type = type0;
}
else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
{
if (TREE_CODE (op1) == ADDR_EXPR
&& decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
warning (OPT_Waddress, "the address of %qD will never be NULL",
TREE_OPERAND (op1, 0));
warning_at (location,
OPT_Waddress, "the address of %qD will never be NULL",
TREE_OPERAND (op1, 0));
result_type = type1;
}
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
pedwarn (input_location, 0, "comparison between pointer and integer");
pedwarn (location, 0, "comparison between pointer and integer");
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
result_type = type1;
pedwarn (input_location, 0, "comparison between pointer and integer");
pedwarn (location, 0, "comparison between pointer and integer");
}
break;
@ -8286,16 +8302,16 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
result_type = common_pointer_type (type0, type1);
if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
!= !COMPLETE_TYPE_P (TREE_TYPE (type1)))
pedwarn (input_location, 0,
pedwarn (location, 0,
"comparison of complete and incomplete pointers");
else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn (input_location, OPT_pedantic, "ISO C forbids "
pedwarn (location, OPT_pedantic, "ISO C forbids "
"ordered comparisons of pointers to functions");
}
else
{
result_type = ptr_type_node;
pedwarn (input_location, 0,
pedwarn (location, 0,
"comparison of distinct pointer types lacks a cast");
}
}
@ -8303,27 +8319,27 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
{
result_type = type0;
if (pedantic)
pedwarn (input_location, OPT_pedantic,
pedwarn (location, OPT_pedantic,
"ordered comparison of pointer with integer zero");
else if (extra_warnings)
warning (OPT_Wextra,
warning_at (location, OPT_Wextra,
"ordered comparison of pointer with integer zero");
}
else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
{
result_type = type1;
pedwarn (input_location, OPT_pedantic,
pedwarn (location, OPT_pedantic,
"ordered comparison of pointer with integer zero");
}
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
pedwarn (input_location, 0, "comparison between pointer and integer");
pedwarn (location, 0, "comparison between pointer and integer");
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
result_type = type1;
pedwarn (input_location, 0, "comparison between pointer and integer");
pedwarn (location, 0, "comparison between pointer and integer");
}
break;
@ -8339,7 +8355,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
|| !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
TREE_TYPE (type1))))
{
binary_op_error (code, type0, type1);
binary_op_error (location, code, type0, type1);
return error_mark_node;
}
@ -8429,7 +8445,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
if (warn_sign_compare && !skip_evaluation)
{
warn_for_sign_compare (orig_op0, orig_op1, op0, op1,
warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
result_type, resultcode);
}
}
@ -8443,7 +8459,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
if (!result_type)
{
binary_op_error (code, TREE_TYPE (op0), TREE_TYPE (op1));
binary_op_error (location, code, TREE_TYPE (op0), TREE_TYPE (op1));
return error_mark_node;
}
@ -8479,23 +8495,23 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
/* Convert EXPR to be a truth-value, validating its type for this
purpose. */
purpose. LOCATION is the source location for the expression. */
tree
c_objc_common_truthvalue_conversion (tree expr)
c_objc_common_truthvalue_conversion (location_t location, tree expr)
{
switch (TREE_CODE (TREE_TYPE (expr)))
{
case ARRAY_TYPE:
error ("used array that cannot be converted to pointer where scalar is required");
error_at (location, "used array that cannot be converted to pointer where scalar is required");
return error_mark_node;
case RECORD_TYPE:
error ("used struct type value where scalar is required");
error_at (location, "used struct type value where scalar is required");
return error_mark_node;
case UNION_TYPE:
error ("used union type value where scalar is required");
error_at (location, "used union type value where scalar is required");
return error_mark_node;
case FUNCTION_TYPE:
@ -8507,7 +8523,7 @@ c_objc_common_truthvalue_conversion (tree expr)
/* ??? Should we also give an error for void and vectors rather than
leaving those to give errors later? */
return c_common_truthvalue_conversion (expr);
return c_common_truthvalue_conversion (location, expr);
}

View File

@ -1,3 +1,30 @@
2008-09-23 Aldy Hernandez <aldyh@redhat.com>
* typeck.c (build_array_ref): Pass location to cp_build_binary_op.
(get_member_function_from_ptrfunc): Same.
(build_x_binary_op): Same.
(build_binary_op): Same.
(cp_build_binary_op): New location argument.
(pointer_diff): Pass location to cp_build_binary_op.
(cp_truthvalue_conversion): Pass location to build_binary_op.
(convert_ptrmem): Pass location to cp_build_binary_op.
(cp_build_modify_expr): Same.
(build_ptrmemfunc): Same.
* init.c (expand_cleanup_for_base): Pass location to
c_common_truthvalue_conversion.
(build_new_1): Pass location to cp_build_binary_op.
(build_vec_delete_1): Pass location to *build_binary_op,
c_common_truthvalue_conversion.
(build_vec_init): Same.
(build_delete): Same.
* decl.c (compute_array_index_type): Same.
* call.c (build_new_op): Same.
* rtti.c (build_dynamic_cast_1): Same.
* cp-tree.h: Add argument to cp_build_binary_op.
* semantics.c (handle_omp_for_class_iterator): Pass location to
*build_binary_op, c_common_truthvalue_conversion.
* decl2.c (get_guard_cond): Same.
2008-09-17 Richard Guenther <rguenther@suse.de>
PR c++/22374

View File

@ -4199,7 +4199,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
return cp_build_binary_op (code, arg1, arg2, complain);
return cp_build_binary_op (input_location, code, arg1, arg2, complain);
case UNARY_PLUS_EXPR:
case NEGATE_EXPR:

View File

@ -4963,7 +4963,8 @@ extern tree composite_pointer_type (tree, tree, tree, tree,
const char*, tsubst_flags_t);
extern tree merge_types (tree, tree);
extern tree check_return_expr (tree, bool *);
extern tree cp_build_binary_op (enum tree_code, tree, tree,
extern tree cp_build_binary_op (location_t,
enum tree_code, tree, tree,
tsubst_flags_t);
#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
extern tree build_ptrmemfunc_access_expr (tree, tree);

View File

@ -7223,7 +7223,8 @@ compute_array_index_type (tree name, tree size)
cp_build_binary_op will be appropriately folded. */
saved_processing_template_decl = processing_template_decl;
processing_template_decl = 0;
itype = cp_build_binary_op (MINUS_EXPR,
itype = cp_build_binary_op (input_location,
MINUS_EXPR,
cp_convert (ssizetype, size),
cp_convert (ssizetype, integer_one_node),
tf_warning_or_error);

View File

@ -2530,14 +2530,16 @@ get_guard_cond (tree guard)
guard_value = integer_one_node;
if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
guard_value = convert (TREE_TYPE (guard), guard_value);
guard = cp_build_binary_op (BIT_AND_EXPR, guard, guard_value,
guard = cp_build_binary_op (input_location,
BIT_AND_EXPR, guard, guard_value,
tf_warning_or_error);
}
guard_value = integer_zero_node;
if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
guard_value = convert (TREE_TYPE (guard), guard_value);
return cp_build_binary_op (EQ_EXPR, guard, guard_value,
return cp_build_binary_op (input_location,
EQ_EXPR, guard, guard_value,
tf_warning_or_error);
}
@ -2927,20 +2929,22 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp)
last to destroy the variable. */
else if (initp)
guard_cond
= cp_build_binary_op (EQ_EXPR,
= cp_build_binary_op (input_location,
EQ_EXPR,
cp_build_unary_op (PREINCREMENT_EXPR,
guard,
/*noconvert=*/1,
tf_warning_or_error),
guard,
/*noconvert=*/1,
tf_warning_or_error),
integer_one_node,
tf_warning_or_error);
else
guard_cond
= cp_build_binary_op (EQ_EXPR,
= cp_build_binary_op (input_location,
EQ_EXPR,
cp_build_unary_op (PREDECREMENT_EXPR,
guard,
/*noconvert=*/1,
tf_warning_or_error),
guard,
/*noconvert=*/1,
tf_warning_or_error),
integer_zero_node,
tf_warning_or_error);
@ -2993,7 +2997,8 @@ do_static_initialization_or_destruction (tree vars, bool initp)
/* Build the outer if-stmt to check for initialization or destruction. */
init_if_stmt = begin_if_stmt ();
cond = initp ? integer_one_node : integer_zero_node;
cond = cp_build_binary_op (EQ_EXPR,
cond = cp_build_binary_op (input_location,
EQ_EXPR,
initialize_p_decl,
cond,
tf_warning_or_error);
@ -3026,7 +3031,8 @@ do_static_initialization_or_destruction (tree vars, bool initp)
/* Conditionalize this initialization on being in the right priority
and being initializing/finalizing appropriately. */
priority_if_stmt = begin_if_stmt ();
cond = cp_build_binary_op (EQ_EXPR,
cond = cp_build_binary_op (input_location,
EQ_EXPR,
priority_decl,
build_int_cst (NULL_TREE, priority),
tf_warning_or_error);

View File

@ -1001,7 +1001,7 @@ expand_cleanup_for_base (tree binfo, tree flag)
tf_warning_or_error);
if (flag)
expr = fold_build3 (COND_EXPR, void_type_node,
c_common_truthvalue_conversion (flag),
c_common_truthvalue_conversion (input_location, flag),
expr, integer_zero_node);
finish_eh_cleanup (expr);
@ -1877,7 +1877,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
for (elt_type = type;
TREE_CODE (elt_type) == ARRAY_TYPE;
elt_type = TREE_TYPE (elt_type))
nelts = cp_build_binary_op (MULT_EXPR, nelts,
nelts = cp_build_binary_op (input_location,
MULT_EXPR, nelts,
array_type_nelts_top (elt_type),
complain);
@ -2177,7 +2178,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
}
init_expr
= build_vec_init (init_expr,
cp_build_binary_op (MINUS_EXPR, outer_nelts,
cp_build_binary_op (input_location,
MINUS_EXPR, outer_nelts,
integer_one_node,
complain),
init,
@ -2312,7 +2314,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
{
if (check_new)
{
tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node,
tree ifexp = cp_build_binary_op (input_location,
NE_EXPR, alloc_node,
integer_zero_node,
complain);
rval = build_conditional_expr (ifexp, rval, alloc_node,
@ -2579,7 +2582,8 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
cookie_size = targetm.cxx.get_cookie_size (type);
base_tbd
= cp_convert (ptype,
cp_build_binary_op (MINUS_EXPR,
cp_build_binary_op (input_location,
MINUS_EXPR,
cp_convert (string_type_node,
base),
cookie_size,
@ -2933,13 +2937,15 @@ build_vec_init (tree base, tree maxindex, tree init,
&& from_array != 2)
{
tree e;
tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator,
tree m = cp_build_binary_op (input_location,
MINUS_EXPR, maxindex, iterator,
complain);
/* Flatten multi-dimensional array since build_vec_delete only
expects one-dimensional array. */
if (TREE_CODE (type) == ARRAY_TYPE)
m = cp_build_binary_op (MULT_EXPR, m,
m = cp_build_binary_op (input_location,
MULT_EXPR, m,
array_type_nelts_total (type),
complain);
@ -3167,7 +3173,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
ifexp = integer_one_node;
else
/* Handle deleting a null pointer. */
ifexp = fold (cp_build_binary_op (NE_EXPR, addr, integer_zero_node,
ifexp = fold (cp_build_binary_op (input_location,
NE_EXPR, addr, integer_zero_node,
tf_warning_or_error));
if (ifexp != integer_one_node)

View File

@ -721,7 +721,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
tree neq;
result = save_expr (result);
neq = c_common_truthvalue_conversion (result);
neq = c_common_truthvalue_conversion (input_location, result);
return cp_convert (type,
build3 (COND_EXPR, TREE_TYPE (result),
neq, result, bad));

View File

@ -4107,7 +4107,8 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
tf_warning_or_error));
*pre_body = pop_stmt_list (*pre_body);
cond = cp_build_binary_op (TREE_CODE (cond), decl, diff,
cond = cp_build_binary_op (elocus,
TREE_CODE (cond), decl, diff,
tf_warning_or_error);
incr = build_modify_expr (decl, PLUS_EXPR, incr);

View File

@ -2655,7 +2655,8 @@ build_array_ref (tree array, tree idx, location_t loc)
warn_array_subscript_with_type_char (idx);
ret = cp_build_indirect_ref (cp_build_binary_op (PLUS_EXPR, ar, ind,
ret = cp_build_indirect_ref (cp_build_binary_op (input_location,
PLUS_EXPR, ar, ind,
tf_warning_or_error),
"array indexing",
tf_warning_or_error);
@ -2718,16 +2719,20 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
{
case ptrmemfunc_vbit_in_pfn:
e1 = cp_build_binary_op (BIT_AND_EXPR, idx, integer_one_node,
e1 = cp_build_binary_op (input_location,
BIT_AND_EXPR, idx, integer_one_node,
tf_warning_or_error);
idx = cp_build_binary_op (MINUS_EXPR, idx, integer_one_node,
idx = cp_build_binary_op (input_location,
MINUS_EXPR, idx, integer_one_node,
tf_warning_or_error);
break;
case ptrmemfunc_vbit_in_delta:
e1 = cp_build_binary_op (BIT_AND_EXPR, delta, integer_one_node,
e1 = cp_build_binary_op (input_location,
BIT_AND_EXPR, delta, integer_one_node,
tf_warning_or_error);
delta = cp_build_binary_op (RSHIFT_EXPR, delta, integer_one_node,
delta = cp_build_binary_op (input_location,
RSHIFT_EXPR, delta, integer_one_node,
tf_warning_or_error);
break;
@ -3141,15 +3146,16 @@ build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code,
/* For the c-common bits. */
tree
build_binary_op (enum tree_code code, tree op0, tree op1,
build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
int convert_p ATTRIBUTE_UNUSED)
{
return cp_build_binary_op(code, op0, op1, tf_warning_or_error);
return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
}
/* Build a binary-operation expression without default conversions.
CODE is the kind of expression to build.
LOCATION is the location_t of the operator in the source code.
This function differs from `build' in several ways:
the data type of the result is computed and recorded in it,
warnings are generated if arg data types are invalid,
@ -3167,7 +3173,8 @@ build_binary_op (enum tree_code code, tree op0, tree op1,
multiple inheritance, and deal with pointer to member functions. */
tree
cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
cp_build_binary_op (location_t location,
enum tree_code code, tree orig_op0, tree orig_op1,
tsubst_flags_t complain)
{
tree op0, op1;
@ -3555,18 +3562,22 @@ cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
{
tree pfn0 = pfn_from_ptrmemfunc (op0);
tree delta0 = delta_from_ptrmemfunc (op0);
tree e1 = cp_build_binary_op (EQ_EXPR,
tree e1 = cp_build_binary_op (location,
EQ_EXPR,
pfn0,
fold_convert (TREE_TYPE (pfn0),
integer_zero_node),
complain);
tree e2 = cp_build_binary_op (BIT_AND_EXPR,
tree e2 = cp_build_binary_op (location,
BIT_AND_EXPR,
delta0,
integer_one_node,
complain);
e2 = cp_build_binary_op (EQ_EXPR, e2, integer_zero_node,
e2 = cp_build_binary_op (location,
EQ_EXPR, e2, integer_zero_node,
complain);
op0 = cp_build_binary_op (TRUTH_ANDIF_EXPR, e1, e2,
op0 = cp_build_binary_op (location,
TRUTH_ANDIF_EXPR, e1, e2,
complain);
op1 = cp_convert (TREE_TYPE (op0), integer_one_node);
}
@ -3578,7 +3589,7 @@ cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
result_type = TREE_TYPE (op0);
}
else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (op0))
return cp_build_binary_op (code, op1, op0, complain);
return cp_build_binary_op (location, code, op1, op0, complain);
else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1))
{
tree type;
@ -3626,28 +3637,34 @@ cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
pointer-to-member is any member with a zero PFN and
LSB of the DELTA field is 0. */
e1 = cp_build_binary_op (BIT_AND_EXPR,
e1 = cp_build_binary_op (location, BIT_AND_EXPR,
delta0,
integer_one_node,
complain);
e1 = cp_build_binary_op (EQ_EXPR, e1, integer_zero_node,
e1 = cp_build_binary_op (location,
EQ_EXPR, e1, integer_zero_node,
complain);
e2 = cp_build_binary_op (BIT_AND_EXPR,
e2 = cp_build_binary_op (location, BIT_AND_EXPR,
delta1,
integer_one_node,
complain);
e2 = cp_build_binary_op (EQ_EXPR, e2, integer_zero_node,
e2 = cp_build_binary_op (location,
EQ_EXPR, e2, integer_zero_node,
complain);
e1 = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1,
e1 = cp_build_binary_op (location,
TRUTH_ANDIF_EXPR, e2, e1,
complain);
e2 = cp_build_binary_op (EQ_EXPR,
e2 = cp_build_binary_op (location, EQ_EXPR,
pfn0,
fold_convert (TREE_TYPE (pfn0),
integer_zero_node),
complain);
e2 = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1, complain);
e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1, complain);
e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2, complain);
e2 = cp_build_binary_op (location,
TRUTH_ANDIF_EXPR, e2, e1, complain);
e1 = cp_build_binary_op (location,
EQ_EXPR, delta0, delta1, complain);
e1 = cp_build_binary_op (location,
TRUTH_ORIF_EXPR, e1, e2, complain);
}
else
{
@ -3660,19 +3677,24 @@ cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
pointer-to-member is any member with a zero PFN; the
DELTA field is unspecified. */
e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1, complain);
e2 = cp_build_binary_op (EQ_EXPR,
e1 = cp_build_binary_op (location,
EQ_EXPR, delta0, delta1, complain);
e2 = cp_build_binary_op (location,
EQ_EXPR,
pfn0,
fold_convert (TREE_TYPE (pfn0),
integer_zero_node),
complain);
e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2, complain);
e1 = cp_build_binary_op (location,
TRUTH_ORIF_EXPR, e1, e2, complain);
}
e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
e = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1, complain);
e = cp_build_binary_op (location,
TRUTH_ANDIF_EXPR, e2, e1, complain);
if (code == EQ_EXPR)
return e;
return cp_build_binary_op (EQ_EXPR, e, integer_zero_node, complain);
return cp_build_binary_op (location,
EQ_EXPR, e, integer_zero_node, complain);
}
else
{
@ -3773,7 +3795,7 @@ cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
|| !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
TREE_TYPE (type1)))
{
binary_op_error (code, type0, type1);
binary_op_error (location, code, type0, type1);
return error_mark_node;
}
arithmetic_types_p = 1;
@ -3857,8 +3879,8 @@ cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
&& !processing_template_decl
&& (complain & tf_warning))
{
warn_for_sign_compare (orig_op0, orig_op1, op0, op1,
result_type, resultcode);
warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
result_type, resultcode);
}
}
@ -3954,7 +3976,8 @@ pointer_diff (tree op0, tree op1, tree ptrtype)
/* First do the subtraction as integers;
then drop through to build the divide operator. */
op0 = cp_build_binary_op (MINUS_EXPR,
op0 = cp_build_binary_op (input_location,
MINUS_EXPR,
cp_convert (restype, op0),
cp_convert (restype, op1),
tf_warning_or_error);
@ -4073,9 +4096,10 @@ cp_truthvalue_conversion (tree expr)
{
tree type = TREE_TYPE (expr);
if (TYPE_PTRMEM_P (type))
return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
return build_binary_op (EXPR_LOCATION (expr),
NE_EXPR, expr, integer_zero_node, 1);
else
return c_common_truthvalue_conversion (expr);
return c_common_truthvalue_conversion (input_location, expr);
}
/* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR. */
@ -4968,12 +4992,14 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
{
tree cond, op1, op2;
cond = cp_build_binary_op (EQ_EXPR,
cond = cp_build_binary_op (input_location,
EQ_EXPR,
expr,
build_int_cst (TREE_TYPE (expr), -1),
tf_warning_or_error);
op1 = build_nop (ptrdiff_type_node, expr);
op2 = cp_build_binary_op (PLUS_EXPR, op1, delta,
op2 = cp_build_binary_op (input_location,
PLUS_EXPR, op1, delta,
tf_warning_or_error);
expr = fold_build3 (COND_EXPR, ptrdiff_type_node, cond, op1, op2);
@ -5914,7 +5940,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
|| MAYBE_CLASS_TYPE_P (lhstype)));
lhs = stabilize_reference (lhs);
newrhs = cp_build_binary_op (modifycode, lhs, rhs,
newrhs = cp_build_binary_op (EXPR_LOCATION (lhs),
modifycode, lhs, rhs,
complain);
if (newrhs == error_mark_node)
{
@ -6303,9 +6330,11 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p)
gcc_assert (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (delta), ptrdiff_type_node));
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node,
n = cp_build_binary_op (input_location,
LSHIFT_EXPR, n, integer_one_node,
tf_warning_or_error);
delta = cp_build_binary_op (PLUS_EXPR, delta, n, tf_warning_or_error);
delta = cp_build_binary_op (input_location,
PLUS_EXPR, delta, n, tf_warning_or_error);
return build_ptrmemfunc1 (to_type, delta, npfn);
}

View File

@ -1,3 +1,10 @@
2008-09-23 Aldy Hernandez <aldyh@redhat.com>
* objc-act.c (next_sjlj_build_enter_and_setjmp): Call
c_common_truthvalue_conversion with location.
(next_sjlj_build_catch_list): Same.
(next_sjlj_build_try_catch_finally): Same.
2008-09-17 Andrew Pinski <andrew_pinski@playstation.sony.com>
PR objc/37460

View File

@ -3538,7 +3538,7 @@ next_sjlj_build_enter_and_setjmp (void)
sj = build_function_call (objc_setjmp_decl, t);
cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
cond = c_common_truthvalue_conversion (cond);
cond = c_common_truthvalue_conversion (input_location, cond);
return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
}
@ -3605,7 +3605,7 @@ next_sjlj_build_catch_list (void)
t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
args = tree_cons (NULL, t, args);
t = build_function_call (objc_exception_match_decl, args);
cond = c_common_truthvalue_conversion (t);
cond = c_common_truthvalue_conversion (input_location, t);
}
t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
@ -3727,7 +3727,8 @@ next_sjlj_build_try_catch_finally (void)
/* Build the complete FINALLY statement list. */
t = next_sjlj_build_try_exit ();
t = build_stmt (COND_EXPR,
c_common_truthvalue_conversion (rethrow_decl),
c_common_truthvalue_conversion
(input_location, rethrow_decl),
NULL, t);
SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
@ -3738,7 +3739,8 @@ next_sjlj_build_try_catch_finally (void)
t = tree_cons (NULL, rethrow_decl, NULL);
t = build_function_call (objc_exception_throw_decl, t);
t = build_stmt (COND_EXPR,
c_common_truthvalue_conversion (rethrow_decl),
c_common_truthvalue_conversion (input_location,
rethrow_decl),
t, NULL);
SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));

View File

@ -1,3 +1,10 @@
2008-09-23 Aldy Hernandez <aldyh@redhat.com>
* gcc.dg/Walways-true-1.c: Test column numbers.
* gcc.dg/c90-const-expr-5.c: Same.
* gcc.dg/compare4.c: Same.
* gcc.dg/Werror-1.c: Same.
2008-09-23 Daniel Kraft <d@domob.eu>
PR fortran/37588
@ -619,6 +626,7 @@
PR tree-optimization/37508
* gcc.dg/tree-ssa/pr37508.c: New testcase.
>>>>>>> .r140590
2008-09-15 Aldy Hernandez <aldyh@redhat.com>
* g++.old-deja/g++.brendan/crash16.C: Function name is the correct

View File

@ -2,7 +2,7 @@
Origin: Ian Lance Taylor <iant@google.com>. */
/* { dg-do compile} */
/* { dg-options "-Waddress" } */
/* { dg-options "-Waddress -fshow-column" } */
extern int foo (int);
@ -12,46 +12,46 @@ void
bar (int a)
{
lab:
if (foo) /* { dg-warning "always evaluate as" "correct warning" } */
if (foo) /* { dg-warning "7:always evaluate as" "correct warning" } */
foo (0);
if (foo (1))
;
if (&i) /* { dg-warning "always evaluate as" "correct warning" } */
if (&i) /* { dg-warning "7:always evaluate as" "correct warning" } */
foo (2);
if (i)
foo (3);
if (&a) /* { dg-warning "always evaluate as" "correct warning" } */
if (&a) /* { dg-warning "7:always evaluate as" "correct warning" } */
foo (4);
if (a)
foo (5);
if (&&lab) /* { dg-warning "always evaluate as" "correct warning" } */
if (&&lab) /* { dg-warning "7:always evaluate as" "correct warning" } */
foo (6);
if (foo == 0) /* { dg-warning "never be NULL" "correct warning" } */
if (foo == 0) /* { dg-warning "11:never be NULL" "correct warning" } */
foo (7);
if (foo (1) == 0)
foo (8);
if (&i == 0) /* { dg-warning "never be NULL" "correct warning" } */
if (&i == 0) /* { dg-warning "10:never be NULL" "correct warning" } */
foo (9);
if (i == 0)
foo (10);
if (&a == 0) /* { dg-warning "never be NULL" "correct warning" } */
if (&a == 0) /* { dg-warning "10:never be NULL" "correct warning" } */
foo (11);
if (a == 0)
foo (12);
if (&&lab == 0) /* { dg-warning "never be NULL" "correct warning" } */
if (&&lab == 0) /* { dg-warning "13:never be NULL" "correct warning" } */
foo (13);
if (0 == foo) /* { dg-warning "never be NULL" "correct warning" } */
if (0 == foo) /* { dg-warning "9:never be NULL" "correct warning" } */
foo (14);
if (0 == foo (1))
foo (15);
if (0 == &i) /* { dg-warning "never be NULL" "correct warning" } */
if (0 == &i) /* { dg-warning "9:never be NULL" "correct warning" } */
foo (16);
if (0 == i)
foo (17);
if (0 == &a) /* { dg-warning "never be NULL" "correct warning" } */
if (0 == &a) /* { dg-warning "9:never be NULL" "correct warning" } */
foo (18);
if (0 == a)
foo (19);
if (0 == &&lab) /* { dg-warning "never be NULL" "correct warning" } */
if (0 == &&lab) /* { dg-warning "9:never be NULL" "correct warning" } */
foo (20);
}

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "-Waddress -Wattributes -Werror" } */
/* { dg-options "-Waddress -Wattributes -Werror -fshow-column" } */
/* { dg-message "warnings being treated as errors" "" {target "*-*-*"} 0 } */
/* This is the first in a series of test cases that test the
@ -16,6 +16,6 @@ int i;
void
foo ()
{
if (&i) /* { dg-error ".* will always evaluate as 'true'" } */
if (&i) /* { dg-error "7:.* will always evaluate as 'true'" } */
grill ();
}

View File

@ -2,7 +2,7 @@
qualified void. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
/* { dg-options "-std=iso9899:1990 -pedantic-errors -fshow-column" } */
typedef void V;
int *p;
@ -15,14 +15,14 @@ f (void)
{
/* (V *)0 is a null pointer constant, so the assignment should be
diagnosed. */
q = (j ? p : (V *)0); /* { dg-error "assignment from incompatible pointer type" } */
q = (j ? p : (void *)0); /* { dg-error "assignment from incompatible pointer type" } */
q = (j ? p : (V *)0); /* { dg-error "3:assignment from incompatible pointer type" } */
q = (j ? p : (void *)0); /* { dg-error "3:assignment from incompatible pointer type" } */
/* And this conversion should be valid. */
(void (*)(void))(V *)0;
(void (*)(void))(void *)0;
/* Pointers to qualified void are not valid null pointer
constants. */
fp = (const void *)0; /* { dg-error "ISO C forbids assignment between function pointer and 'void \\*'" } */
fp = (const void *)0; /* { dg-error "3:ISO C forbids assignment between function pointer and 'void \\*'" } */
fp = (void *)0;
fp = (V *)0;
fp = 0;
@ -32,8 +32,8 @@ f (void)
(void *)0 == fp;
fp == (V *)0;
(V *)0 == fp;
fp == (V *)1; /* { dg-error "ISO C forbids comparison of 'void \\*' with function pointer" } */
(V *)1 == fp; /* { dg-error "ISO C forbids comparison of 'void \\*' with function pointer" } */
fp == (const void *)0; /* { dg-error "ISO C forbids comparison of 'void \\*' with function pointer" } */
(const void *)0 == fp; /* { dg-error "ISO C forbids comparison of 'void \\*' with function pointer" } */
fp == (V *)1; /* { dg-error "6:ISO C forbids comparison of 'void \\*' with function pointer" } */
(V *)1 == fp; /* { dg-error "10:ISO C forbids comparison of 'void \\*' with function pointer" } */
fp == (const void *)0; /* { dg-error "6:ISO C forbids comparison of 'void \\*' with function pointer" } */
(const void *)0 == fp; /* { dg-error "19:ISO C forbids comparison of 'void \\*' with function pointer" } */
}

View File

@ -2,7 +2,7 @@
Origin: Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 5/13/2001. */
/* { dg-do compile } */
/* { dg-options "-Wsign-compare -fstrict-overflow" } */
/* { dg-options "-fshow-column -Wsign-compare -fstrict-overflow" } */
extern void bar(void);
@ -10,7 +10,7 @@ int foo(int x, int y, unsigned u)
{
/* A COMPOUND_EXPR is non-negative if the last element is known to
be non-negative. */
if (u < (bar(), -1)) /*{ dg-warning "signed and unsigned" "COMPOUND_EXPR" }*/
if (u < (bar(), -1)) /*{ dg-warning "9:signed and unsigned" "COMPOUND_EXPR" }*/
return x;
if (u < (bar(), 10))
return x;
@ -34,7 +34,7 @@ int foo(int x, int y, unsigned u)
/* A MODIFY_EXPR is non-negative if the new value is known to be
non-negative. */
if (u < (x = -1)) /* { dg-warning "signed and unsigned" "MODIFY_EXPR" } */
if (u < (x = -1)) /* { dg-warning "9:signed and unsigned" "MODIFY_EXPR" } */
return x;
if (u < (x = 10))
return x;

View File

@ -0,0 +1,29 @@
/* { dg-options "-fshow-column -Wall -Wfloat-equal -pedantic" } */
float a, b;
int *p;
struct {
int a;
char b;
} *q;
extern void bar();
void foo (void)
{
if (a == b) /* { dg-warning "9:comparing floating point with" } */
bar ();
if (p < q) /* { dg-warning "9:comparison of distinct pointer types" } */
bar ();
if (&p == 0) /* { dg-warning "10:will never be NULL" } */
bar();
if (p == 4) /* { dg-warning "9:comparison between pointer and integer" } */
bar();
if (p < 0) /* { dg-warning "9:ordered comparison of pointer with" } */
bar();
}