summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/injectdestructors.nim27
-rw-r--r--tests/arc/tarc_orc.nim13
2 files changed, 38 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:
diff --git a/tests/arc/tarc_orc.nim b/tests/arc/tarc_orc.nim
index 879ece3c7..c6a7845b0 100644
--- a/tests/arc/tarc_orc.nim
+++ b/tests/arc/tarc_orc.nim
@@ -1,4 +1,5 @@
 discard """
+  targets: "c cpp"
   matrix: "--mm:arc; --mm:orc"
 """
 
@@ -20,3 +21,15 @@ block:
 
   let keys = initKeyPair()
   doAssert keys.public[0] == 88
+
+
+template minIndexByIt: untyped =
+  var other = 3
+  other
+
+proc bug20303() =
+  var hlibs = @["hello", "world", "how", "are", "you"]
+  let res = hlibs[minIndexByIt()]
+  doAssert res == "are"
+
+bug20303()