diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2022-09-08 14:07:28 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-08 08:07:28 +0200 |
commit | bbbfde7341ba581534abf8fa51a9703bd925b63c (patch) | |
tree | 88d394843dddf36efe314ba76eba8b9834df9eee /compiler | |
parent | f433d9cccf1a05da1a24e9fed9b914b7a2a35945 (diff) | |
download | Nim-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.nim | 27 |
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: |