diff options
-rw-r--r-- | compiler/injectdestructors.nim | 27 | ||||
-rw-r--r-- | tests/arc/tarc_orc.nim | 13 |
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() |