From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id E14E2399E064; Fri, 4 Jun 2021 18:50:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E14E2399E064 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r10-9891] d: Fix ICE in gimplify_var_or_parm_decl, at gimplify.c:2755 (PR100882) X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/releases/gcc-10 X-Git-Oldrev: df45c5b83447a06e6b15c729807a17409c39ddff X-Git-Newrev: dcc5cf980af747941b32fd16c1d6a07177a1a404 Message-Id: <20210604185031.E14E2399E064@sourceware.org> Date: Fri, 4 Jun 2021 18:50:31 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Jun 2021 18:50:32 -0000 https://gcc.gnu.org/g:dcc5cf980af747941b32fd16c1d6a07177a1a404 commit r10-9891-gdcc5cf980af747941b32fd16c1d6a07177a1a404 Author: Iain Buclaw Date: Fri Jun 4 19:38:26 2021 +0200 d: Fix ICE in gimplify_var_or_parm_decl, at gimplify.c:2755 (PR100882) Constructor calls for temporaries were reusing the TARGET_EXPR_SLOT of a TARGET_EXPR for an assignment, which later got passed to `build_assign', which stripped away the outer TARGET_EXPR, leaving a reference to a lone temporary with no declaration. This stripping away of the TARGET_EXPR also discarded any cleanups that may have been assigned to the expression as well. So now the reuse of TARGET_EXPR_SLOT has been removed, and `build_assign' now constructs assignments inside the TARGET_EXPR_INITIAL slot. This has also been extended to `return_expr', to deal with possibility of a TARGET_EXPR being returned. gcc/d/ChangeLog: PR d/100882 * d-codegen.cc (build_assign): Construct initializations inside TARGET_EXPR_INITIAL. (compound_expr): Remove intermediate expressions that have no side-effects. (return_expr): Construct returns inside TARGET_EXPR_INITIAL. * expr.cc (ExprVisitor::visit (CallExp *)): Remove useless assignment to TARGET_EXPR_SLOT. gcc/testsuite/ChangeLog: PR d/100882 * gdc.dg/pr100882a.d: New test. * gdc.dg/pr100882b.d: New test. * gdc.dg/pr100882c.d: New test. * gdc.dg/pr100882d.d: New test. (cherry picked from commit e8761d4c21b5f4cc1c5612be9bf952a07c8a2238) Diff: --- gcc/d/d-codegen.cc | 36 ++++++++++++++++++++++++++++++------ gcc/d/expr.cc | 7 +------ gcc/testsuite/gdc.dg/pr100882a.d | 21 +++++++++++++++++++++ gcc/testsuite/gdc.dg/pr100882b.d | 35 +++++++++++++++++++++++++++++++++++ gcc/testsuite/gdc.dg/pr100882c.d | 19 +++++++++++++++++++ gcc/testsuite/gdc.dg/pr100882d.d | 25 +++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 12 deletions(-) diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 8042f03f369..54fee00eb5b 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -1269,6 +1269,7 @@ component_ref (tree object, tree field) tree build_assign (tree_code code, tree lhs, tree rhs) { + tree result; tree init = stabilize_expr (&lhs); init = compound_expr (init, stabilize_expr (&rhs)); @@ -1287,22 +1288,27 @@ build_assign (tree_code code, tree lhs, tree rhs) if (TREE_CODE (rhs) == TARGET_EXPR) { /* If CODE is not INIT_EXPR, can't initialize LHS directly, - since that would cause the LHS to be constructed twice. - So we force the TARGET_EXPR to be expanded without a target. */ + since that would cause the LHS to be constructed twice. */ if (code != INIT_EXPR) { init = compound_expr (init, rhs); - rhs = TARGET_EXPR_SLOT (rhs); + result = build_assign (code, lhs, TARGET_EXPR_SLOT (rhs)); } else { d_mark_addressable (lhs); - rhs = TARGET_EXPR_INITIAL (rhs); + TARGET_EXPR_INITIAL (rhs) = build_assign (code, lhs, + TARGET_EXPR_INITIAL (rhs)); + result = rhs; } } + else + { + /* Simple assignment. */ + result = fold_build2_loc (input_location, code, + TREE_TYPE (lhs), lhs, rhs); + } - tree result = fold_build2_loc (input_location, code, - TREE_TYPE (lhs), lhs, rhs); return compound_expr (init, result); } @@ -1424,6 +1430,11 @@ compound_expr (tree arg0, tree arg1) if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0)) return arg1; + /* Remove intermediate expressions that have no side-effects. */ + while (TREE_CODE (arg0) == COMPOUND_EXPR + && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1))) + arg0 = TREE_OPERAND (arg0, 0); + if (TREE_CODE (arg1) == TARGET_EXPR) { /* If the rhs is a TARGET_EXPR, then build the compound expression @@ -1444,6 +1455,19 @@ compound_expr (tree arg0, tree arg1) tree return_expr (tree ret) { + /* Same as build_assign, the DECL_RESULT assignment replaces the temporary + in TARGET_EXPR_SLOT. */ + if (ret != NULL_TREE && TREE_CODE (ret) == TARGET_EXPR) + { + tree exp = TARGET_EXPR_INITIAL (ret); + tree init = stabilize_expr (&exp); + + exp = fold_build1_loc (input_location, RETURN_EXPR, void_type_node, exp); + TARGET_EXPR_INITIAL (ret) = compound_expr (init, exp); + + return ret; + } + return fold_build1_loc (input_location, RETURN_EXPR, void_type_node, ret); } diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index ad2255e1cd1..2e70bf3a8e7 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -1870,15 +1870,10 @@ public: exp = d_convert (build_ctype (e->type), exp); /* If this call was found to be a constructor for a temporary with a - cleanup, then move the call inside the TARGET_EXPR. The original - initializer is turned into an assignment, to keep its side effect. */ + cleanup, then move the call inside the TARGET_EXPR. */ if (cleanup != NULL_TREE) { tree init = TARGET_EXPR_INITIAL (cleanup); - tree slot = TARGET_EXPR_SLOT (cleanup); - d_mark_addressable (slot); - init = build_assign (INIT_EXPR, slot, init); - TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp); exp = cleanup; } diff --git a/gcc/testsuite/gdc.dg/pr100882a.d b/gcc/testsuite/gdc.dg/pr100882a.d new file mode 100644 index 00000000000..d94baff97ac --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr100882a.d @@ -0,0 +1,21 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100882 +// { dg-additional-options "-fmain" } +// { dg-do run } + +__gshared int counter = 0; +struct S100882 +{ + this(int) { counter++; } + ~this() { counter++; } +} +static S100882 s; +static this() +{ + s = cast(shared) S100882(0); + assert(counter == 2); +} + +auto test100882() +{ + return cast(shared) S100882(0); +} diff --git a/gcc/testsuite/gdc.dg/pr100882b.d b/gcc/testsuite/gdc.dg/pr100882b.d new file mode 100644 index 00000000000..de92ab3bef1 --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr100882b.d @@ -0,0 +1,35 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100882 +// { dg-do compile } + +struct AllocatorList(Factory) +{ + Factory factory; + auto make(size_t n) { return factory(n); } + this(Factory plant) + { + factory = plant; + } +} + +struct Region +{ + ~this() + { + } +} + +auto mmapRegionList() +{ + struct Factory + { + this(size_t ) + { + } + auto opCall(size_t ) + { + return Region(); + } + } + auto shop = Factory(); + AllocatorList!Factory(shop); +} diff --git a/gcc/testsuite/gdc.dg/pr100882c.d b/gcc/testsuite/gdc.dg/pr100882c.d new file mode 100644 index 00000000000..deaa4b44a16 --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr100882c.d @@ -0,0 +1,19 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100882 +// { dg-do compile } + +auto iota(int, int) +{ + struct Result + { + this(int) + { + } + } + return Result(); +} + +auto iota(int end) +{ + int begin; + return iota(begin, end); +} diff --git a/gcc/testsuite/gdc.dg/pr100882d.d b/gcc/testsuite/gdc.dg/pr100882d.d new file mode 100644 index 00000000000..f4e6e4d3651 --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr100882d.d @@ -0,0 +1,25 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100882 +// { dg-do compile } + +struct CowArray +{ + this(this) + { + } +} + +struct Tuple +{ + CowArray expand; +} + +auto tuple(CowArray) +{ + return Tuple(); +} + +auto parseCharTerm() +{ + CowArray set; + return tuple(set); +}