c-common.c (verify_sequence_points): Export.
authorRichard Henderson <rth@redhat.com>
Mon, 21 Jun 2004 09:15:29 +0000 (02:15 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 21 Jun 2004 09:15:29 +0000 (02:15 -0700)
        * c-common.c (verify_sequence_points): Export.
        (c_expand_expr_stmt): Move to c-typeck.c.
        * c-common.h (c_expand_expr_stmt): Remove.
        (verify_sequence_points): Declare.
        * c-mudflap.c (mflang_flush_calls): Use c_finish_expr_stmt.
        * c-parse.in (for_init_stmt, stmt): Likewise.
        * c-tree.h (c_finish_expr_stmt): Declare.
        (c_tree_expr_nonnegative_p): Remove.
        * c-typeck.c (c_tree_expr_nonnegative_p): Remove.
        (build_conditional_expr, build_binary_op): Use tree_expr_nonnegative_p.
        (emit_side_effect_warnings): New.
        (c_finish_expr_stmt): Rename from c_expand_expr_stmt.  Use it.
        (c_finish_stmt_expr): Work without EXPR_STMT.  Handle eh regions.
        Use emit_side_effect_warnings.
        (push_cleanup): Copy STATEMENT_LIST_STMT_EXPR.
        * fold-const.c (tree_expr_nonnegative_p): Handle TARGET_EXPR.
        * gimplify.c (gimplify_modify_expr): Don't discard TARGET_EXPR
        with void initializer.
        (gimplify_target_expr): Handle void BIND_EXPR initializer.
        * tree-inline.c (estimate_num_insns_1): Fix type lookup for
        INIT_EXPR and MODIFY_EXPR.
        * objc/objc-act.c (build_module_descriptor): Use add_stmt
        instead of c_expand_expr_stmt.
cp/
        * semantics.c (finish_expr_stmt): Call verify_sequence_points.
testsuite/
        * gcc.dg/tree-ssa/20030714-1.c: Rename variables to avoid
        merging && to BIT_FIELD_REF.

From-SVN: r83429

15 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-mudflap.c
gcc/c-parse.in
gcc/c-tree.h
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/fold-const.c
gcc/gimplify.c
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c
gcc/tree-inline.c

index e2d9993f9e0ee1c7f02717989a2802e7d1f8d0f0..77f8f98e00c188a3bee92f418ae354a246eee91e 100644 (file)
@@ -1,3 +1,29 @@
+2004-06-21  Richard Henderson  <rth@redhat.com>
+
+       * c-common.c (verify_sequence_points): Export.
+       (c_expand_expr_stmt): Move to c-typeck.c.
+       * c-common.h (c_expand_expr_stmt): Remove.
+       (verify_sequence_points): Declare.
+       * c-mudflap.c (mflang_flush_calls): Use c_finish_expr_stmt.
+       * c-parse.in (for_init_stmt, stmt): Likewise.
+       * c-tree.h (c_finish_expr_stmt): Declare.
+       (c_tree_expr_nonnegative_p): Remove.
+       * c-typeck.c (c_tree_expr_nonnegative_p): Remove.
+       (build_conditional_expr, build_binary_op): Use tree_expr_nonnegative_p.
+       (emit_side_effect_warnings): New.
+       (c_finish_expr_stmt): Rename from c_expand_expr_stmt.  Use it.
+       (c_finish_stmt_expr): Work without EXPR_STMT.  Handle eh regions.
+       Use emit_side_effect_warnings.
+       (push_cleanup): Copy STATEMENT_LIST_STMT_EXPR.
+       * fold-const.c (tree_expr_nonnegative_p): Handle TARGET_EXPR.
+       * gimplify.c (gimplify_modify_expr): Don't discard TARGET_EXPR
+       with void initializer.
+       (gimplify_target_expr): Handle void BIND_EXPR initializer.
+       * tree-inline.c (estimate_num_insns_1): Fix type lookup for
+       INIT_EXPR and MODIFY_EXPR.
+       * objc/objc-act.c (build_module_descriptor): Use add_stmt
+       instead of c_expand_expr_stmt.
+
 2004-06-21  Paolo Bonzini  <bonzini@gnu.org>
 
        * fold-const.c (fold_cond_expr_with_comparison):
index a982852482d10dbf30f52bfb551e5efac381bc83..79d9d9ac85970e9e68c60471fec9aa950d0b3aac 100644 (file)
@@ -1247,7 +1247,6 @@ static int warning_candidate_p (tree);
 static void warn_for_collisions (struct tlist *);
 static void warn_for_collisions_1 (tree, tree, struct tlist *, int);
 static struct tlist *new_tlist (struct tlist *, tree, tree);
-static void verify_sequence_points (tree);
 
 /* Create a new struct tlist and fill in its fields.  */
 static struct tlist *
@@ -1586,7 +1585,7 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp,
 /* Try to warn for undefined behavior in EXPR due to missing sequence
    points.  */
 
-static void
+void
 verify_sequence_points (tree expr)
 {
   struct tlist *before_sp = 0, *after_sp = 0;
@@ -1603,32 +1602,6 @@ verify_sequence_points (tree expr)
   warn_for_collisions (after_sp);
   obstack_free (&tlist_obstack, tlist_firstobj);
 }
-
-tree
-c_expand_expr_stmt (tree expr)
-{
-  /* Do default conversion if safe and possibly important,
-     in case within ({...}).  */
-  if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
-       && (flag_isoc99 || lvalue_p (expr)))
-      || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)
-    expr = default_conversion (expr);
-
-  if (warn_sequence_point)
-    verify_sequence_points (expr);
-
-  if (TREE_TYPE (expr) != error_mark_node
-      && !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr))
-      && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
-    error ("expression statement has incomplete type");
-
-  /* As tempting as it might be, we can't diagnose statement with no
-     effect yet.  We have to wait until after statement expressions
-     have been parsed, and that process modifies the trees we are
-     creating here.  */
-
-  return add_stmt (build_stmt (EXPR_STMT, expr));
-}
 \f
 /* Validate the expression after `case' and apply default promotions.  */
 
