diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-05-10 10:19:44 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-05-10 10:19:44 +0200 |
commit | b5cbaee240380ba1a3a48fad3810409dea32b888 (patch) | |
tree | b139f71ecf5589c0f08d1eb5288164013361f0d1 /gcc | |
parent | 0a52429609a9570149af903c231c25f17da79b15 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C | 22 | ||||
-rw-r--r-- | gcc/tree-inline.c | 12 | ||||
-rw-r--r-- | gcc/tree-inline.h | 3 |
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; |