summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-03-23 14:49:21 +0100
committerGitHub <noreply@github.com>2019-03-23 14:49:21 +0100
commit0cc6e124254a2222e04d1226fe9c362d20f38cd5 (patch)
tree03bbd1c925da0b773590d2d77f504b58ccc992cd
parentf8146dfd845e8d9a8f19ae59ef9c9350cd9db453 (diff)
downloadNim-0cc6e124254a2222e04d1226fe9c362d20f38cd5.tar.gz
fixes #8202 (#10888)
* fixes #8202

* make tests green
-rw-r--r--compiler/cgen.nim10
-rw-r--r--tests/cpp/tevalorder.nim18
2 files changed, 27 insertions, 1 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 25921e9f3..747494277 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -534,7 +534,15 @@ proc initLocExpr(p: BProc, e: PNode, result: var TLoc) =
 
 proc initLocExprSingleUse(p: BProc, e: PNode, result: var TLoc) =
   initLoc(result, locNone, e, OnUnknown)
-  result.flags.incl lfSingleUse
+  if e.kind in nkCallKinds and (e[0].kind != nkSym or e[0].sym.magic == mNone):
+    # We cannot check for tfNoSideEffect here because of mutable parameters.
+    discard "bug #8202; enforce evaluation order for nested calls for C++ too"
+    # We may need to consider that 'f(g())' cannot be rewritten to 'tmp = g(); f(tmp)'
+    # if 'tmp' lacks a move/assignment operator.
+    if e[0].kind == nkSym and sfConstructor in e[0].sym.flags:
+      result.flags.incl lfSingleUse
+  else:
+    result.flags.incl lfSingleUse
   expr(p, e, result)
 
 include ccgcalls, "ccgstmts.nim"
diff --git a/tests/cpp/tevalorder.nim b/tests/cpp/tevalorder.nim
new file mode 100644
index 000000000..f130cef6c
--- /dev/null
+++ b/tests/cpp/tevalorder.nim
@@ -0,0 +1,18 @@
+discard """
+  output: '''0
+1
+2'''
+target: "cpp"
+"""
+
+# bug #8202
+var current: int = 0
+
+proc gen(): string = current.inc; $(current - 1)
+
+proc allOut(a, b, c: string) =
+    echo a
+    echo b
+    echo c
+
+allOut(gen(), gen(), gen())