index f8d087b8dbd8f334dc42e2abb58ec214e8ef1bfd..27733aa7c5c3bba40c812cbe73b0b8287acb4dfc 100644 (file)
@@ -859,7 +859,6 @@ extern void binary_op_error (enum tree_code);
 #define my_friendly_assert(EXP, N) (void) \
  (((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
 
-extern tree c_expand_expr_stmt (tree);
 /* Validate the expression after `case' and apply default promotions.  */
 extern tree check_case_value (tree);
 extern tree fix_string_type (tree);
@@ -1097,6 +1096,8 @@ extern tree c_walk_subtrees (tree*, int*, walk_tree_fn, void*, void*);
 
 extern void c_warn_unused_result (tree *);
 
+extern void verify_sequence_points (tree);
+
 /* In c-gimplify.c  */
 extern void c_genericize (tree);
 extern int c_gimplify_expr (tree *, tree *, tree *);
index 78523e960a07df5ab9193a60d848a9b2cf23a836..af1ade9b2dea4b427cc427d2e915186bc57ccafd 100644 (file)
@@ -85,7 +85,7 @@ mflang_flush_calls (tree enqueued_call_stmt_chain)
   mf_mark (current_function_decl);
 
   cs = c_begin_compound_stmt (true);
-  c_expand_expr_stmt (enqueued_call_stmt_chain);
+  c_finish_expr_stmt (enqueued_call_stmt_chain);
   add_stmt (c_end_compound_stmt (cs, true));
 
   finish_function ();
index 176e97a7281c3765531f2754b1c5fa02623207db..ce8829a0321d85a17220778eadf254c3e63996ae 100644 (file)
@@ -2210,7 +2210,7 @@ select_or_iter_stmt:
 
 for_init_stmt:
          xexpr ';'
-               { add_stmt (build_stmt (EXPR_STMT, $1)); }
+               { c_finish_expr_stmt ($1); }
        | decl
                { check_for_loop_decls (); }
        ;
@@ -2226,7 +2226,7 @@ stmt:
          compstmt
                { stmt_count++; add_stmt ($1); }
        | expr ';'
-               { stmt_count++; c_expand_expr_stmt ($1); }
+               { stmt_count++; c_finish_expr_stmt ($1); }
        | c99_block_start select_or_iter_stmt
                 { add_stmt (c_end_compound_stmt ($1, flag_isoc99)); }
        | BREAK ';'
index 92a5b7144784abb0b95734e2dda568e9dd1a36e1..03d84dd6672c4356b13bbf49659ca9c020642148 100644 (file)
@@ -227,7 +227,6 @@ extern tree build_indirect_ref (tree, const char *);
 extern tree build_array_ref (tree, tree);
 extern tree build_external_ref (tree, int);
 extern tree parser_build_binary_op (enum tree_code, tree, tree);
-extern int c_tree_expr_nonnegative_p (tree);
 extern void readonly_error (tree, const char *);
 extern tree build_conditional_expr (tree, tree, tree);
 extern tree build_compound_expr (tree);
@@ -272,6 +271,7 @@ extern void c_finish_for_stmt_incr (tree, tree);
 extern void c_finish_for_stmt (tree, tree);
 extern tree c_begin_stmt_expr (void);
 extern tree c_finish_stmt_expr (tree);
+extern void c_finish_expr_stmt (tree);
 extern tree build_offsetof (tree, tree);
 
 /* Set to 0 at beginning of a function definition, set to 1 if
index 99bb78d7c1d75fb8fbe07f203d6483f78db16209..91423dda0c778687384c3e8a59128dab8f5aba56 100644 (file)
@@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "ggc.h"
 #include "target.h"
 #include "tree-iterator.h"
+#include "tree-gimple.h"
 
 
 /* Nonzero if we've already printed a "missing braces around initializer"
@@ -2201,17 +2202,6 @@ parser_build_binary_op (enum tree_code code, tree arg1, tree arg2)
   return result;
 }
 \f
-
-/* Return true if `t' is known to be non-negative.  */
-
-int
-c_tree_expr_nonnegative_p (tree t)
-{
-  if (TREE_CODE (t) == STMT_EXPR)
-    t = expr_last (STMT_EXPR_STMT (t));
-  return tree_expr_nonnegative_p (t);
-}
-
 /* Return a tree for the difference of pointers OP0 and OP1.
    The resulting tree has type int.  */
 
@@ -2810,8 +2800,8 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
              /* Do not warn if the signed quantity is an unsuffixed
                 integer literal (or some static constant expression
                 involving such literals) and it is non-negative.  */
-             else if ((unsigned_op2 && c_tree_expr_nonnegative_p (op1))
-                      || (unsigned_op1 && c_tree_expr_nonnegative_p (op2)))
+             else if ((unsigned_op2 && tree_expr_nonnegative_p (op1))
+                      || (unsigned_op1 && tree_expr_nonnegative_p (op2)))
                /* OK */;
              else
                warning ("signed and unsigned type in conditional expression");
@@ -6657,7 +6647,61 @@ c_finish_for_stmt (tree body, tree for_stmt)
   FOR_BODY (for_stmt) = body;
 }
 \f
-/* Create a statement expression.  */
+/* A helper routine for c_finish_expr_stmt and c_finish_stmt_expr.  */
+
+static void
+emit_side_effect_warnings (tree expr)
+{
+  if (!TREE_SIDE_EFFECTS (expr))
+    {
+      if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr))
+       warning ("%Hstatement with no effect",
+                EXPR_LOCUS (expr) ? EXPR_LOCUS (expr) : &input_location);
+    }
+  else if (warn_unused_value)
+    warn_if_unused_value (expr, input_location);
+}
+
+/* Emit an expression as a statement.  */
+
+void
+c_finish_expr_stmt (tree expr)
+{
+  if (!expr)
+    return;
+
+  /* Do default conversion if safe and possibly important,
+     in case within ({...}).  */
+  if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
+       && (flag_isoc99 || lvalue_p (expr)))
+      || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)
+    expr = default_conversion (expr);
+
+  if (warn_sequence_point)
+    verify_sequence_points (expr);
+
+  if (TREE_TYPE (expr) != error_mark_node
+      && !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr))
+      && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
+    error ("expression statement has incomplete type");
+
+  /* If we're not processing a statement expression, warn about unused values.
+     Warnings for statement expressions will be emitted later, once we figure
+     out which is the result.  */
+  if (!STATEMENT_LIST_STMT_EXPR (cur_stmt_list)
+      && (extra_warnings || warn_unused_value))
+    emit_side_effect_warnings (expr);
+
+  /* If the expression is not of a type to which we cannot assign a line
+     number, wrap the thing in a no-op NOP_EXPR.  */
+  if (DECL_P (expr) || TREE_CODE_CLASS (TREE_CODE (expr)) == 'c')
+    expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
+
+  add_stmt (expr);
+}
+
+/* Do the opposite and emit a statement as an expression.  To begin,
+   create a new binding level and return it.  */
 
 tree
 c_begin_stmt_expr (void)
