summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2021-02-17 11:00:03 +0100
committerGitHub <noreply@github.com>2021-02-17 11:00:03 +0100
commitf32ffb6ed821cc01e52c48181a4caa15e73c0362 (patch)
treea6fdfc6b2fb31a0a896b96400eaf43331535eab7 /compiler
parentb9994925f5051a55bb13bd3115d60c92c52c3c09 (diff)
downloadNim-f32ffb6ed821cc01e52c48181a4caa15e73c0362.tar.gz
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
Diffstat (limited to 'compiler')
-rw-r--r--compiler/varpartitions.nim22
1 files changed, 19 insertions, 3 deletions
diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim
index 812ab262c..3093fb38f 100644
--- a/compiler/varpartitions.nim
+++ b/compiler/varpartitions.nim
@@ -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)