diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 93df4081ff4c..a71ebc3519dd 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -388,16 +388,28 @@ proc genIf(c: PCtx, n: PNode; dest: var TDest) = for endPos in endings: c.patch(endPos) c.clearDest(n, dest) +proc isTemp(c: PCtx; dest: TDest): bool = + result = dest >= 0 and c.prc.slots[dest].kind >= slotTempUnknown + proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) = # asgn dest, a # tjmp|fjmp L1 # asgn dest, b # L1: - if dest < 0: dest = getTemp(c, n.typ) - c.gen(n.sons[1], dest) - let L1 = c.xjmp(n, opc, dest) - c.gen(n.sons[2], dest) + let copyBack = dest < 0 or not isTemp(c, dest) + let tmp = if copyBack: + getTemp(c, n.typ) + else: + TRegister dest + c.gen(n.sons[1], tmp) + let L1 = c.xjmp(n, opc, tmp) + c.gen(n.sons[2], tmp) c.patch(L1) + if dest < 0: + dest = tmp + elif copyBack: + c.gABC(n, opcAsgnInt, dest, tmp) + freeTemp(c, tmp) proc canonValue*(n: PNode): PNode = result = n @@ -1469,9 +1481,6 @@ proc checkCanEval(c: PCtx; n: PNode) = skIterator} and sfForward in s.flags: cannotEval(c, n) -proc isTemp(c: PCtx; dest: TDest): bool = - result = dest >= 0 and c.prc.slots[dest].kind >= slotTempUnknown - template needsAdditionalCopy(n): untyped = not c.isTemp(dest) and not fitsRegister(n.typ) diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim index 78871d1036c3..20adb5b8faf8 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -160,3 +160,21 @@ block: ["", "M", "MM", "MMM", "--", "-", "--", "---", "----", "--"], ] doAssert encoding.len == 4 + +# #10886 + +proc tor(): bool = + result = true + result = false or result + +proc tand(): bool = + result = false + result = true and result + +const + ctor = tor() + ctand = not tand() + +static: + doAssert ctor + doAssert ctand