fixes #17033 [backport:1.4] (#17061)

* fixes #17033 [backport:1.4]

* make test robust against stdlib gensym things

* cleanup assertions.nim to make topt_no_cursor easier to get right
This commit is contained in:
Andreas Rumpf 2021-02-17 11:00:03 +01:00 • committed by GitHub
commit f32ffb6ed8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 105 additions and 9 deletions

View file

@ -57,6 +57,7 @@ type
ownsData,
preventCursor,
isReassigned,
isConditionallyReassigned,
viewDoesMutate,
viewBorrowsFromConst
@ -98,6 +99,7 @@ type
goals: set[Goal]
unanalysableMutation: bool
inAsgnSource, inConstructor, inNoSideEffectSection: int
inConditional, inLoop: int
owner: PSym
g: ModuleGraph
@ -748,6 +750,13 @@ proc traverse(c: var Partitions; n: PNode) =
else:
for child in n: traverse(c, child)
proc markAsReassigned(c: var Partitions; vid: int) {.inline.} =
c.s[vid].flags.incl isReassigned
if c.inConditional > 0 and c.inLoop > 0:
# bug #17033: live ranges with loops and conditionals are too
# complex for our current analysis, so we prevent the cursorfication.
c.s[vid].flags.incl isConditionallyReassigned
proc computeLiveRanges(c: var Partitions; n: PNode) =
# first pass: Compute live ranges for locals.
# **Watch out!** We must traverse the tree like 'traverse' does
@ -777,7 +786,7 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
if n[1].kind == nkSym and (c.s[vid].reassignedTo == 0 or c.s[vid].reassignedTo == n[1].sym.id):
c.s[vid].reassignedTo = n[1].sym.id
else:
c.s[vid].flags.incl isReassigned
markAsReassigned(c, vid)
of nkSym:
dec c.abstractTime
@ -804,7 +813,7 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
if not paramType.isCompileTimeOnly and paramType.kind == tyVar:
let vid = variableId(c, it.sym)
if vid >= 0:
c.s[vid].flags.incl isReassigned
markAsReassigned(c, vid)
of nkAddr, nkHiddenAddr:
computeLiveRanges(c, n[0])
@ -822,7 +831,13 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
# while cond:
# mutate(graph)
# connect(graph, cursorVar)
inc c.inLoop
for child in n: computeLiveRanges(c, child)
inc c.inLoop
of nkElifBranch, nkElifExpr, nkElse, nkOfBranch:
inc c.inConditional
for child in n: computeLiveRanges(c, child)
dec c.inConditional
else:
for child in n: computeLiveRanges(c, child)
@ -896,7 +911,8 @@ proc computeCursors*(s: PSym; n: PNode; g: ModuleGraph) =
var par = computeGraphPartitions(s, n, g, {cursorInference})
for i in 0 ..< par.s.len:
let v = addr(par.s[i])
if v.flags * {ownsData, preventCursor} == {} and v.sym.kind notin {skParam, skResult} and
if v.flags * {ownsData, preventCursor, isConditionallyReassigned} == {} and
v.sym.kind notin {skParam, skResult} and
v.sym.flags * {sfThread, sfGlobal} == {} and hasDestructor(v.sym.typ) and
v.sym.typ.skipTypes({tyGenericInst, tyAlias}).kind != tyOwned:
let rid = root(par, i)