re PR c++/80129 (wrong code with ternary struct assignment to const)
authorJakub Jelinek <jakub@redhat.com>
Wed, 22 Mar 2017 18:45:48 +0000 (19:45 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 22 Mar 2017 18:45:48 +0000 (19:45 +0100)
PR c++/80129
* gimplify.c (gimplify_modify_expr_rhs) <case COND_EXPR>: Clear
TREE_READONLY on result if writing it more than once.

* g++.dg/torture/pr80129.C: New test.

From-SVN: r246401

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr80129.C [new file with mode: 0644]

index a1e007f118db8e09ce8fe195ad56ed6c02e24b5a..5259dce80a509b98afa9c695b96a614798897e46 100644 (file)
@@ -1,5 +1,9 @@
 2017-03-22  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/80129
+       * gimplify.c (gimplify_modify_expr_rhs) <case COND_EXPR>: Clear
+       TREE_READONLY on result if writing it more than once.
+
        PR sanitizer/80110
        * doc/invoke.texi (-fsanitize=thread): Document that with
        -fnon-call-exceptions atomics are not able to throw
index 5658d0a2f0bbec0c33ba0b8a0259855e698e190a..f90ae94bc6960b25e0018bc2bb68a3a5a06adfcb 100644 (file)
@@ -5098,6 +5098,14 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
              if (ret != GS_ERROR)
                ret = GS_OK;
 
+             /* If we are going to write RESULT more than once, clear
+                TREE_READONLY flag, otherwise we might incorrectly promote
+                the variable to static const and initialize it at compile
+                time in one of the branches.  */
+             if (VAR_P (result)
+                 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
+                 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
+               TREE_READONLY (result) = 0;
              if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
                TREE_OPERAND (cond, 1)
                  = build2 (code, void_type_node, result,
index d8b45dcacf667f692bf3fc65d4cebd0661df20d9..add3a14eca52c728239546fef1fab4583f294b30 100644 (file)
@@ -1,5 +1,8 @@
 2017-03-22  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/80129
+       * g++.dg/torture/pr80129.C: New test.
+
        PR sanitizer/80110
        * g++.dg/tsan/pr80110.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/torture/pr80129.C b/gcc/testsuite/g++.dg/torture/pr80129.C
new file mode 100644 (file)
index 0000000..134293c
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/80129
+// { dg-do run }
+// { dg-options "-std=c++11" }
+
+struct A { bool a; int b; };
+
+int
+main ()
+{
+  bool c = false;
+  const A x = c ? A {true, 1} : A {false, 0};
+  if (x.a)
+    __builtin_abort ();
+}