summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/gcc-interface/trans.c3
-rw-r--r--gcc/c-common.c6
-rw-r--r--gcc/c-parser.c12
-rw-r--r--gcc/c-typeck.c3
-rw-r--r--gcc/fold-const.c108
-rw-r--r--gcc/gimplify.c91
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c108
10 files changed, 285 insertions, 78 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f59688e0fe7..3c622f75512 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2009-04-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-common.c (c_common_truthvalue_conversion): Use LOCATION to build
+ NE_EXPR operations as well.
+ * c-parser.c (c_parser_condition): Do not set location information on
+ the condition.
+ (c_parser_conditional_expression): Likewise.
+ (c_parser_binary_expression): Set location information on operators.
+ * c-typeck.c (build_unary_op) <TRUTH_NOT_EXPR>: Reset the location if
+ TRUTH_NOT_EXPR has been folded.
+ * fold-const.c (fold_truth_not_expr): Copy location information from
+ the incoming expression to the outgoing one.
+ * gimplify.c (shortcut_cond_r): Add locus parameter. Pass it to
+ recursive calls on the LHS of the operator but pass that of the
+ operator to recursive calls on the RHS of the operator. Set it
+ on the COND_EXPR.
+ (shortcut_cond_expr): Set the locus of the operator on the second
+ COND_EXPR and that of the expression on the first in degenerate cases.
+ Pass the locus of the expression to calls to shortcut_cond_r.
+ Set the locus of the 'then' block on the associated jump, if any.
+ (gimplify_boolean_expr): Add locus parameter. Set it on the COND_EXPR.
+ (gimplify_expr) <TRUTH_ANDIF_EXPR>: Pass the locus of the outer
+ expression to call to gimplify_boolean_expr.
+
2009-04-21 Kai Tietz <kai.tietz@onevision.com>
* config.gcc: Add additional configuration for
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index a8e01f0eae7..6f31dbd3e3d 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,9 @@
2009-04-21 Eric Botcazou <ebotcazou@adacore.com>
+ * gcc-interface/trans.c (gnat_to_gnu): Do not overwrite location info.
+
+2009-04-21 Eric Botcazou <ebotcazou@adacore.com>
+
* gcc-interface/ada-tree.h (TYPE_RM_SIZE_NUM): Delete.
(TYPE_RM_SIZE): Access TYPE_LANG_SLOT_1 directly for integral types.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Modular_Integer_Type>:
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 50e3fca20e1..84aa3963910 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -5303,7 +5303,8 @@ gnat_to_gnu (Node_Id gnat_node)
if (gnu_result
&& EXPR_P (gnu_result)
&& TREE_CODE (gnu_result) != NOP_EXPR
- && !REFERENCE_CLASS_P (gnu_result))
+ && !REFERENCE_CLASS_P (gnu_result)
+ && !EXPR_HAS_LOCATION (gnu_result))
set_expr_location_from_node (gnu_result, gnat_node);
/* If we're supposed to return something of void_type, it means we have
diff --git a/gcc/c-common.c b/gcc/c-common.c
index eab4582b8e0..3595e552966 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4114,12 +4114,10 @@ c_common_truthvalue_conversion (location_t location, tree expr)
tree fixed_zero_node = build_fixed (TREE_TYPE (expr),
FCONST0 (TYPE_MODE
(TREE_TYPE (expr))));
- return build_binary_op (EXPR_LOCATION (expr),
- NE_EXPR, expr, fixed_zero_node, 1);
+ return build_binary_op (location, NE_EXPR, expr, fixed_zero_node, 1);
}
- return build_binary_op (EXPR_LOCATION (expr),
- NE_EXPR, expr, integer_zero_node, 1);
+ return build_binary_op (location, NE_EXPR, expr, integer_zero_node, 1);
}
static void def_builtin_1 (enum built_in_function fncode,
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index ca51d95eed5..676c709cdf2 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -3835,7 +3835,6 @@ c_parser_condition (c_parser *parser)
cond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (loc, cond);
cond = c_fully_fold (cond, false, NULL);
- protected_set_expr_location (cond, loc);
if (warn_sequence_point)
verify_sequence_points (cond);
return cond;
@@ -4479,7 +4478,6 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
cond_loc = c_parser_peek_token (parser)->location;
cond = c_parser_binary_expression (parser, after);
- protected_set_expr_location (cond.value, cond_loc);
if (c_parser_next_token_is_not (parser, CPP_QUERY))
return cond;
@@ -4651,6 +4649,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
enum prec prec;
/* The operation on its left. */
enum tree_code op;
+ /* The source location of this operation. */
+ location_t loc;
} stack[NUM_PRECS];
int sp;
/* Location of the binary operator. */
@@ -4672,13 +4672,14 @@ 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 (binary_loc, \
+ stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
stack[sp].op, \
stack[sp - 1].expr, \
stack[sp].expr); \
sp--; \
} while (0)
gcc_assert (!after || c_dialect_objc ());
+ stack[0].loc = c_parser_peek_token (parser)->location;
stack[0].expr = c_parser_cast_expression (parser, after);
stack[0].prec = PREC_NONE;
sp = 0;
@@ -4777,20 +4778,21 @@ 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
- (binary_loc, default_conversion (stack[sp].expr.value));
+ (stack[sp].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
- (binary_loc, default_conversion (stack[sp].expr.value));
+ (stack[sp].loc, default_conversion (stack[sp].expr.value));
skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
break;
default:
break;
}
sp++;
+ stack[sp].loc = binary_loc;
stack[sp].expr = c_parser_cast_expression (parser, NULL);
stack[sp].prec = oprec;
stack[sp].op = ocode;
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index f5cfc6440d3..1ff6e9b744d 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -3209,6 +3209,9 @@ build_unary_op (location_t location,
}
arg = c_objc_common_truthvalue_conversion (location, arg);
ret = invert_truthvalue (arg);
+ /* If the TRUTH_NOT_EXPR has been folded, reset the location. */
+ if (EXPR_P (ret) && EXPR_HAS_LOCATION (ret))
+ location = EXPR_LOCATION (ret);
goto return_build_unary_op;
case REALPART_EXPR:
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index bd5e97df4a9..ca07cf16720 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3641,7 +3641,7 @@ omit_two_operands (tree type, tree result, tree omitted1, tree omitted2)
tree
fold_truth_not_expr (tree arg)
{
- tree type = TREE_TYPE (arg);
+ tree t, type = TREE_TYPE (arg);
enum tree_code code = TREE_CODE (arg);
/* If this is a comparison, we can simply invert it, except for
@@ -3656,16 +3656,15 @@ fold_truth_not_expr (tree arg)
&& code != ORDERED_EXPR && code != UNORDERED_EXPR
&& code != NE_EXPR && code != EQ_EXPR)
return NULL_TREE;
- else
- {
- code = invert_tree_comparison (code,
- HONOR_NANS (TYPE_MODE (op_type)));
- if (code == ERROR_MARK)
- return NULL_TREE;
- else
- return build2 (code, type,
- TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
- }
+
+ code = invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (op_type)));
+ if (code == ERROR_MARK)
+ return NULL_TREE;
+
+ t = build2 (code, type, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
+ if (EXPR_HAS_LOCATION (arg))
+ SET_EXPR_LOCATION (t, EXPR_LOCATION (arg));
+ return t;
}
switch (code)
@@ -3674,14 +3673,16 @@ fold_truth_not_expr (tree arg)
return constant_boolean_node (integer_zerop (arg), type);
case TRUTH_AND_EXPR:
- return build2 (TRUTH_OR_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (TRUTH_OR_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case TRUTH_OR_EXPR:
- return build2 (TRUTH_AND_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (TRUTH_AND_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case TRUTH_XOR_EXPR:
/* Here we can invert either operand. We invert the first operand
@@ -3690,22 +3691,25 @@ fold_truth_not_expr (tree arg)
negation of the second operand. */
if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
- return build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
- TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
+ t = build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
+ TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
else
- return build2 (TRUTH_XOR_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- TREE_OPERAND (arg, 1));
+ t = build2 (TRUTH_XOR_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ TREE_OPERAND (arg, 1));
+ break;
case TRUTH_ANDIF_EXPR:
- return build2 (TRUTH_ORIF_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (TRUTH_ORIF_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case TRUTH_ORIF_EXPR:
- return build2 (TRUTH_ANDIF_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (TRUTH_ANDIF_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case TRUTH_NOT_EXPR:
return TREE_OPERAND (arg, 0);
@@ -3717,47 +3721,61 @@ fold_truth_not_expr (tree arg)
/* A COND_EXPR may have a throw as one operand, which
then has void type. Just leave void operands
as they are. */
- return build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
- VOID_TYPE_P (TREE_TYPE (arg1))
- ? arg1 : invert_truthvalue (arg1),
- VOID_TYPE_P (TREE_TYPE (arg2))
- ? arg2 : invert_truthvalue (arg2));
+ t = build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
+ VOID_TYPE_P (TREE_TYPE (arg1))
+ ? arg1 : invert_truthvalue (arg1),
+ VOID_TYPE_P (TREE_TYPE (arg2))
+ ? arg2 : invert_truthvalue (arg2));
+ break;
}
case COMPOUND_EXPR:
- return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case NON_LVALUE_EXPR:
return invert_truthvalue (TREE_OPERAND (arg, 0));
case NOP_EXPR:
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
- return build1 (TRUTH_NOT_EXPR, type, arg);
+ {
+ t = build1 (TRUTH_NOT_EXPR, type, arg);
+ break;
+ }
+
+ /* ... fall through ... */
case CONVERT_EXPR:
case FLOAT_EXPR:
- return build1 (TREE_CODE (arg), type,
- invert_truthvalue (TREE_OPERAND (arg, 0)));
+ t = build1 (TREE_CODE (arg), type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)));
+ break;
case BIT_AND_EXPR:
if (!integer_onep (TREE_OPERAND (arg, 1)))
- break;
- return build2 (EQ_EXPR, type, arg,
- build_int_cst (type, 0));
+ return NULL_TREE;
+ t = build2 (EQ_EXPR, type, arg, build_int_cst (type, 0));
+ break;
case SAVE_EXPR:
- return build1 (TRUTH_NOT_EXPR, type, arg);
+ t = build1 (TRUTH_NOT_EXPR, type, arg);
+ break;
case CLEANUP_POINT_EXPR:
- return build1 (CLEANUP_POINT_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)));
+ t = build1 (CLEANUP_POINT_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)));
+ break;
default:
+ t = NULL_TREE;
break;
}
- return NULL_TREE;
+ if (t && EXPR_HAS_LOCATION (arg))
+ SET_EXPR_LOCATION (t, EXPR_LOCATION (arg));
+
+ return t;
}
/* Return a simplified tree node for the truth-negation of ARG. This
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 515c58ed57e..993f7c2ae44 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2449,12 +2449,15 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
condition is true or false, respectively. If null, we should generate
our own to skip over the evaluation of this specific expression.
+ LOCUS is the source location of the COND_EXPR.
+
This function is the tree equivalent of do_jump.
shortcut_cond_r should only be called by shortcut_cond_expr. */
static tree
-shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
+shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
+ location_t locus)
{
tree local_label = NULL_TREE;
tree t, expr = NULL;
@@ -2464,6 +2467,8 @@ shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
shortcut_cond_expr will append the real blocks later. */
if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
{
+ location_t new_locus;
+
/* Turn if (a && b) into
if (a); else goto no;
@@ -2473,15 +2478,20 @@ shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
if (false_label_p == NULL)
false_label_p = &local_label;
- t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p);
+ /* Keep the original source location on the first 'if'. */
+ t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
append_to_statement_list (t, &expr);
- t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
- false_label_p);
+ /* Set the source location of the && on the second 'if'. */
+ new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
+ t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
+ new_locus);
append_to_statement_list (t, &expr);
}
else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
{
+ location_t new_locus;
+
/* Turn if (a || b) into
if (a) goto yes;
@@ -2491,31 +2501,41 @@ shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
if (true_label_p == NULL)
true_label_p = &local_label;
- t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL);
+ /* Keep the original source location on the first 'if'. */
+ t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
append_to_statement_list (t, &expr);
- t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
- false_label_p);
+ /* Set the source location of the || on the second 'if'. */
+ new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
+ t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
+ new_locus);
append_to_statement_list (t, &expr);
}
else if (TREE_CODE (pred) == COND_EXPR)
{
+ location_t new_locus;
+
/* As long as we're messing with gotos, turn if (a ? b : c) into
if (a)
if (b) goto yes; else goto no;
else
if (c) goto yes; else goto no; */
+
+ /* Keep the original source location on the first 'if'. Set the source
+ location of the ? on the second 'if'. */
+ new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
- false_label_p),
+ false_label_p, locus),
shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
- false_label_p));
+ false_label_p, new_locus));
}
else
{
expr = build3 (COND_EXPR, void_type_node, pred,
build_and_jump (true_label_p),
build_and_jump (false_label_p));
+ SET_EXPR_LOCATION (expr, locus);
}
if (local_label)
@@ -2547,14 +2567,24 @@ shortcut_cond_expr (tree expr)
/* First do simple transformations. */
if (!else_se)
{
- /* If there is no 'else', turn (a && b) into if (a) if (b). */
+ /* If there is no 'else', turn
+ if (a && b) then c
+ into
+ if (a) if (b) then c. */
while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
{
+ /* Keep the original source location on the first 'if'. */
+ location_t locus = EXPR_HAS_LOCATION (expr)
+ ? EXPR_LOCATION (expr) : input_location;
TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
+ /* Set the source location of the && on the second 'if'. */
+ if (EXPR_HAS_LOCATION (pred))
+ SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
then_ = shortcut_cond_expr (expr);
then_se = then_ && TREE_SIDE_EFFECTS (then_);
pred = TREE_OPERAND (pred, 0);
expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
+ SET_EXPR_LOCATION (expr, locus);
}
}
@@ -2566,11 +2596,18 @@ shortcut_cond_expr (tree expr)
if (a); else if (b); else d. */
while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
{
+ /* Keep the original source location on the first 'if'. */
+ location_t locus = EXPR_HAS_LOCATION (expr)
+ ? EXPR_LOCATION (expr) : input_location;
TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
+ /* Set the source location of the || on the second 'if'. */
+ if (EXPR_HAS_LOCATION (pred))
+ SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
else_ = shortcut_cond_expr (expr);
else_se = else_ && TREE_SIDE_EFFECTS (else_);
pred = TREE_OPERAND (pred, 0);
expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
+ SET_EXPR_LOCATION (expr, locus);
}
}
@@ -2624,17 +2661,19 @@ shortcut_cond_expr (tree expr)
/* If there was nothing else in our arms, just forward the label(s). */
if (!then_se && !else_se)
- return shortcut_cond_r (pred, true_label_p, false_label_p);
+ return shortcut_cond_r (pred, true_label_p, false_label_p,
+ EXPR_HAS_LOCATION (expr)
+ ? EXPR_LOCATION (expr) : input_location);
/* If our last subexpression already has a terminal label, reuse it. */
if (else_se)
- expr = expr_last (else_);
+ t = expr_last (else_);
else if (then_se)
- expr = expr_last (then_);
+ t = expr_last (then_);
else
- expr = NULL;
- if (expr && TREE_CODE (expr) == LABEL_EXPR)
- end_label = LABEL_EXPR_LABEL (expr);
+ t = NULL;
+ if (t && TREE_CODE (t) == LABEL_EXPR)
+ end_label = LABEL_EXPR_LABEL (t);
/* If we don't care about jumping to the 'else' branch, jump to the end
if the condition is false. */
@@ -2655,7 +2694,9 @@ shortcut_cond_expr (tree expr)
non-void function. */
jump_over_else = block_may_fallthru (then_);
- pred = shortcut_cond_r (pred, true_label_p, false_label_p);
+ pred = shortcut_cond_r (pred, true_label_p, false_label_p,
+ EXPR_HAS_LOCATION (expr)
+ ? EXPR_LOCATION (expr) : input_location);
expr = NULL;
append_to_statement_list (pred, &expr);
@@ -2665,7 +2706,10 @@ shortcut_cond_expr (tree expr)
{
if (jump_over_else)
{
+ tree last = expr_last (expr);
t = build_and_jump (&end_label);
+ if (EXPR_HAS_LOCATION (last))
+ SET_EXPR_LOCATION (t, EXPR_LOCATION (last));
append_to_statement_list (t, &expr);
}
if (emit_false)
@@ -4428,13 +4472,11 @@ gimplify_scalar_mode_aggregate_compare (tree *expr_p)
a && b ? true : false
- gimplify_cond_expr will do the rest.
-
- PRE_P points to the list where side effects that must happen before
- *EXPR_P should be stored. */
+ LOCUS is the source location to be put on the generated COND_EXPR.
+ gimplify_cond_expr will do the rest. */
static enum gimplify_status
-gimplify_boolean_expr (tree *expr_p)
+gimplify_boolean_expr (tree *expr_p, location_t locus)
{
/* Preserve the original type of the expression. */
tree type = TREE_TYPE (*expr_p);
@@ -4443,6 +4485,8 @@ gimplify_boolean_expr (tree *expr_p)
fold_convert (type, boolean_true_node),
fold_convert (type, boolean_false_node));
+ SET_EXPR_LOCATION (*expr_p, locus);
+
return GS_OK;
}
@@ -6430,7 +6474,8 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
- ret = gimplify_boolean_expr (expr_p);
+ /* Pass the source location of the outer expression. */
+ ret = gimplify_boolean_expr (expr_p, saved_location);
break;
case TRUTH_NOT_EXPR:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 066f4ea26c8..697da24fec6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-04-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/debug/dwarf2/short-circuit.c: New test.
+
2009-04-21 Richard Guenther <rguenther@suse.de>
PR middle-end/39829
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c b/gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c
new file mode 100644
index 00000000000..7e745ff19d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c
@@ -0,0 +1,108 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+
+#define True 1
+#define False 0
+
+_Bool F1 (_Bool B1, _Bool B2)
+{
+ _Bool R;
+
+ if (B1
+ && B2)
+ R = True;
+ else
+ R = False;
+ return R;
+}
+
+_Bool F2 (_Bool B1, _Bool B2)
+{
+ _Bool R;
+
+ R = B1
+ && B2;
+ return R;
+}
+
+_Bool F3 (_Bool B1, _Bool B2)
+{
+ _Bool R = False;
+
+ if (B1
+ && B2)
+ R = True;
+ return R;
+}
+
+_Bool F4 (_Bool B1, _Bool B2)
+{
+ _Bool R = False;
+
+ if (B1
+ || B2)
+ ;
+ else
+ R = True;
+ return R;
+}
+
+_Bool F5 (_Bool B1, _Bool B2)
+{
+ _Bool R = False;
+
+ if (!(B1
+ && B2))
+ R = True;
+ return R;
+}
+
+_Bool F8 (_Bool B1, _Bool B2, _Bool B3, _Bool B4, _Bool B5, _Bool B6,
+ _Bool B7, _Bool B8)
+{
+ _Bool R;
+
+ if ((B1
+ || B2)
+ && B3
+ && !(B4
+ || B5)
+ && (B6
+ || (B7
+ && B8)))
+ R = True;
+ else
+ R = False;
+ return R;
+}
+
+/* { dg-final { scan-assembler "short-circuit.c:11" } } */
+/* { dg-final { scan-assembler "short-circuit.c:12" } } */
+/* { dg-final { scan-assembler "short-circuit.c:13" } } */
+/* { dg-final { scan-assembler "short-circuit.c:15" } } */
+
+/* { dg-final { scan-assembler "short-circuit.c:23" } } */
+/* { dg-final { scan-assembler "short-circuit.c:24" } } */
+
+/* { dg-final { scan-assembler "short-circuit.c:32" } } */
+/* { dg-final { scan-assembler "short-circuit.c:33" } } */
+/* { dg-final { scan-assembler "short-circuit.c:34" } } */
+
+/* { dg-final { scan-assembler "short-circuit.c:42" } } */
+/* { dg-final { scan-assembler "short-circuit.c:43" } } */
+/* { dg-final { scan-assembler "short-circuit.c:46" } } */
+
+/* { dg-final { scan-assembler "short-circuit.c:54" } } */
+/* { dg-final { scan-assembler "short-circuit.c:55" } } */
+/* { dg-final { scan-assembler "short-circuit.c:56" } } */
+
+/* { dg-final { scan-assembler "short-circuit.c:65" } } */
+/* { dg-final { scan-assembler "short-circuit.c:66" } } */
+/* { dg-final { scan-assembler "short-circuit.c:67" } } */
+/* { dg-final { scan-assembler "short-circuit.c:68" } } */
+/* { dg-final { scan-assembler "short-circuit.c:69" } } */
+/* { dg-final { scan-assembler "short-circuit.c:70" } } */
+/* { dg-final { scan-assembler "short-circuit.c:71" } } */
+/* { dg-final { scan-assembler "short-circuit.c:72" } } */
+/* { dg-final { scan-assembler "short-circuit.c:73" } } */
+/* { dg-final { scan-assembler "short-circuit.c:75" } } */