]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c++/90383 (GCC generates invalid constexpr copy/move assignment opera...
authorJakub Jelinek <jakub@redhat.com>
Fri, 17 May 2019 19:50:52 +0000 (21:50 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 17 May 2019 19:50:52 +0000 (21:50 +0200)
Backported from mainline
2019-05-10  Jakub Jelinek  <jakub@redhat.com>

PR c++/90383
* tree-inline.h (struct copy_body_data): Add do_not_fold member.
* tree-inline.c (remap_gimple_op_r): Avoid folding expressions if
id->do_not_fold.
(copy_tree_body_r): Likewise.
(copy_fn): Set id.do_not_fold to true.

* g++.dg/cpp1y/constexpr-90383-1.C: New test.
* g++.dg/cpp1y/constexpr-90383-2.C: New test.

From-SVN: r271351

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C [new file with mode: 0644]
gcc/tree-inline.c
gcc/tree-inline.h

index d3c8c5e4e94dbe575920197fbc43008647b9944d..843c03aa8744aa9daad86af0c6ce768052d021f8 100644 (file)
@@ -1,6 +1,15 @@
 2019-05-17  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-05-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/90383
+       * tree-inline.h (struct copy_body_data): Add do_not_fold member.
+       * tree-inline.c (remap_gimple_op_r): Avoid folding expressions if
+       id->do_not_fold.
+       (copy_tree_body_r): Likewise.
+       (copy_fn): Set id.do_not_fold to true.
+
        2019-05-03  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/90303
index 05ca071e31af47ecf8428cfe09fff7610d7347ea..170106fe24af7e291586ac761f62ee5be5f9a901 100644 (file)
@@ -3,6 +3,10 @@
        Backported from mainline
        2019-05-10  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/90383
+       * g++.dg/cpp1y/constexpr-90383-1.C: New test.
+       * g++.dg/cpp1y/constexpr-90383-2.C: New test.
+
        PR pch/90326
        * g++.dg/pch/pr90326.C: New test.
        * g++.dg/pch/pr90326.Hs: New file.
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C
new file mode 100644 (file)
index 0000000..b398331
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/90383
+// { dg-do compile { target c++14 } }
+
+struct alignas(8) A { constexpr A (bool x) : a(x) {} A () = delete; bool a; };
+struct B { A b; };
+
+constexpr bool
+foo ()
+{
+  B w{A (true)};
+  w.b = A (true);
+  return w.b.a;
+}
+
+static_assert (foo (), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C
new file mode 100644 (file)
index 0000000..a08b1dd
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/90383
+// { dg-do run { target c++14 } }
+// { dg-options "-O2" }
+
+extern "C" void abort ();
+struct alignas(8) A { constexpr A (bool x) : a(x) {} A () = default; bool a; };
+struct B { A b; };
+
+constexpr bool
+foo ()
+{
+  B w{A (true)};
+  w.b = A (true);
+  return w.b.a;
+}
+
+int
+main ()
+{
+  if (!foo ())
+    abort ();
+}
index 9bf1c4080f50417149077c7f6691e4a349333f94..7b62ff8a566e6fbec83d46c4eab732473f57ed2e 100644 (file)
@@ -1100,7 +1100,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
       /* Otherwise, just copy the node.  Note that copy_tree_r already
         knows not to copy VAR_DECLs, etc., so this is safe.  */
 
-      if (TREE_CODE (*tp) == MEM_REF)
+      if (TREE_CODE (*tp) == MEM_REF && !id->do_not_fold)
        {
          /* We need to re-canonicalize MEM_REFs from inline substitutions
             that can happen when a pointer argument is an ADDR_EXPR.
@@ -1326,11 +1326,11 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
              tree type = TREE_TYPE (*tp);
              tree ptr = id->do_not_unshare ? *n : unshare_expr (*n);
              tree old = *tp;
-             *tp = gimple_fold_indirect_ref (ptr);
+             *tp = id->do_not_fold ? NULL : gimple_fold_indirect_ref (ptr);
              if (! *tp)
                {
                  type = remap_type (type, id);
-                 if (TREE_CODE (ptr) == ADDR_EXPR)
+                 if (TREE_CODE (ptr) == ADDR_EXPR && !id->do_not_fold)
                    {
                      *tp
                        = fold_indirect_ref_1 (EXPR_LOCATION (ptr), type, ptr);
@@ -1359,7 +1359,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
              return NULL;
            }
        }
-      else if (TREE_CODE (*tp) == MEM_REF)
+      else if (TREE_CODE (*tp) == MEM_REF && !id->do_not_fold)
        {
          /* We need to re-canonicalize MEM_REFs from inline substitutions
             that can happen when a pointer argument is an ADDR_EXPR.
@@ -1431,7 +1431,8 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
 
          /* Handle the case where we substituted an INDIRECT_REF
             into the operand of the ADDR_EXPR.  */
-         if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
+         if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF
+             && !id->do_not_fold)
            {
              tree t = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
              if (TREE_TYPE (t) != TREE_TYPE (*tp))
@@ -6323,6 +6324,7 @@ copy_fn (tree fn, tree& parms, tree& result)
      since front-end specific mechanisms may rely on sharing.  */
   id.regimplify = false;
   id.do_not_unshare = true;
+  id.do_not_fold = true;
 
   /* We're not inside any EH region.  */
   id.eh_lp_nr = 0;
index 9e3c249ba9688815a88f55062ae41a2e3cbc98b3..f90fabb33cc6c5f4431d63866830a7e6ad0a993d 100644 (file)
@@ -113,6 +113,9 @@ struct copy_body_data
   /* True if trees may not be unshared.  */
   bool do_not_unshare;
 
+  /* True if trees should not be folded during the copying.  */
+  bool do_not_fold;
+
   /* True if new declarations may not be created during type remapping.  */
   bool prevent_decl_creation_for_types;