@@ -6679,63 +6723,77 @@ c_begin_stmt_expr (void)
 tree
 c_finish_stmt_expr (tree body)
 {
-  tree ret, last, type;
+  tree last, type, tmp, val;
   tree *last_p;
 
   body = c_end_compound_stmt (body, true);
 
-  /* Locate the last statement in BODY.  */
-  last = body, last_p = &body;
-  if (TREE_CODE (last) == BIND_EXPR)
-    {
-      last_p = &BIND_EXPR_BODY (last);
-      last = BIND_EXPR_BODY (last);
-    }
+  /* Locate the last statement in BODY.  See c_end_compound_stmt
+     about always returning a BIND_EXPR.  */
+  last_p = &BIND_EXPR_BODY (body);
+  last = BIND_EXPR_BODY (body);
+
+ continue_searching:
   if (TREE_CODE (last) == STATEMENT_LIST)
     {
-      tree_stmt_iterator i = tsi_last (last);
-      if (tsi_end_p (i))
+      tree_stmt_iterator i;
+
+      /* This can happen with degenerate cases like ({ }).  No value.  */
+      if (!TREE_SIDE_EFFECTS (last))
+       return body;
+
+      /* If we're supposed to generate side effects warnings, process
+        all of the statements except the last.  */
+      if (extra_warnings || warn_unused_value)
        {
-         type = void_type_node;
-         /* ??? Warn */
-         goto no_expr;
+         for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i))
+           emit_side_effect_warnings (tsi_stmt (i));
        }
       else
