aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-05-10 10:19:44 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-05-10 10:19:44 +0200
commitb5cbaee240380ba1a3a48fad3810409dea32b888 (patch)
treeb139f71ecf5589c0f08d1eb5288164013361f0d1 /gcc
parent0a52429609a9570149af903c231c25f17da79b15 (diff)
downloadgcc-b5cbaee240380ba1a3a48fad3810409dea32b888.zip
gcc-b5cbaee240380ba1a3a48fad3810409dea32b888.tar.gz
gcc-b5cbaee240380ba1a3a48fad3810409dea32b888.tar.bz2
re PR c++/90383 (GCC generates invalid constexpr copy/move assignment operators for types with trailing padding. (Again))
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: r271058
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C22
-rw-r--r--gcc/tree-inline.c12
-rw-r--r--gcc/tree-inline.h3
6 files changed, 62 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5e30430..d1b9123 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+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-10 Martin Liska <mliska@suse.cz>
* config/i386/i386-expand.c (ix86_expand_floorceildf_32):
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 889c08d..0ca0b5a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2019-05-10 Paul Thomas <pault@gcc.gnu.org>
PR fortran/90093
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
index 0000000..b398331
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C
@@ -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
index 0000000..a08b1dd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C
@@ -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 ();
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 2d314a7..35c005e 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1101,7 +1101,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.
@@ -1327,11 +1327,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);
@@ -1360,7 +1360,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.
@@ -1432,7 +1432,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))
@@ -6370,6 +6371,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;
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index 4c954a0..3ede89e 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -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;