From: Jakub Jelinek Date: Fri, 17 May 2019 19:50:52 +0000 (+0200) Subject: backport: re PR c++/90383 (GCC generates invalid constexpr copy/move assignment opera... X-Git-Tag: releases/gcc-9.2.0~354 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=97088068826bc5eb09211a6681012e1b8477fd78;p=thirdparty%2Fgcc.git backport: re PR c++/90383 (GCC generates invalid constexpr copy/move assignment operators for types with trailing padding. (Again)) Backported from mainline 2019-05-10 Jakub Jelinek 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d3c8c5e4e94d..843c03aa8744 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,15 @@ 2019-05-17 Jakub Jelinek Backported from mainline + 2019-05-10 Jakub Jelinek + + 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 PR tree-optimization/90303 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 05ca071e31af..170106fe24af 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,10 @@ Backported from mainline 2019-05-10 Jakub Jelinek + 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 index 000000000000..b398331ad7dc --- /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 000000000000..a08b1dd6f442 --- /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 9bf1c4080f50..7b62ff8a566e 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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; diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h index 9e3c249ba968..f90fabb33cc6 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;