]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c++/84961 (ICE error: SSA_NAME_DEF_STMT is wrong)
authorJakub Jelinek <jakub@redhat.com>
Fri, 22 Jun 2018 20:54:44 +0000 (22:54 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 22 Jun 2018 20:54:44 +0000 (22:54 +0200)
Backported from mainline
2018-03-21  Jakub Jelinek  <jakub@redhat.com>

PR c++/84961
* cp-tree.h (genericize_compound_lvalue): Declare.
* typeck.c (genericize_compound_lvalue): New function.
(unary_complex_lvalue, cp_build_modify_expr): Use it.
* semantics.c (finish_asm_stmt): Replace MODIFY_EXPR, PREINCREMENT_EXPR
and PREDECREMENT_EXPR in output and "m" constrained input operands with
COMPOUND_EXPR.  Call cxx_mark_addressable on the rightmost
COMPOUND_EXPR operand.

* c-c++-common/pr43690.c: Don't expect errors on "m" (--x) and
"m" (++x) in C++.
* g++.dg/torture/pr84961-1.C: New test.
* g++.dg/torture/pr84961-2.C: New test.

From-SVN: r261933

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr43690.c
gcc/testsuite/g++.dg/torture/pr84961-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/pr84961-2.C [new file with mode: 0644]

index 163969d74d8e90c879c899b223b90cbed722aa45..59d20325138a7fc45c64fac933d9c6acc0ff5938 100644 (file)
@@ -1,6 +1,17 @@
 2018-06-22  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2018-03-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/84961
+       * cp-tree.h (genericize_compound_lvalue): Declare.
+       * typeck.c (genericize_compound_lvalue): New function.
+       (unary_complex_lvalue, cp_build_modify_expr): Use it.
+       * semantics.c (finish_asm_stmt): Replace MODIFY_EXPR, PREINCREMENT_EXPR
+       and PREDECREMENT_EXPR in output and "m" constrained input operands with
+       COMPOUND_EXPR.  Call cxx_mark_addressable on the rightmost
+       COMPOUND_EXPR operand.
+
        2018-03-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/84874
index 8251f85eded3c3b63ede465aac15b11e1dda90d9..25d404bc609c58f179d511ca5a90809860591156 100644 (file)
@@ -6778,6 +6778,7 @@ extern tree cp_build_addressof                    (location_t, tree,
 extern tree cp_build_addr_expr                 (tree, tsubst_flags_t);
 extern tree cp_build_unary_op                   (enum tree_code, tree, bool,
                                                  tsubst_flags_t);
+extern tree genericize_compound_lvalue         (tree);
 extern tree unary_complex_lvalue               (enum tree_code, tree);
 extern tree build_x_conditional_expr           (location_t, tree, tree, tree, 
                                                  tsubst_flags_t);
index 481c88b07288df718b016dcf4e07c159f987c197..d8c4f011526ca4223fff3fa03d30a62c52f095a4 100644 (file)
@@ -1483,6 +1483,21 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
                      && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
            cxx_readonly_error (operand, lv_asm);
 
+         tree *op = &operand;
+         while (TREE_CODE (*op) == COMPOUND_EXPR)
+           op = &TREE_OPERAND (*op, 1);
+         switch (TREE_CODE (*op))
+           {
+           case PREINCREMENT_EXPR:
+           case PREDECREMENT_EXPR:
+           case MODIFY_EXPR:
+             *op = genericize_compound_lvalue (*op);
+             op = &TREE_OPERAND (*op, 1);
+             break;
+           default:
+             break;
+           }
+
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
          oconstraints[i] = constraint;
 
@@ -1491,7 +1506,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
            {
              /* If the operand is going to end up in memory,
                 mark it addressable.  */
-             if (!allows_reg && !cxx_mark_addressable (operand))
+             if (!allows_reg && !cxx_mark_addressable (*op))
                operand = error_mark_node;
            }
          else
@@ -1533,7 +1548,23 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
                  /* Strip the nops as we allow this case.  FIXME, this really
                     should be rejected or made deprecated.  */
                  STRIP_NOPS (operand);
-                 if (!cxx_mark_addressable (operand))
+
+                 tree *op = &operand;
+                 while (TREE_CODE (*op) == COMPOUND_EXPR)
+                   op = &TREE_OPERAND (*op, 1);
+                 switch (TREE_CODE (*op))
+                   {
+                   case PREINCREMENT_EXPR:
+                   case PREDECREMENT_EXPR:
+                   case MODIFY_EXPR:
+                     *op = genericize_compound_lvalue (*op);
+                     op = &TREE_OPERAND (*op, 1);
+                     break;
+                   default:
+                     break;
+                   }
+
+                 if (!cxx_mark_addressable (*op))
                    operand = error_mark_node;
                }
              else if (!allows_reg && !allows_mem)
index 9d7c9aa27d0490dfb1b7ffef1663f50b9c0abe36..68a4c25a434d1c1bb32b4064ac86d349af15573b 100644 (file)
@@ -6177,6 +6177,25 @@ build_unary_op (location_t /*location*/,
   return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
 }
 
+/* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR,
+   so that it is a valid lvalue even for GENERIC by replacing
+   (lhs = rhs) with ((lhs = rhs), lhs)
+   (--lhs) with ((--lhs), lhs)
+   (++lhs) with ((++lhs), lhs)
+   and if lhs has side-effects, calling cp_stabilize_reference on it, so
+   that it can be evaluated multiple times.  */
+
+tree
+genericize_compound_lvalue (tree lvalue)
+{
+  if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
+    lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
+                    cp_stabilize_reference (TREE_OPERAND (lvalue, 0)),
+                    TREE_OPERAND (lvalue, 1));
+  return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)),
+                lvalue, TREE_OPERAND (lvalue, 0));
+}
+
 /* Apply unary lvalue-demanding operator CODE to the expression ARG
    for certain kinds of expressions which are not really lvalues
    but which we can accept as lvalues.
@@ -6211,17 +6230,7 @@ unary_complex_lvalue (enum tree_code code, tree arg)
   if (TREE_CODE (arg) == MODIFY_EXPR
       || TREE_CODE (arg) == PREINCREMENT_EXPR
       || TREE_CODE (arg) == PREDECREMENT_EXPR)
-    {
-      tree lvalue = TREE_OPERAND (arg, 0);
-      if (TREE_SIDE_EFFECTS (lvalue))
-       {
-         lvalue = cp_stabilize_reference (lvalue);
-         arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
-                       lvalue, TREE_OPERAND (arg, 1));
-       }
-      return unary_complex_lvalue
-       (code, build2 (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
-    }
+    return unary_complex_lvalue (code, genericize_compound_lvalue (arg));
 
   if (code != ADDR_EXPR)
     return NULL_TREE;
@@ -7617,11 +7626,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
     case PREINCREMENT_EXPR:
       if (compound_side_effects_p)
        newrhs = rhs = stabilize_expr (rhs, &preeval);
-      if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
-       lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
-                     cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
-                     TREE_OPERAND (lhs, 1));
-      lhs = build2 (COMPOUND_EXPR, lhstype, lhs, TREE_OPERAND (lhs, 0));
+      lhs = genericize_compound_lvalue (lhs);
     maybe_add_compound:
       /* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5;
         and looked through the COMPOUND_EXPRs, readd them now around
@@ -7644,11 +7649,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
     case MODIFY_EXPR:
       if (compound_side_effects_p)
        newrhs = rhs = stabilize_expr (rhs, &preeval);
-      if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
-       lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
-                     cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
-                     TREE_OPERAND (lhs, 1));
-      lhs = build2 (COMPOUND_EXPR, lhstype, lhs, TREE_OPERAND (lhs, 0));
+      lhs = genericize_compound_lvalue (lhs);
       goto maybe_add_compound;
 
     case MIN_EXPR:
index 93b4acee0f3e696f965f2bc090e34fae763dbdc1..bfe4de9a591a4e2d3774f9c387c2f32b2776d56e 100644 (file)
@@ -1,6 +1,14 @@
 2018-06-22  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2018-03-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/84961
+       * c-c++-common/pr43690.c: Don't expect errors on "m" (--x) and
+       "m" (++x) in C++.
+       * g++.dg/torture/pr84961-1.C: New test.
+       * g++.dg/torture/pr84961-2.C: New test.
+
        2018-03-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/84875
index 67c6cb0f88cd059c640c3db7a7128c737591aad2..8d10744903f28ed4d9916d201fca1778755d5f93 100644 (file)
@@ -6,8 +6,8 @@ void
 foo (char *x)
 {
   asm ("" : : "m" (x++));      /* { dg-error "is not directly addressable" } */
