summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2022-09-08 14:07:28 +0800
committerGitHub <noreply@github.com>2022-09-08 08:07:28 +0200
commitbbbfde7341ba581534abf8fa51a9703bd925b63c (patch)
tree88d394843dddf36efe314ba76eba8b9834df9eee /compiler
parentf433d9cccf1a05da1a24e9fed9b914b7a2a35945 (diff)
downloadNim-bbbfde7341ba581534abf8fa51a9703bd925b63c.tar.gz
fixes #20303; wasMoved expressions with side effects for ORC (#20307) [backport]
fixes #20303; wasMoved expressions with side effects
Diffstat (limited to 'compiler')
-rw-r--r--compiler/injectdestructors.nim27
1 files changed, 25 insertions, 2 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim
index 4cb3b4f50..40ff7ab55 100644
--- a/compiler/injectdestructors.nim
+++ b/compiler/injectdestructors.nim
@@ -1014,6 +1014,26 @@ proc sameLocation*(a, b: PNode): bool =
     of nkHiddenStdConv, nkHiddenSubConv: sameLocation(a[1], b)
     else: false
 
+proc genFieldAccessSideEffects(c: var Con; dest, ri: PNode, isDecl: bool): PNode =
+  # with side effects
+  var temp = newSym(skLet, getIdent(c.graph.cache, "bracketTmp"), nextSymId c.idgen, c.owner, ri[1].info)
+  temp.typ = ri[1].typ
+  var v = newNodeI(nkLetSection, ri[1].info)
+  let tempAsNode = newSymNode(temp)
+
+  var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3)
+  vpart[0] = tempAsNode
+  vpart[1] = newNodeI(nkEmpty, tempAsNode.info)
+  vpart[2] = ri[1]
+  v.add(vpart)
+
+  var newAccess = copyNode(ri)
+  newAccess.add ri[0]
+  newAccess.add tempAsNode
+
+  var snk = c.genSink(dest, newAccess, isDecl)
+  result = newTree(nkStmtList, v, snk, c.genWasMoved(newAccess))
+
 proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNode =
   if sameLocation(dest, ri):
     # rule (self-assignment-removal):
@@ -1037,8 +1057,11 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod
       elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c):
         if aliases(dest, ri) == no:
           # Rule 3: `=sink`(x, z); wasMoved(z)
-          var snk = c.genSink(dest, ri, isDecl)
-          result = newTree(nkStmtList, snk, c.genWasMoved(ri))
+          if isAtom(ri[1]):
+            var snk = c.genSink(dest, ri, isDecl)
+            result = newTree(nkStmtList, snk, c.genWasMoved(ri))
+          else:
+            result = genFieldAccessSideEffects(c, dest, ri, isDecl)
         else:
           result = c.genSink(dest, destructiveMoveVar(ri, c, s), isDecl)
       else: