aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/d/d-codegen.cc5
-rw-r--r--gcc/d/expr.cc3
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr97843.d37
3 files changed, 44 insertions, 1 deletions
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 1f2d65c..4c16f6a 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 79f212c..ef2bf5f 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 0000000..1a417b3
--- /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]);
+}