mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-29 18:53:58 +00:00
This commit is contained in:
@@ -98,6 +98,8 @@ type
|
||||
|
||||
Partitions* = object
|
||||
abstractTime: AbstractTime
|
||||
defers: seq[PNode]
|
||||
processDefer: bool
|
||||
s: seq[VarIndex]
|
||||
graphs: seq[MutationInfo]
|
||||
goals: set[Goal]
|
||||
@@ -781,6 +783,9 @@ proc traverse(c: var Partitions; n: PNode) =
|
||||
traverse(c, n[0])
|
||||
# variables in while condition has longer alive time than local variables
|
||||
# in the while loop body
|
||||
of nkDefer:
|
||||
if c.processDefer:
|
||||
for child in n: traverse(c, child)
|
||||
else:
|
||||
for child in n: traverse(c, child)
|
||||
|
||||
@@ -877,6 +882,11 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
|
||||
inc c.inConditional
|
||||
for child in n: computeLiveRanges(c, child)
|
||||
dec c.inConditional
|
||||
of nkDefer:
|
||||
if c.processDefer:
|
||||
for child in n: computeLiveRanges(c, child)
|
||||
else:
|
||||
c.defers.add n
|
||||
else:
|
||||
for child in n: computeLiveRanges(c, child)
|
||||
|
||||
@@ -890,9 +900,17 @@ proc computeGraphPartitions*(s: PSym; n: PNode; g: ModuleGraph; goals: set[Goal]
|
||||
registerResult(result, s.ast[resultPos])
|
||||
|
||||
computeLiveRanges(result, n)
|
||||
result.processDefer = true
|
||||
for i in countdown(len(result.defers)-1, 0):
|
||||
computeLiveRanges(result, result.defers[i])
|
||||
result.processDefer = false
|
||||
# restart the timer for the second pass:
|
||||
result.abstractTime = AbstractTime 0
|
||||
traverse(result, n)
|
||||
result.processDefer = true
|
||||
for i in countdown(len(result.defers)-1, 0):
|
||||
traverse(result, result.defers[i])
|
||||
result.processDefer = false
|
||||
|
||||
proc dangerousMutation(g: MutationInfo; v: VarIndex): bool =
|
||||
#echo "range ", v.aliveStart, " .. ", v.aliveEnd, " ", v.sym
|
||||
|
||||
@@ -93,3 +93,15 @@ block: # bug #21674
|
||||
foo(x)
|
||||
|
||||
main()
|
||||
|
||||
block: # bug #22117
|
||||
proc main: int =
|
||||
var a = 10
|
||||
defer: discard a # extend a's lifetime
|
||||
|
||||
var aref: var int = a
|
||||
#└──── 'aref' borrows from location 'a' which does not live long enough
|
||||
|
||||
result = aref
|
||||
|
||||
doAssert main() == 10
|
||||
|
||||
Reference in New Issue
Block a user