-  asm ("" : : "m" (++x));      /* { dg-error "is not directly addressable" } */
+  asm ("" : : "m" (++x));      /* { dg-error "is not directly addressable" "" { target c } } */
   asm ("" : : "m" (x--));      /* { dg-error "is not directly addressable" } */
-  asm ("" : : "m" (--x));      /* { dg-error "is not directly addressable" } */
+  asm ("" : : "m" (--x));      /* { dg-error "is not directly addressable" "" { target c } } */
   asm ("" : : "m" (x + 1));    /* { dg-error "is not directly addressable" } */
 }
diff --git a/gcc/testsuite/g++.dg/torture/pr84961-1.C b/gcc/testsuite/g++.dg/torture/pr84961-1.C
new file mode 100644 (file)
index 0000000..6a72ad5
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/84961
+// { dg-do compile }
+
+short a;
+volatile int b;
+int c, d;
+
+void
+foo ()
+{
+  asm volatile ("" : "=r" (b = a));
+}
+
+void
+bar ()
+{
+  asm volatile ("" : "=r" (++c, ++d, b = a));
+}
+
+void
+baz ()
+{
+  asm volatile ("" : "=r" (--b));
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr84961-2.C b/gcc/testsuite/g++.dg/torture/pr84961-2.C
new file mode 100644 (file)
index 0000000..0909eed
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/84961
+// { dg-do compile }
+
+short a;
+volatile int b;
+int c, d;
+
+void
+foo ()
+{
+  asm volatile ("" : : "m" (b = a));
+}
+
+void
+bar ()
+{
+  asm volatile ("" : : "m" (++c, ++d, b = a));
+}
+
+void
+baz ()
+{
+  asm volatile ("" : : "m" (--b));
+}