From c9c5abcdc17daa3aeb583f4473925b6ea19b0d64 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 23 Mar 2019 14:44:53 +0100 Subject: [PATCH] fixes #10886 [backport] (#10897) (cherry picked from commit 0b2a3f6f7f7dfc40e08d287f41f7ce7c2e51fd9c) --- compiler/vmgen.nim | 23 ++++++++++++++++------- tests/vm/tvmmisc.nim | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 2f96f60bc8..6cfc07446c 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -361,16 +361,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 @@ -1396,9 +1408,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 6a8084647f..a178bb95eb 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -148,3 +148,32 @@ static: static: doAssert foo().i == 1 + +# #10333 +block: + const + encoding: auto = [ + ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], + ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], + ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"], + ["", "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