diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 1f2d65c4ae2..4c16f6a822b 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -1343,7 +1343,10 @@ build_assign (tree_code code, tree lhs, tree rhs) 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, TARGET_EXPR_SLOT (rhs)); + { + init = compound_expr (init, rhs); + rhs = TARGET_EXPR_SLOT (rhs); + } else { d_mark_addressable (lhs); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 79f212c3a08..ef2bf5f2e36 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -884,6 +884,9 @@ public: tree t2 = build_expr (e->e2); tree expr = stabilize_expr (&t2); + if (TREE_CODE (t2) == CALL_EXPR) + t2 = force_target_expr (t2); + result = modify_expr (build_deref (ptrexp), t2); this->result_ = compound_expr (expr, result); diff --git a/gcc/testsuite/gdc.dg/torture/pr97843.d b/gcc/testsuite/gdc.dg/torture/pr97843.d new file mode 100644 index 00000000000..1a417b32359 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/pr97843.d @@ -0,0 +1,37 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97843 +// { dg-additional-options "-fmain -funittest" } +// { dg-do run } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } + +struct Sdtor +{ + int value; + ~this() { } +} + +Sdtor sum(Sdtor[] sdtors) +{ + int result; + foreach (s; sdtors) + result += s.value; + return Sdtor(result); +} + +uint sum(uint[] ints) +{ + uint result; + foreach(i; ints) + result += i; + return result; +} + +unittest +{ + Sdtor[] sdtors = [Sdtor(0), Sdtor(1)]; + sdtors ~= sum(sdtors); + assert(sdtors == [Sdtor(0), Sdtor(1), Sdtor(1)]); + + uint[] ints = [0, 1]; + ints ~= ints.sum; + assert(ints == [0, 1, 1]); +}