* fix #13490
This commit is contained in:
parent
25dc5f76e0
commit
c79df2fb6a
5 changed files with 42 additions and 8 deletions
|
|
@ -336,6 +336,8 @@ const
|
||||||
tagEffects* = 3 # user defined tag ('gc', 'time' etc.)
|
tagEffects* = 3 # user defined tag ('gc', 'time' etc.)
|
||||||
pragmasEffects* = 4 # not an effect, but a slot for pragmas in proc type
|
pragmasEffects* = 4 # not an effect, but a slot for pragmas in proc type
|
||||||
effectListLen* = 5 # list of effects list
|
effectListLen* = 5 # list of effects list
|
||||||
|
nkLastBlockStmts* = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
|
||||||
|
# these must be last statements in a block
|
||||||
|
|
||||||
type
|
type
|
||||||
TTypeKind* = enum # order is important!
|
TTypeKind* = enum # order is important!
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ proc endsInNoReturn(n: PNode): bool =
|
||||||
var it = n
|
var it = n
|
||||||
while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0:
|
while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0:
|
||||||
it = it.lastSon
|
it = it.lastSon
|
||||||
result = it.kind == nkRaiseStmt or
|
result = it.kind in nkLastBlockStmts or
|
||||||
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
|
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
|
||||||
|
|
||||||
proc commonType*(x: PType, y: PNode): PType =
|
proc commonType*(x: PType, y: PNode): PType =
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ const
|
||||||
proc implicitlyDiscardable(n: PNode): bool =
|
proc implicitlyDiscardable(n: PNode): bool =
|
||||||
var n = n
|
var n = n
|
||||||
while n.kind in skipForDiscardable: n = n.lastSon
|
while n.kind in skipForDiscardable: n = n.lastSon
|
||||||
result = n.kind == nkRaiseStmt or
|
result = n.kind in nkLastBlockStmts or
|
||||||
(isCallExpr(n) and n[0].kind == nkSym and
|
(isCallExpr(n) and n[0].kind == nkSym and
|
||||||
sfDiscardable in n[0].sym.flags)
|
sfDiscardable in n[0].sym.flags)
|
||||||
|
|
||||||
|
|
@ -2162,9 +2162,6 @@ proc inferConceptStaticParam(c: PContext, inferred, n: PNode) =
|
||||||
typ.n = res
|
typ.n = res
|
||||||
|
|
||||||
proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# these must be last statements in a block:
|
|
||||||
const
|
|
||||||
LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
|
|
||||||
result = n
|
result = n
|
||||||
result.transitionSonsKind(nkStmtList)
|
result.transitionSonsKind(nkStmtList)
|
||||||
var voidContext = false
|
var voidContext = false
|
||||||
|
|
@ -2209,7 +2206,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
else:
|
else:
|
||||||
n.typ = n[i].typ
|
n.typ = n[i].typ
|
||||||
if not isEmptyType(n.typ): n.transitionSonsKind(nkStmtListExpr)
|
if not isEmptyType(n.typ): n.transitionSonsKind(nkStmtListExpr)
|
||||||
if n[i].kind in LastBlockStmts or
|
if n[i].kind in nkLastBlockStmts or
|
||||||
n[i].kind in nkCallKinds and n[i][0].kind == nkSym and
|
n[i].kind in nkCallKinds and n[i][0].kind == nkSym and
|
||||||
sfNoReturn in n[i][0].sym.flags:
|
sfNoReturn in n[i][0].sym.flags:
|
||||||
for j in i + 1..<n.len:
|
for j in i + 1..<n.len:
|
||||||
|
|
|
||||||
|
|
@ -2094,12 +2094,10 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
genWhile(c, n)
|
genWhile(c, n)
|
||||||
of nkBlockExpr, nkBlockStmt: genBlock(c, n, dest)
|
of nkBlockExpr, nkBlockStmt: genBlock(c, n, dest)
|
||||||
of nkReturnStmt:
|
of nkReturnStmt:
|
||||||
unused(c, n, dest)
|
|
||||||
genReturn(c, n)
|
genReturn(c, n)
|
||||||
of nkRaiseStmt:
|
of nkRaiseStmt:
|
||||||
genRaise(c, n)
|
genRaise(c, n)
|
||||||
of nkBreakStmt:
|
of nkBreakStmt:
|
||||||
unused(c, n, dest)
|
|
||||||
genBreak(c, n)
|
genBreak(c, n)
|
||||||
of nkTryStmt, nkHiddenTryStmt: genTry(c, n, dest)
|
of nkTryStmt, nkHiddenTryStmt: genTry(c, n, dest)
|
||||||
of nkStmtList:
|
of nkStmtList:
|
||||||
|
|
|
||||||
|
|
@ -250,3 +250,40 @@ proc negativeOrNot(num: int): string =
|
||||||
doAssert negativeOrNot(-1) == "negative"
|
doAssert negativeOrNot(-1) == "negative"
|
||||||
doAssert negativeOrNot(10000000) == "zero or positive"
|
doAssert negativeOrNot(10000000) == "zero or positive"
|
||||||
doAssert negativeOrNot(0) == "zero or positive"
|
doAssert negativeOrNot(0) == "zero or positive"
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
# issue #13490
|
||||||
|
import strutils
|
||||||
|
func foo(input: string): int =
|
||||||
|
try:
|
||||||
|
parseInt(input)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
|
func foo2(b, input: string): int =
|
||||||
|
case b:
|
||||||
|
of "Y":
|
||||||
|
for c in input:
|
||||||
|
result = if c in '0'..'9': parseInt($c)
|
||||||
|
else: break
|
||||||
|
of "N":
|
||||||
|
for c in input:
|
||||||
|
result = if c in '0'..'9': parseInt($c)
|
||||||
|
else: continue
|
||||||
|
else: return
|
||||||
|
|
||||||
|
|
||||||
|
static:
|
||||||
|
doAssert(foo("3") == 3)
|
||||||
|
doAssert(foo("a") == 0)
|
||||||
|
doAssert(foo2("Y", "a2") == 0)
|
||||||
|
doAssert(foo2("Y", "2a") == 2)
|
||||||
|
doAssert(foo2("N", "a3") == 3)
|
||||||
|
doAssert(foo2("z", "2") == 0)
|
||||||
|
|
||||||
|
doAssert(foo("3") == 3)
|
||||||
|
doAssert(foo("a") == 0)
|
||||||
|
doAssert(foo2("Y", "a2") == 0)
|
||||||
|
doAssert(foo2("Y", "2a") == 2)
|
||||||
|
doAssert(foo2("N", "a3") == 3)
|
||||||
|
doAssert(foo2("z", "2") == 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue