public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8512] d: Fix ICE in gimplify_var_or_parm_decl, at gimplify.c:2755 (PR100882)
@ 2021-06-04 18:50 Iain Buclaw
0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2021-06-04 18:50 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:83f932f23cae74344ec9e67c76faf2f014857992
commit r11-8512-g83f932f23cae74344ec9e67c76faf2f014857992
Author: Iain Buclaw <ibuclaw@gdcproject.org>
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/torture/pr100882.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 | 35 ++++++++++++++++++++++++++++++++
gcc/testsuite/gdc.dg/pr100882b.d | 19 +++++++++++++++++
gcc/testsuite/gdc.dg/pr100882c.d | 25 +++++++++++++++++++++++
gcc/testsuite/gdc.dg/torture/pr100882.d | 21 +++++++++++++++++++
6 files changed, 131 insertions(+), 12 deletions(-)
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 5fa1acd9240..9a9447371aa 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -1330,6 +1330,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));
@@ -1348,22 +1349,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);
}
@@ -1485,6 +1491,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
@@ -1505,6 +1516,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 aad7cbbf947..e76cae98f7e 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -1894,15 +1894,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..de92ab3bef1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr100882a.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/pr100882b.d b/gcc/testsuite/gdc.dg/pr100882b.d
new file mode 100644
index 00000000000..deaa4b44a16
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr100882b.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/pr100882c.d b/gcc/testsuite/gdc.dg/pr100882c.d
new file mode 100644
index 00000000000..f4e6e4d3651
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr100882c.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);
+}
diff --git a/gcc/testsuite/gdc.dg/torture/pr100882.d b/gcc/testsuite/gdc.dg/torture/pr100882.d
new file mode 100644
index 00000000000..d94baff97ac
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr100882.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);
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-06-04 18:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-04 18:50 [gcc r11-8512] d: Fix ICE in gimplify_var_or_parm_decl, at gimplify.c:2755 (PR100882) Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).