diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-08-11 00:04:29 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-10 18:04:29 +0200 |
commit | faf1c91e6a418e21d56ac6e45e1dbc851f9ffd22 (patch) | |
tree | 9b55a5534b793e844ad135a713e6a025acf3e1cc | |
parent | 7be2e2bef545e68ac3d88876fe7073a033fbb5f4 (diff) | |
download | Nim-faf1c91e6a418e21d56ac6e45e1dbc851f9ffd22.tar.gz |
fixes move sideeffects issues [backport] (#22439)
* fixes move sideeffects issues [backport] * fix openarray * fixes openarray
-rw-r--r-- | compiler/ccgexprs.nim | 18 | ||||
-rw-r--r-- | tests/destructor/tmove.nim | 18 |
2 files changed, 33 insertions, 3 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index dd47d1d1f..64bd16f84 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2310,9 +2310,21 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) = if op == nil: resetLoc(p, a) else: - let addrExp = makeAddr(n[1], p.module.idgen) - let wasMovedCall = newTreeI(nkCall, n.info, newSymNode(op), addrExp) - genCall(p, wasMovedCall, d) + var b = initLocExpr(p, newSymNode(op)) + case skipTypes(a.t, abstractVar+{tyStatic}).kind + of tyOpenArray, tyVarargs: # todo fixme generated `wasMoved` hooks for + # openarrays, but it probably shouldn't? + var s: string + if reifiedOpenArray(a.lode): + if a.t.kind in {tyVar, tyLent}: + s = "$1->Field0, $1->Field1" % [rdLoc(a)] + else: + s = "$1.Field0, $1.Field1" % [rdLoc(a)] + else: + s = "$1, $1Len_0" % [rdLoc(a)] + linefmt(p, cpsStmts, "$1($2);$n", [rdLoc(b), s]) + else: + linefmt(p, cpsStmts, "$1($2);$n", [rdLoc(b), byRefLoc(p, a)]) else: let flags = if not canMove(p, n[1], d): {needToCopy} else: {} genAssignment(p, d, a, flags) diff --git a/tests/destructor/tmove.nim b/tests/destructor/tmove.nim new file mode 100644 index 000000000..2762aff90 --- /dev/null +++ b/tests/destructor/tmove.nim @@ -0,0 +1,18 @@ +discard """ + targets: "c cpp" +""" + +block: + var called = 0 + + proc bar(a: var int): var int = + inc called + result = a + + proc foo = + var a = 2 + var s = move bar(a) + doAssert called == 1 + doAssert s == 2 + + foo() |