Skip to content

Commit

Permalink
Fixes #23624 "nim check crash" (#23625)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmgomez authored Sep 16, 2024
1 parent d0dc4ac commit 651fdbe
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 38 deletions.
2 changes: 1 addition & 1 deletion compiler/msgs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ proc warningDeprecated*(conf: ConfigRef, info: TLineInfo = gCmdLineInfo, msg = "
message(conf, info, warnDeprecated, msg)

proc internalErrorImpl(conf: ConfigRef; info: TLineInfo, errMsg: string, info2: InstantiationInfo) =
if conf.cmd == cmdIdeTools and conf.structuredErrorHook.isNil: return
if conf.cmd in {cmdIdeTools, cmdCheck} and conf.structuredErrorHook.isNil: return
writeContext(conf, info)
liMessage(conf, info, errInternal, errMsg, doAbort, info2)

Expand Down
67 changes: 39 additions & 28 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcYldVal: assert false
of opcAsgnInt:
decodeB(rkInt)
regs[ra].intVal = regs[rb].intVal
if regs[rb].kind == rkInt:
regs[ra].intVal = regs[rb].intVal
else:
stackTrace(c, tos, pc, "opcAsgnInt: got " & $regs[rb].kind)
of opcAsgnFloat:
decodeB(rkFloat)
regs[ra].floatVal = regs[rb].floatVal
Expand Down Expand Up @@ -676,16 +679,19 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
else:
assert regs[rb].kind == rkNode
let nb = regs[rb].node
case nb.kind
of nkCharLit..nkUInt64Lit:
ensureKind(rkInt)
regs[ra].intVal = nb.intVal
of nkFloatLit..nkFloat64Lit:
ensureKind(rkFloat)
regs[ra].floatVal = nb.floatVal
if nb == nil:
stackTrace(c, tos, pc, errNilAccess)
else:
ensureKind(rkNode)
regs[ra].node = nb
case nb.kind
of nkCharLit..nkUInt64Lit:
ensureKind(rkInt)
regs[ra].intVal = nb.intVal
of nkFloatLit..nkFloat64Lit:
ensureKind(rkFloat)
regs[ra].floatVal = nb.floatVal
else:
ensureKind(rkNode)
regs[ra].node = nb
of opcSlice:
# A bodge, but this takes in `toOpenArray(rb, rc, rc)` and emits
# nkTupleConstr(x, y, z) into the `regs[ra]`. These can later be used for calculating the slice we have taken.
Expand Down Expand Up @@ -850,25 +856,30 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcLdObj:
# a = b.c
decodeBC(rkNode)
let src = if regs[rb].kind == rkNode: regs[rb].node else: regs[rb].nodeAddr[]
case src.kind
of nkEmpty..nkNilLit:
# for nkPtrLit, this could be supported in the future, use something like:
# derefPtrToReg(src.intVal + offsetof(src.typ, rc), typ_field, regs[ra], isAssign = false)
# where we compute the offset in bytes for field rc
stackTrace(c, tos, pc, errNilAccess & " " & $("kind", src.kind, "typ", typeToString(src.typ), "rc", rc))
of nkObjConstr:
let n = src[rc + 1].skipColon
regs[ra].node = n
of nkTupleConstr:
let n = if src.typ != nil and tfTriggersCompileTime in src.typ.flags:
src[rc]
else:
src[rc].skipColon
regs[ra].node = n
if rb >= regs.len or regs[rb].kind == rkNone or
(regs[rb].kind == rkNode and regs[rb].node == nil) or
(regs[rb].kind == rkNodeAddr and regs[rb].nodeAddr[] == nil):
stackTrace(c, tos, pc, errNilAccess)
else:
let n = src[rc]
regs[ra].node = n
let src = if regs[rb].kind == rkNode: regs[rb].node else: regs[rb].nodeAddr[]
case src.kind
of nkEmpty..nkNilLit:
# for nkPtrLit, this could be supported in the future, use something like:
# derefPtrToReg(src.intVal + offsetof(src.typ, rc), typ_field, regs[ra], isAssign = false)
# where we compute the offset in bytes for field rc
stackTrace(c, tos, pc, errNilAccess & " " & $("kind", src.kind, "typ", typeToString(src.typ), "rc", rc))
of nkObjConstr:
let n = src[rc + 1].skipColon
regs[ra].node = n
of nkTupleConstr:
let n = if src.typ != nil and tfTriggersCompileTime in src.typ.flags:
src[rc]
else:
src[rc].skipColon
regs[ra].node = n
else:
let n = src[rc]
regs[ra].node = n
of opcLdObjAddr:
# a = addr(b.c)
decodeBC(rkNodeAddr)
Expand Down
23 changes: 14 additions & 9 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ proc getTemp(cc: PCtx; tt: PType): TRegister =

proc freeTemp(c: PCtx; r: TRegister) =
let c = c.prc
if c.regInfo[r].kind in {slotSomeTemp..slotTempComplex}:
if r < c.regInfo.len and c.regInfo[r].kind in {slotSomeTemp..slotTempComplex}:
# this seems to cause https://github.com/nim-lang/Nim/issues/10647
c.regInfo[r].inUse = false

Expand Down Expand Up @@ -357,12 +357,13 @@ proc genBlock(c: PCtx; n: PNode; dest: var TDest) =
#if c.prc.regInfo[i].kind in {slotFixedVar, slotFixedLet}:
if i != dest:
when not defined(release):
if c.prc.regInfo[i].inUse and c.prc.regInfo[i].kind in {slotTempUnknown,
slotTempInt,
slotTempFloat,
slotTempStr,
slotTempComplex}:
raiseAssert "leaking temporary " & $i & " " & $c.prc.regInfo[i].kind
if c.config.cmd != cmdCheck:
if c.prc.regInfo[i].inUse and c.prc.regInfo[i].kind in {slotTempUnknown,
slotTempInt,
slotTempFloat,
slotTempStr,
slotTempComplex}:
raiseAssert "leaking temporary " & $i & " " & $c.prc.regInfo[i].kind
c.prc.regInfo[i] = (inUse: false, kind: slotEmpty)

c.clearDest(n, dest)
Expand Down Expand Up @@ -1529,7 +1530,11 @@ proc setSlot(c: PCtx; v: PSym) =
if v.position == 0:
v.position = getFreeRegister(c, if v.kind == skLet: slotFixedLet else: slotFixedVar, start = 1)

proc cannotEval(c: PCtx; n: PNode) {.noinline.} =
template cannotEval(c: PCtx; n: PNode) =
if c.config.cmd == cmdCheck:
localError(c.config, n.info, "cannot evaluate at compile time: " &
n.renderTree)
return
globalError(c.config, n.info, "cannot evaluate at compile time: " &
n.renderTree)

Expand Down Expand Up @@ -1742,7 +1747,7 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
s.kind in {skParam, skResult}):
if dest < 0:
dest = s.position + ord(s.kind == skParam)
internalAssert(c.config, c.prc.regInfo[dest].kind < slotSomeTemp)
internalAssert(c.config, c.prc.regInfo.len > dest and c.prc.regInfo[dest].kind < slotSomeTemp)
else:
# we need to generate an assignment:
let requiresCopy = c.prc.regInfo[dest].kind >= slotSomeTemp and
Expand Down

0 comments on commit 651fdbe

Please sign in to comment.