OSDN Git Service

PR c++/45437
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 9 Jul 2011 03:33:54 +0000 (03:33 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 9 Jul 2011 03:33:54 +0000 (03:33 +0000)
gcc/
* gimplify.c (goa_stabilize_expr): Handle RHS preevaluation in
compound assignment.
gcc/c-family/
* c-omp.c (check_omp_for_incr_expr): Handle preevaluation.
gcc/cp/
* typeck.c (cp_build_modify_expr): Preevaluate RHS.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@176072 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-omp.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/compound-asn1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/sequence-pt-1.C

index c2d866d..9bf2942 100644 (file)
@@ -1,5 +1,9 @@
 2011-07-08  Jason Merrill  <jason@redhat.com>
 
+       PR c++/45437
+       * gimplify.c (goa_stabilize_expr): Handle RHS preevaluation in
+       compound assignment.
+
        * cgraph.c (cgraph_add_to_same_comdat_group): New.
        * cgraph.h: Declare it.
        * ipa.c (function_and_variable_visibility): Make sure thunks
index 72a118a..87930c2 100644 (file)
@@ -1,5 +1,8 @@
 2011-07-08  Jason Merrill  <jason@redhat.com>
 
+       PR c++/45437
+       * c-omp.c (check_omp_for_incr_expr): Handle preevaluation.
+
        PR c++/49673
        * c-common.c (c_apply_type_quals_to_decl): Don't check
        TYPE_NEEDS_CONSTRUCTING.
index 1ee0bf0..d2256ff 100644 (file)
@@ -213,6 +213,27 @@ check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
         return fold_build2_loc (loc, PLUS_EXPR,
                            TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
       break;
+    case COMPOUND_EXPR:
+      {
+       /* cp_build_modify_expr forces preevaluation of the RHS to make
+          sure that it is evaluated before the lvalue-rvalue conversion
+          is applied to the LHS.  Reconstruct the original expression.  */
+       tree op0 = TREE_OPERAND (exp, 0);
+       if (TREE_CODE (op0) == TARGET_EXPR
+           && !VOID_TYPE_P (TREE_TYPE (op0)))
+         {
+           tree op1 = TREE_OPERAND (exp, 1);
+           tree temp = TARGET_EXPR_SLOT (op0);
+           if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary
+               && TREE_OPERAND (op1, 1) == temp)
+             {
+               op1 = copy_node (op1);
+               TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
+               return check_omp_for_incr_expr (loc, op1, decl);
+             }
+         }
+       break;
+      }
     default:
       break;
     }
index 3f776b0..cbdc4d8 100644 (file)
@@ -1,5 +1,8 @@
 2011-07-08  Jason Merrill  <jason@redhat.com>
 
+       PR c++/45437
+       * typeck.c (cp_build_modify_expr): Preevaluate RHS.
+
        * method.c (use_thunk): Use cgraph_add_to_same_comdat_group.
        * optimize.c (maybe_clone_body): Likewise.
        * semantics.c (maybe_add_lambda_conv_op): Likewise.
index 5febff5..d87c107 100644 (file)
@@ -6663,6 +6663,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
        }
       else
        {
+         tree init = NULL_TREE;
+
          /* A binary op has been requested.  Combine the old LHS
             value with the RHS producing the value we should actually
             store into the LHS.  */
@@ -6670,7 +6672,17 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
                         && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
                        || MAYBE_CLASS_TYPE_P (lhstype)));
 
+         /* Preevaluate the RHS to make sure its evaluation is complete
+            before the lvalue-to-rvalue conversion of the LHS:
+
+            [expr.ass] With respect to an indeterminately-sequenced
+            function call, the operation of a compound assignment is a
+            single evaluation. [ Note: Therefore, a function call shall
+            not intervene between the lvalue-to-rvalue conversion and the
+            side effect associated with any single compound assignment
+            operator. -- end note ]  */
          lhs = stabilize_reference (lhs);
+         rhs = stabilize_expr (rhs, &init);
          newrhs = cp_build_binary_op (input_location,
                                       modifycode, lhs, rhs,
                                       complain);
@@ -6682,6 +6694,9 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
              return error_mark_node;
            }
 
+         if (init)
+           newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
+
          /* Now it looks like a plain assignment.  */
          modifycode = NOP_EXPR;
          if (c_dialect_objc ())
index 4ff7e93..5a928be 100644 (file)
@@ -6451,6 +6451,13 @@ goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
          saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
                                         lhs_addr, lhs_var);
          break;
+       case COMPOUND_EXPR:
+         /* Break out any preevaluations from cp_build_modify_expr.  */
+         for (; TREE_CODE (expr) == COMPOUND_EXPR;
+              expr = TREE_OPERAND (expr, 1))
+           gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
+         *expr_p = expr;
+         return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
        default:
          break;
        }
index fc6931a..5b8be33 100644 (file)
@@ -1,3 +1,9 @@
+2011-07-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/45437
+       * g++.dg/expr/compound-asn1.C: New.
+       * g++.dg/warn/sequence-pt-1.C: Change one dg-error to dg-bogus.
+
 2011-07-08  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/49621
diff --git a/gcc/testsuite/g++.dg/expr/compound-asn1.C b/gcc/testsuite/g++.dg/expr/compound-asn1.C
new file mode 100644 (file)
index 0000000..194235c
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/45437
+// { dg-options -Wsequence-point }
+// { dg-do run }
+
+bool f(bool& b) {
+  b = true;
+  return false;
+}
+
+int main() {
+  bool b = false;
+  b |= f(b);
+  if (!b)
+    return 1;
+}
index 05eee82..6a98fd7 100644 (file)
@@ -62,7 +62,7 @@ foo (int a, int b, int n, int p, int *ptr, struct s *sptr,
   (a = a++) && b; /* { dg-warning "undefined" "sequence point warning" } */
   b, (a = a++); /* { dg-warning "undefined" "sequence point warning" } */
   (a = a++), b; /* { dg-warning "undefined" "sequence point warning" } */
-  a ^= b ^= a ^= b; /* { dg-warning "undefined" "sequence point warning" } */
+  a ^= b ^= a ^= b; /* { dg-bogus "undefined" "sequence point warning" } */
 
   a = a; /* { dg-bogus "undefined" "bogus sequence point warning" } */
   a = (a++ && 4); /* { dg-bogus "undefined" "bogus sequence point warning" } */