]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-common.c (c_common_truthvalue_conversion): Use LOCATION to build NE_EXPR operations...
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 21 Apr 2009 17:17:13 +0000 (17:17 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 21 Apr 2009 17:17:13 +0000 (17:17 +0000)
* 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.
ada/
* gcc-interface/trans.c (gnat_to_gnu): Do not overwrite location info.

From-SVN: r146532

gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c
gcc/c-common.c
gcc/c-parser.c
gcc/c-typeck.c
gcc/fold-const.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c [new file with mode: 0644]

index f59688e0fe733fee36d6a0d82f98c671cb89e441..3c622f75512ad054e126b6e1a9b6075322b59bd0 100644 (file)
@@ -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
index a8e01f0eae766de979bf9b545bffec15af21fef1..6f31dbd3e3d29b729e844a4c478466e2ee390dd0 100644 (file)
@@ -1,3 +1,7 @@
+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.
index 50e3fca20e19aadd2c667f641c8c7ff9712b0c19..84aa3963910a080cd20982d84d7ecfa3e7437b98 100644 (file)
@@ -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
index eab4582b8e08de3dd8b7716e558013fdf243ea91..3595e552966f0f20e709a5dc514cdd12611edd05 100644 (file)
@@ -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);
 }
 \f
 static void def_builtin_1  (enum built_in_function fncode,
index ca51d95eed50ea5c8dd1a3821e216d70d8bad25b..676c709cdf2f179a3c7c142c35808fbd76ad8949 100644 (file)
@@ -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;
index f5cfc6440d382f5f1f53cb1ff8fbe84cbc5fa455..1ff6e9b744d62cf7c9805ab524008f0ee70a4c6c 100644 (file)
@@ -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:
index bd5e97df4a92b622ae27c6620ee500b197ecf6d1..ca07cf16720427edfad48c1e39044ede0fccbdc9 100644 (file)
@@ -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
index 515c58ed57e9ead1a1dcd66f262daa2d7bb08116..993f7c2ae449bb698d4172c8cf0c3b1591e27dd6 100644 (file)
@@ -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:
index 066f4ea26c83b835d6227b3b1f77e9012502c868..697da24fec6904e06dbfb80f7e5247f143965fa3 100644 (file)
@@ -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 (file)
index 0000000..7e745ff
--- /dev/null
@@ -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" } } */