Skip to content
This repository has been archived by the owner on Jun 20, 2019. It is now read-only.

Commit

Permalink
Merge pull request #252 from ibuclaw/issue235
Browse files Browse the repository at this point in the history
Bug 235: Fix ICE with array slice assign.
  • Loading branch information
jpf91 authored Oct 29, 2016
2 parents ae520df + 6fadc54 commit 30764bd
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
13 changes: 13 additions & 0 deletions gcc/d/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
2016-10-27 Iain Buclaw <ibuclaw@gdcproject.org>

* expr.cc (ExprVisitor::visit(AssignExp)): Don't set TREE_ADDRESSABLE.
* d-codegen.cc (build_assign): Handle setting up INIT_EXPR from a
value returning via NRVO here instead.

2016-10-26 Iain Buclaw <ibuclaw@gdcproject.org>

* d-codegen.cc (d_build_call): Only convert CALL_EXPRs into a
TARGET_EXPR if return type is TREE_ADDRESSABLE.
(build_assign): Use TARGET_EXPR accessors.
(compound_expr): Likewise.

2016-10-15 Iain Buclaw <ibuclaw@gdcproject.org>

* d-codegen.h (d_types_same): Return early if types are identical.
Expand Down
28 changes: 22 additions & 6 deletions gcc/d/d-codegen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2315,16 +2315,30 @@ build_assign(tree_code code, tree lhs, tree rhs)
tree init = stabilize_expr(&lhs);
init = compound_expr(init, stabilize_expr(&rhs));

// The LHS assignment is replaces the temporary in TARGET_EXPR_SLOT.
// If initializing the LHS using a function that returns via NRVO.
if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
&& AGGREGATE_TYPE_P (TREE_TYPE (rhs))
&& aggregate_value_p (TREE_TYPE (rhs), rhs))
{
// Mark as addressable here, which should ensure the return slot is the
// address of the LHS expression, taken care of by back-end.
d_mark_addressable (lhs);
CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;
}

// The LHS assignment replaces the temporary in TARGET_EXPR_SLOT.
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.
if (code != INIT_EXPR)
rhs = compound_expr(rhs, TREE_OPERAND (rhs, 0));
rhs = compound_expr(rhs, TARGET_EXPR_SLOT (rhs));
else
rhs = TARGET_EXPR_INITIAL (rhs);
{
d_mark_addressable (lhs);
rhs = TARGET_EXPR_INITIAL (rhs);
}
}

tree result = fold_build2_loc(input_location, code,
Expand Down Expand Up @@ -2437,8 +2451,8 @@ compound_expr(tree arg0, tree arg1)
// If the rhs is a TARGET_EXPR, then build the compound expression
// inside the target_expr's initializer. This helps the compiler
// to eliminate unnecessary temporaries.
tree init = compound_expr(arg0, TREE_OPERAND (arg1, 1));
TREE_OPERAND (arg1, 1) = init;
tree init = compound_expr(arg0, TARGET_EXPR_INITIAL (arg1));
TARGET_EXPR_INITIAL (arg1) = init;

return arg1;
}
Expand Down Expand Up @@ -3079,9 +3093,11 @@ d_build_call(TypeFunction *tf, tree callable, tree object, Expressions *argument
tree result = d_build_call_list(TREE_TYPE (ctype), callee, arg_list);
result = expand_intrinsic(result);

// Return the value in a temporary slot so that it can be evaluated
// multiple times by the caller.
if (TREE_CODE (result) == CALL_EXPR
&& AGGREGATE_TYPE_P (TREE_TYPE (result))
&& aggregate_value_p(TREE_TYPE (result), result))
&& TREE_ADDRESSABLE (TREE_TYPE (result)))
{
CALL_EXPR_RETURN_SLOT_OPT (result) = true;
result = build_target_expr(result);
Expand Down
6 changes: 0 additions & 6 deletions gcc/d/expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -992,9 +992,6 @@ class ExprVisitor : public Visitor
tree t2 = convert_for_assignment(build_expr(e->e2),
e->e2->type, e->e1->type);

if (e->op == TOKconstruct && e->e2->op == TOKcall)
d_mark_addressable(t1);

if (e->e2->op == TOKint64)
{
// Use memset to fill struct.
Expand Down Expand Up @@ -1047,9 +1044,6 @@ class ExprVisitor : public Visitor
tree t2 = convert_for_assignment(build_expr(e->e2),
e->e2->type, e->e1->type);

if (e->op == TOKconstruct && e->e2->op == TOKcall)
d_mark_addressable(t1);

this->result_ = build_assign(modifycode, t1, t2);
}
else if (e->op == TOKconstruct)
Expand Down

0 comments on commit 30764bd

Please sign in to comment.