-       {
-         last_p = tsi_stmt_ptr (i);
-         last = *last_p;
-       }
+       i = tsi_last (last);
+      last_p = tsi_stmt_ptr (i);
+      last = *last_p;
     }
 
-  /* If the last statement is an EXPR_STMT, then unwrap it.  Otherwise
-     voidify_wrapper_expr will stuff it inside a MODIFY_EXPR and we'll
-     fail gimplification.  */
-  /* ??? Should we go ahead and perform voidify_wrapper_expr here?
-     We've got about all the information we need here.  All we'd have
-     to do even for proper type safety is to create, in effect,
-       ( ({ ...; tmp = last; }), tmp )
-     I.e. a COMPOUND_EXPR with the rhs being the compiler temporary.
-     Not going to try this now, since it's not clear what should
-     happen (wrt bindings) with new temporaries at this stage.  It's
-     easier once we begin gimplification.  */
-  if (TREE_CODE (last) == EXPR_STMT)
-    *last_p = last = EXPR_STMT_EXPR (last);
+  /* If the end of the list is exception related, then the list was split
+     by a call to push_cleanup.  Continue searching.  */
+  if (TREE_CODE (last) == TRY_FINALLY_EXPR
+      || TREE_CODE (last) == TRY_CATCH_EXPR)
+    {
+      last_p = &TREE_OPERAND (last, 0);
+      last = *last_p;
+      goto continue_searching;
+    }
+
+  /* In the case that the BIND_EXPR is not necessary, return the
+     expression out from inside it.  */
+  if (last == BIND_EXPR_BODY (body) && BIND_EXPR_VARS (body) == NULL)
+    return last;
 
   /* Extract the type of said expression.  */
   type = TREE_TYPE (last);
-  if (!type)
-    type = void_type_node;
-
- no_expr:
-  /* If what's left is compound, make sure we've got a BIND_EXPR, and
-     that it has the proper type.  */
-  ret = body;
-  if (TREE_CODE (ret) == STATEMENT_LIST)
-    ret = build (BIND_EXPR, type, NULL, ret, NULL);
-  else if (TREE_CODE (ret) == BIND_EXPR)
-    TREE_TYPE (ret) = type;
 
-  return ret;
+  /* If we're not returning a value at all, then the BIND_EXPR that
+     we already have is a fine expression to return.  */
+  if (!type || VOID_TYPE_P (type))
+    return body;
+
+  /* Now that we've located the expression containing the value, it seems
+     silly to make voidify_wrapper_expr repeat the process.  Create a
+     temporary of the appropriate type and stick it in a TARGET_EXPR.  */
+  tmp = create_tmp_var_raw (type, NULL);
+
+  /* Unwrap a no-op NOP_EXPR as added by c_finish_expr_stmt.  This avoids
+     tree_expr_nonnegative_p giving up immediately.  */
+  val = last;
+  if (TREE_CODE (val) == NOP_EXPR
+      && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0)))
+    val = TREE_OPERAND (val, 0);
+
+  *last_p = build (MODIFY_EXPR, void_type_node, tmp, val);
+  SET_EXPR_LOCUS (*last_p, EXPR_LOCUS (last));
+
+  return build (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE);
 }
 \f
 /* Begin and end compound statements.  This is as simple as pushing
@@ -6791,10 +6849,17 @@ c_end_compound_stmt (tree stmt, bool do_scope)
 void
 push_cleanup (tree decl ATTRIBUTE_UNUSED, tree cleanup, bool eh_only)
 {
-  enum tree_code code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR;
-  tree stmt = build_stmt (code, NULL, cleanup);
+  enum tree_code code;
+  tree stmt, list;
+  bool stmt_expr;
+
+  code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR;
+  stmt = build_stmt (code, NULL, cleanup);
   add_stmt (stmt);
-  TREE_OPERAND (stmt, 0) = push_stmt_list ();
+  stmt_expr = STATEMENT_LIST_STMT_EXPR (cur_stmt_list);
+  list = push_stmt_list ();
+  TREE_OPERAND (stmt, 0) = list;
+  STATEMENT_LIST_STMT_EXPR (list) = stmt_expr;
 }
 \f
 /* Build a binary-operation expression without default conversions.
@@ -7412,7 +7477,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
                     constant expression involving such literals or a
                     conditional expression involving such literals)
                     and it is non-negative.  */
