mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
fixes #22672
This commit is contained in:
@@ -76,6 +76,23 @@ proc isHarmlessStore(p: BProc; canRaise: bool; d: TLoc): bool =
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc cleanupTemp(p: BProc; returnType: PType, tmp: TLoc): bool =
|
||||
if returnType.kind in {tyVar, tyLent}:
|
||||
# we don't need to worry about var/lent return types
|
||||
result = false
|
||||
elif hasDestructor(returnType) and getAttachedOp(p.module.g.graph, returnType, attachedDestructor) != nil:
|
||||
let dtor = getAttachedOp(p.module.g.graph, returnType, attachedDestructor)
|
||||
var op = initLocExpr(p, newSymNode(dtor))
|
||||
var callee = rdLoc(op)
|
||||
let destroy = if dtor.typ.firstParamType.kind == tyVar:
|
||||
callee & "(&" & rdLoc(tmp) & ")"
|
||||
else:
|
||||
callee & "(" & rdLoc(tmp) & ")"
|
||||
raiseExitCleanup(p, destroy)
|
||||
result = true
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
|
||||
callee, params: Rope) =
|
||||
let canRaise = p.config.exc == excGoto and canRaiseDisp(p, ri[0])
|
||||
@@ -128,18 +145,25 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
|
||||
if canRaise: raiseExit(p)
|
||||
|
||||
elif isHarmlessStore(p, canRaise, d):
|
||||
if d.k == locNone: d = getTemp(p, typ.returnType)
|
||||
var useTemp = false
|
||||
if d.k == locNone:
|
||||
useTemp = true
|
||||
d = getTemp(p, typ.returnType)
|
||||
assert(d.t != nil) # generate an assignment to d:
|
||||
var list = initLoc(locCall, d.lode, OnUnknown)
|
||||
list.r = pl
|
||||
genAssignment(p, d, list, flags) # no need for deep copying
|
||||
if canRaise: raiseExit(p)
|
||||
if canRaise:
|
||||
if not (useTemp and cleanupTemp(p, typ.returnType, d)):
|
||||
raiseExit(p)
|
||||
else:
|
||||
var tmp: TLoc = getTemp(p, typ.returnType, needsInit=true)
|
||||
var list = initLoc(locCall, d.lode, OnUnknown)
|
||||
list.r = pl
|
||||
genAssignment(p, tmp, list, flags) # no need for deep copying
|
||||
if canRaise: raiseExit(p)
|
||||
if canRaise:
|
||||
if not cleanupTemp(p, typ.returnType, tmp):
|
||||
raiseExit(p)
|
||||
genAssignment(p, d, tmp, {})
|
||||
else:
|
||||
pl.add(");\n")
|
||||
|
||||
@@ -755,6 +755,18 @@ proc raiseExit(p: BProc) =
|
||||
lineCg(p, cpsStmts, "if (NIM_UNLIKELY(*nimErr_)) goto LA$1_;$n",
|
||||
[p.nestedTryStmts[^1].label])
|
||||
|
||||
proc raiseExitCleanup(p: BProc, destroy: string) =
|
||||
assert p.config.exc == excGoto
|
||||
if nimErrorFlagDisabled notin p.flags:
|
||||
p.flags.incl nimErrorFlagAccessed
|
||||
if p.nestedTryStmts.len == 0:
|
||||
p.flags.incl beforeRetNeeded
|
||||
# easy case, simply goto 'ret':
|
||||
lineCg(p, cpsStmts, "if (NIM_UNLIKELY(*nimErr_)) {$1; goto BeforeRet_;}$n", [destroy])
|
||||
else:
|
||||
lineCg(p, cpsStmts, "if (NIM_UNLIKELY(*nimErr_)) {$2; goto LA$1_;}$n",
|
||||
[p.nestedTryStmts[^1].label, destroy])
|
||||
|
||||
proc finallyActions(p: BProc) =
|
||||
if p.config.exc != excGoto and p.nestedTryStmts.len > 0 and p.nestedTryStmts[^1].inExcept:
|
||||
# if the current try stmt have a finally block,
|
||||
|
||||
@@ -752,6 +752,7 @@ proc intLiteral(i: BiggestInt; result: var Rope)
|
||||
proc genLiteral(p: BProc, n: PNode; result: var Rope)
|
||||
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType; result: var Rope; argsCounter: var int)
|
||||
proc raiseExit(p: BProc)
|
||||
proc raiseExitCleanup(p: BProc, destroy: string)
|
||||
|
||||
proc initLocExpr(p: BProc, e: PNode, flags: TLocFlags = {}): TLoc =
|
||||
result = initLoc(locNone, e, OnUnknown, flags)
|
||||
|
||||
9
tests/errmsgs/t22852.nim
Normal file
9
tests/errmsgs/t22852.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
discard """
|
||||
exitcode: 1
|
||||
outputsub: '''
|
||||
Error: unhandled exception: value out of range: -2 notin 0 .. 9223372036854775807 [RangeDefect]
|
||||
'''
|
||||
"""
|
||||
|
||||
# bug #22852
|
||||
echo [0][2..^2]
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
matrix: "--mm:refc; --backend:cpp --mm:refc; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
|
||||
matrix: "; --backend:cpp; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
|
||||
"""
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ for i in 0 .. 10000:
|
||||
except:
|
||||
discard
|
||||
# memory diff should less than 4M
|
||||
doAssert(abs(getOccupiedMem() - startMemory) < 4 * 1024 * 1024) # todo fixme doesn;t work for ORC
|
||||
doAssert(abs(getOccupiedMem() - startMemory) < 4 * 1024 * 1024)
|
||||
|
||||
|
||||
# test `$`
|
||||
|
||||
Reference in New Issue
Block a user