]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c++/80129 (wrong code with ternary struct assignment to const)
authorJakub Jelinek <jakub@redhat.com>
Tue, 30 May 2017 08:17:18 +0000 (10:17 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 30 May 2017 08:17:18 +0000 (10:17 +0200)
Backported from mainline
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.

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

From-SVN: r248662

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

index 09a6a4bf9f74dd0e2f94e832879944dadbcfa26f..5ec64f66e44daf33e9c4889ff4119ce5b3ba2a73 100644 (file)
@@ -1,6 +1,12 @@
 2017-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       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.
+
        2017-03-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR sanitizer/79944
index b7aa11d67fcd851699486447b34f09ca070aef6c..052fc08aba77d32337f89cdb39b4c007e6386666 100644 (file)
@@ -4293,6 +4293,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 7f1612091ef3419ccc344bf38c53acafb72e6379..895f61037d20d831633dfa989b4babe44620568b 100644 (file)
@@ -1,6 +1,11 @@
 2017-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2017-03-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/80129
+       * g++.dg/torture/pr80129.C: New test.
+
        2017-03-21  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/80097
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 ();
+}