public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-1993] d: RHS value lost when a target_expr modifies LHS in a cond_expr
@ 2021-07-02 22:44 Iain Buclaw
  0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2021-07-02 22:44 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c77230856eac2d28eb7bf10985846885c3c8727b

commit r12-1993-gc77230856eac2d28eb7bf10985846885c3c8727b
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sat Jul 3 00:13:29 2021 +0200

    d: RHS value lost when a target_expr modifies LHS in a cond_expr
    
    To prevent the RHS of an assignment modifying the LHS before the
    assignment proper, a target_expr is forced so that function calls that
    return with slot optimization modify the temporary instead.  This did
    not work for conditional expressions however, to give one example.  So
    now the RHS is always forced to a temporary.
    
            PR d/101282
    
    gcc/d/ChangeLog:
    
            * d-codegen.cc (build_assign): Force target_expr on RHS for non-POD
            assignment expressions.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/torture/pr101282.d: New test.

Diff:
---
 gcc/d/d-codegen.cc                      |  7 +++++++
 gcc/testsuite/gdc.dg/torture/pr101282.d | 23 +++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 9a9447371aa..ce7c17baaaf 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -1344,6 +1344,13 @@ build_assign (tree_code code, tree lhs, tree rhs)
       d_mark_addressable (lhs);
       CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;
     }
+  /* If modifying an LHS whose type is marked TREE_ADDRESSABLE.  */
+  else if (code == MODIFY_EXPR && TREE_ADDRESSABLE (TREE_TYPE (lhs))
+	   && TREE_SIDE_EFFECTS (rhs) && TREE_CODE (rhs) != TARGET_EXPR)
+    {
+      /* LHS may be referenced by the RHS expression, so force a temporary.  */
+      rhs = force_target_expr (rhs);
+    }
 
   /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT.  */
   if (TREE_CODE (rhs) == TARGET_EXPR)
diff --git a/gcc/testsuite/gdc.dg/torture/pr101282.d b/gcc/testsuite/gdc.dg/torture/pr101282.d
new file mode 100644
index 00000000000..b75d5fc678f
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr101282.d
@@ -0,0 +1,23 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101282
+// { dg-do run }
+
+void main()
+{
+    struct S101282
+    {
+        int impl;
+        S101282 opUnary(string op : "-")()
+        {
+            return S101282(-impl);
+        }
+        int opCmp(int i)
+        {
+            return (impl < i) ? -1 : (impl > i) ? 1 : 0;
+        }
+    }
+    auto a = S101282(120);
+    a = -a;
+    assert(a.impl == -120);
+    a = a >= 0 ? a : -a;
+    assert(a.impl == 120);
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-02 22:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-02 22:44 [gcc r12-1993] d: RHS value lost when a target_expr modifies LHS in a cond_expr 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).