diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index e75348c2f..2d3fb6c40 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,8 @@ +2018-03-18 Iain Buclaw + + * d-codegen.cc (stabilize_expr): Move modify expression rewrite... + * expr.cc (ExprVisitor::binop_assignment): ... here. + 2018-03-11 Iain Buclaw * expr.cc (ExprVisitor::visit(StringExp)): Include null terminator diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index d0dc834b9..b7c746b93 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -541,15 +541,6 @@ stabilize_expr (tree *valuep) *valuep = rhs; return lhs; - case MODIFY_EXPR: - case INIT_EXPR: - /* Given e1 = e2: - Store the leftmost 'e1' expression in VALUEP. */ - lhs = TREE_OPERAND (expr, 0); - stabilize_expr (&lhs); - *valuep = lhs; - return expr; - default: return NULL_TREE; } diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 92d885628..eabc3bfd9 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -171,10 +171,18 @@ class ExprVisitor : public Visitor e1b = ce->e1; } - /* The LHS expression could be an assignment, to which it's operation gets - lost during gimplification. Stabilize lhs for assignment. */ + /* Stabilize LHS for assignment. */ tree lhs = build_expr (e1b); tree lexpr = stabilize_expr (&lhs); + + /* The LHS expression could be an assignment, to which it's operation gets + lost during gimplification. */ + if (TREE_CODE (lhs) == MODIFY_EXPR) + { + lexpr = compound_expr (lexpr, lhs); + lhs = TREE_OPERAND (lhs, 0); + } + lhs = stabilize_reference (lhs); /* Save RHS, to ensure that the expression is evaluated before LHS. */ diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d index 0a996046b..f9eaf8d8c 100644 --- a/gcc/testsuite/gdc.dg/runnable.d +++ b/gcc/testsuite/gdc.dg/runnable.d @@ -1547,6 +1547,44 @@ void test285() /******************************************/ +// Bug 286 + +void test286() +{ + struct K286 + { + int count; + this(this) + { + count++; + } + } + + struct S286 + { + int data; + this(K286 key) + { + data = key.count; + } + } + + S286 getData(K286 key) + { + static S286[K286] getCache; + auto p = key in getCache; + if (p) + return *p; + return (getCache[key] = S286(key)); + } + + auto s = getData(K286()); + if (s.data == 0) + assert(0); +} + +/******************************************/ + void main() { test2(); @@ -1581,6 +1619,7 @@ void main() test250(); test273(); test285(); + test286(); printf("Success!\n"); }