mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 19:52:36 +00:00
fixes regression; block can have arbitrary exit points; too hard for a simple analysis (#23839)
follow up https://github.com/nim-lang/Nim/pull/23681
ref https://forum.nim-lang.org/t/11987
ref https://github.com/nim-lang/Nim/issues/23836#issuecomment-2227267251
(cherry picked from commit b7a275da1d)
This commit is contained in:
@@ -187,18 +187,19 @@ proc implicitlyDiscardable(n: PNode): bool =
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc endsInNoReturn(n: PNode, returningNode: var PNode): bool =
|
||||
proc endsInNoReturn(n: PNode, returningNode: var PNode; discardableCheck = false): bool =
|
||||
## check if expr ends the block like raising or call of noreturn procs do
|
||||
result = false # assume it does return
|
||||
|
||||
template checkBranch(branch) =
|
||||
if not endsInNoReturn(branch, returningNode):
|
||||
if not endsInNoReturn(branch, returningNode, discardableCheck):
|
||||
# proved a branch returns
|
||||
return false
|
||||
|
||||
var it = n
|
||||
# skip these beforehand, no special handling needed
|
||||
while it.kind in skipForDiscardable and it.len > 0:
|
||||
let skips = if discardableCheck: skipForDiscardable else: skipForDiscardable-{nkBlockExpr, nkBlockStmt}
|
||||
while it.kind in skips and it.len > 0:
|
||||
it = it.lastSon
|
||||
|
||||
case it.kind
|
||||
@@ -242,7 +243,7 @@ proc endsInNoReturn(n: PNode, returningNode: var PNode): bool =
|
||||
var lastIndex = it.len - 1
|
||||
if it[lastIndex].kind == nkFinally:
|
||||
# if finally is noreturn, then the entire statement is noreturn
|
||||
if endsInNoReturn(it[lastIndex][^1], returningNode):
|
||||
if endsInNoReturn(it[lastIndex][^1], returningNode, discardableCheck):
|
||||
return true
|
||||
dec lastIndex
|
||||
for i in 1 .. lastIndex:
|
||||
@@ -287,7 +288,7 @@ proc discardCheck(c: PContext, result: PNode, flags: TExprFlags) =
|
||||
else:
|
||||
# Ignore noreturn procs since they don't have a type
|
||||
var n = result
|
||||
if result.endsInNoReturn(n):
|
||||
if result.endsInNoReturn(n, discardableCheck = true):
|
||||
return
|
||||
|
||||
var s = "expression '" & $n & "' is of type '" &
|
||||
|
||||
12
tests/controlflow/tunreachable2.nim
Normal file
12
tests/controlflow/tunreachable2.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
discard """
|
||||
matrix: "--warningAsError:UnreachableCode"
|
||||
"""
|
||||
|
||||
proc test(): bool =
|
||||
block okay:
|
||||
if true: break okay
|
||||
return false
|
||||
|
||||
return true # Line 7 is here
|
||||
|
||||
doAssert test()
|
||||
Reference in New Issue
Block a user