-                 if (c_tree_expr_nonnegative_p (sop))
+                 if (tree_expr_nonnegative_p (sop))
                    /* OK */;
                  /* Do not warn if the comparison is an equality operation,
                     the unsigned quantity is an integral constant, and it
index 4ec0ee6d18c438ece0ab12b65fb1f2b2f1a46a8d..679289af87375e21be650d7d01dae53b1ff9adc1 100644 (file)
@@ -1,3 +1,7 @@
+2004-06-21  Richard Henderson  <rth@redhat.com>
+
+       * semantics.c (finish_expr_stmt): Call verify_sequence_points.
+
 2004-06-20  Richard Henderson  <rth@redhat.com>
 
        * cp-tree.h (add_decl_stmt): Declare.
index 92efe443a6d514fbff97674397f68f368ab45bee..826ac688a761715173c08817aea6c01a52830222 100644 (file)
@@ -493,7 +493,11 @@ finish_expr_stmt (tree expr)
   if (expr != NULL_TREE)
     {
       if (!processing_template_decl)
-       expr = convert_to_void (expr, "statement");
+       {
+         if (warn_sequence_point)
+           verify_sequence_points (expr);
+         expr = convert_to_void (expr, "statement");
+       }
       else if (!type_dependent_expression_p (expr))
        convert_to_void (build_non_dependent_expr (expr), "statement");
 
index 220d1af95ac1b49da136c929335a6892c97a97d9..517d5508b954007b0624786bf88a65ba2a4d2805 100644 (file)
@@ -9267,6 +9267,37 @@ tree_expr_nonnegative_p (tree t)
     case RTL_EXPR:
       return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
 
+    case TARGET_EXPR:
+      {
+       tree temp = TARGET_EXPR_SLOT (t);
+       t = TARGET_EXPR_INITIAL (t);
+
+       /* If the initializer is non-void, then it's a normal expression
+          that will be assigned to the slot.  */
+       if (!VOID_TYPE_P (t))
+         return tree_expr_nonnegative_p (t);
+
+       /* Otherwise, the initializer sets the slot in some way.  One common
+          way is an assignment statement at the end of the initializer.  */
+       while (1)
+         {
+           if (TREE_CODE (t) == BIND_EXPR)
+             t = expr_last (BIND_EXPR_BODY (t));
+           else if (TREE_CODE (t) == TRY_FINALLY_EXPR
+                    || TREE_CODE (t) == TRY_CATCH_EXPR)
+             t = expr_last (TREE_OPERAND (t, 0));
+           else if (TREE_CODE (t) == STATEMENT_LIST)
+             t = expr_last (t);
+           else
+             break;
+         }
+       if (TREE_CODE (t) == MODIFY_EXPR
+           && TREE_OPERAND (t, 0) == temp)
+         return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+
+       return 0;
+      }
+
     case CALL_EXPR:
       {
        tree fndecl = get_callee_fndecl (t);
index 92c52a9365b9191733c6fcfa274a80b3d8c2b53b..f6e4a04bf9bfe67bc6ef1481b47c0c2627ec475e 100644 (file)
@@ -2472,13 +2472,19 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
     return ret;
 
   /* If we are initializing something from a TARGET_EXPR, strip the
-     TARGET_EXPR and initialize it directly.  */
+     TARGET_EXPR and initialize it directly, if possible.  This can't
+     be done if the initializer is void, since that implies that the
+     temporary is set in some non-trivial way.  */
   /* What about code that pulls out the temp and uses it elsewhere?  I
      think that such code never uses the TARGET_EXPR as an initializer.  If
      I'm wrong, we'll abort because the temp won't have any RTL.  In that
      case, I guess we'll need to replace references somehow.  */
   if (TREE_CODE (*from_p) == TARGET_EXPR)
-    *from_p = TARGET_EXPR_INITIAL (*from_p);
+    {
+      tree init = TARGET_EXPR_INITIAL (*from_p);
+      if (!VOID_TYPE_P (TREE_TYPE (init)))
+        *from_p = init;
+    }
 
   /* If we're assigning from a ?: expression with ADDRESSABLE type, push
      the assignment down into the branches, since we can't generate a
@@ -3021,22 +3027,29 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
 
   if (init)
     {
-      /* TARGET_EXPR temps aren't part of the enclosing block, so add it to the
-        temps list.  */
+      /* TARGET_EXPR temps aren't part of the enclosing block, so add it
+        to the temps list.  */
       gimple_add_tmp_var (temp);
 
-      /* Build up the initialization and add it to pre_p.  Special handling
-        for BIND_EXPR can result in fewer temporaries created.  */
-      if (TREE_CODE (init) == BIND_EXPR)
-       gimplify_bind_expr (&init, temp, pre_p);
-      if (init != temp)
+      /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
+        expression is supposed to initialize the slot.  */
+      if (VOID_TYPE_P (TREE_TYPE (init)))
+       ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
+      else
        {
-         if (! VOID_TYPE_P (TREE_TYPE (init)))
-           init = build (MODIFY_EXPR, void_type_node, temp, init);
-         ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
-         if (ret == GS_ERROR)
-           return GS_ERROR;
+          /* Special handling for BIND_EXPR can result in fewer temps.  */
+         ret = GS_OK;
+          if (TREE_CODE (init) == BIND_EXPR)
+           gimplify_bind_expr (&init, temp, pre_p);
+          if (init != temp)
+           {
+             init = build (MODIFY_EXPR, void_type_node, temp, init);
+             ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt,
+                                  fb_none);
+           }
        }
