re PR c++/16277 (Wrong code with conditionals in initializers)
authorRichard Henderson <rth@redhat.com>
Fri, 23 Jul 2004 22:48:14 +0000 (15:48 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 23 Jul 2004 22:48:14 +0000 (15:48 -0700)
        PR c++/16277
        * gimplify.c (gimplify_cond_expr): Gimplify TARGET to a min_lval;
        unshare it properly.
        (gimplify_modify_expr_rhs): Push assignment from a conditional into
        the conditional for all non-register types.

From-SVN: r85100

gcc/ChangeLog
gcc/gimplify.c

index f14f45b5587500fe85a0ac14f1a25c65183d615d..5a563915de05895a19113261e356ad545cdde184 100644 (file)
@@ -1,3 +1,11 @@
+2004-07-23  Richard Henderson  <rth@redhat.com>
+
+       PR c++/16277
+       * gimplify.c (gimplify_cond_expr): Gimplify TARGET to a min_lval;
+       unshare it properly.
+       (gimplify_modify_expr_rhs): Push assignment from a conditional into
+       the conditional for all non-register types.
+
 2004-07-23  Richard Henderson  <rth@redhat.com>
 
        * expr.c (expand_expr_real_1): Don't handle non-local variables.
index f0785035ea0ae03bba9e7298b05b13bcc3dda2c8..fcbab025053a1bc0091fbae3290e0449ba16cc43 100644 (file)
@@ -2191,7 +2191,7 @@ static enum gimplify_status
 gimplify_cond_expr (tree *expr_p, tree *pre_p, tree target)
 {
   tree expr = *expr_p;
-  tree tmp, type;
+  tree tmp, tmp2, type;
   enum gimplify_status ret;
 
   type = TREE_TYPE (expr);
@@ -2204,12 +2204,16 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, tree target)
     {
       if (target)
        {
+         ret = gimplify_expr (&target, pre_p, NULL,
+                              is_gimple_min_lval, fb_lvalue);
+         if (ret != GS_ERROR)
+           ret = GS_OK;
          tmp = target;
-         ret = GS_OK;
+         tmp2 = unshare_expr (target);
        }
       else
        {
-         tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
+         tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
          ret = GS_ALL_DONE;
        }
 
@@ -2222,15 +2226,15 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, tree target)
       /* Build the else clause, 't1 = b;'.  */
       if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
        TREE_OPERAND (expr, 2)
-         = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 2));
+         = build (MODIFY_EXPR, void_type_node, tmp2, TREE_OPERAND (expr, 2));
 
       TREE_TYPE (expr) = void_type_node;
       recalculate_side_effects (expr);
 
-      /* Move the COND_EXPR to the prequeue and use the temp in its place.  */
+      /* Move the COND_EXPR to the prequeue.  */
       gimplify_and_add (expr, pre_p);
-      *expr_p = tmp;
 
+      *expr_p = tmp;
       return ret;
     }
 
@@ -2689,10 +2693,11 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
        return gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
 
       case COND_EXPR:
-       /* If we're assigning from a ?: expression with ADDRESSABLE type, push
-          the assignment down into the branches, since we can't generate a
-          temporary of such a type.  */
-       if (TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
+       /* If we're assigning to a non-register type, push the assignment
+          down into the branches.  This is mandatory for ADDRESSABLE types,
+          since we cannot generate temporaries for such, but it saves a 
+          copy in other cases as well.  */
+       if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
          {
            *expr_p = *from_p;
            return gimplify_cond_expr (expr_p, pre_p, *to_p);