+      if (ret == GS_ERROR)
+       return GS_ERROR;
       append_to_statement_list (init, pre_p);
 
       /* If needed, push the cleanup for the temp.  */
index 8176bd97d2a03c0b645732c9ddac2677c999e8fb..4414309ca7d51cf72c5ba3c0ac181b81c0355d58 100644 (file)
@@ -1918,7 +1918,7 @@ build_module_descriptor (void)
                         build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
     decelerator = build_function_call (execclass_decl, parms);
 
-    c_expand_expr_stmt (decelerator);
+    add_stmt (decelerator);
     add_stmt (c_end_compound_stmt (compound, true));
 
     finish_function ();
index de97d53f6b8274672b1cab1c7bb7d2d7bfed0454..d9f579e2968d3ba3f79e27de5f89b541b2d06d95 100644 (file)
@@ -1,3 +1,8 @@
+2004-06-21  Richard Henderson  <rth@redhat.com>
+
+       * gcc.dg/tree-ssa/20030714-1.c: Rename variables to avoid
+       merging && to BIT_FIELD_REF.
+
 2004-06-21  Richard Sandiford  <rsandifo@redhat.com>
 
        * g++.dg/opt/placeholder1.C: New test.
index 63823f71059ed095971c8b35b0c6a4a2c38d316e..1caa22ab53586c593c703886bb940c1bdb82e98d 100644 (file)
@@ -19,12 +19,12 @@ find_base_value (src)
      rtx src;
 {
   rtx temp;
-  rtx src_0;
-  rtx src_1;
+  rtx src_0, src_2;
+  rtx src_1, src_3;
 
-  if ((src_0->code == REG) && (({src_0;})->frame_related))
+  if ((src_0->code == REG) && (({src_2;})->frame_related))
     return find_base_value (src_0);
-  if ((src_1->code == REG) && (({ src_1;})->frame_related))
+  if ((src_1->code == REG) && (({ src_3;})->frame_related))
     return find_base_value (src_1);
   if (src_0->code == REG)
     find_base_value (src_0);
@@ -41,4 +41,3 @@ find_base_value (src)
 
 /* There should be three loads of ->code.  */
 /* { dg-final { scan-tree-dump-times "->code" 3 "dom3"} } */
-                                                                                
index d5ceac6d6c6f926fd44ebaccae81b76a9d4e1d45..24bf3d1b2ff3e82cdd0b938d31effb239d5daea5 100644 (file)
@@ -1251,11 +1251,14 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
     case STRING_CST:
       *walk_subtrees = 0;
       return NULL;
+
     /* Recognize assignments of large structures and constructors of
        big arrays.  */
     case INIT_EXPR:
-    case TARGET_EXPR:
     case MODIFY_EXPR:
+      x = TREE_OPERAND (x, 0);
+      /* FALLTHRU */
+    case TARGET_EXPR:
     case CONSTRUCTOR:
       {
        HOST_WIDE_INT size;