summary refs log tree commit diff stats
path: root/compiler/dfa.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dfa.nim')
-rw-r--r--compiler/dfa.nim38
1 files changed, 30 insertions, 8 deletions
diff --git a/compiler/dfa.nim b/compiler/dfa.nim
index cdb912163..436fd699f 100644
--- a/compiler/dfa.nim
+++ b/compiler/dfa.nim
@@ -32,7 +32,6 @@
 import ast, astalgo, types, intsets, tables, msgs, options, lineinfos, renderer
 
 from patterns import sameTrees
-from aliases import isPartOf, TAnalysisResult
 
 type
   InstrKind* = enum
@@ -570,7 +569,8 @@ const
   InterestingSyms = {skVar, skResult, skLet, skParam, skForVar, skTemp}
   PathKinds* = {nkDotExpr, nkCheckedFieldExpr,
                 nkBracketExpr, nkDerefExpr, nkHiddenDeref,
-                nkAddr, nkHiddenAddr}
+                nkAddr, nkHiddenAddr,
+                nkHiddenStdConv, nkHiddenSubConv, nkObjDownConv, nkObjUpConv}
 
 proc genUse(c: var Con; orig: PNode) =
   var n = orig
@@ -581,6 +581,27 @@ proc genUse(c: var Con; orig: PNode) =
   if n.kind == nkSym and n.sym.kind in InterestingSyms:
     c.code.add Instr(n: orig, kind: use, sym: if iters > 0: nil else: n.sym)
 
+proc aliases(obj, field: PNode): bool =
+  var n = field
+  var obj = obj
+  while obj.kind in {nkHiddenSubConv, nkHiddenStdConv, nkObjDownConv, nkObjUpConv}:
+    obj = obj[0]
+  while true:
+    if sameTrees(obj, n): return true
+    case n.kind
+    of nkDotExpr, nkCheckedFieldExpr, nkHiddenSubConv, nkHiddenStdConv,
+       nkObjDownConv, nkObjUpConv, nkHiddenDeref:
+      n = n[0]
+    of nkBracketExpr:
+      let x = n[0]
+      if x.typ != nil and x.typ.skipTypes(abstractInst).kind == tyTuple:
+        n = x
+      else:
+        break
+    else:
+      break
+  return false
+
 proc instrTargets*(ins: Instr; loc: PNode): bool =
   assert ins.kind in {def, use}
   if ins.sym != nil and loc.kind == nkSym:
@@ -593,14 +614,16 @@ proc instrTargets*(ins: Instr; loc: PNode): bool =
     # def x; question: does it affect the 'x.f'? Yes.
     # use x.f;  question: does it affect the full 'x'? No.
     # use x; question does it affect 'x.f'? Yes.
-    result = isPartOf(ins.n, loc) == arYes
+    result = aliases(ins.n, loc) or aliases(loc, ins.n)
 
 proc isAnalysableFieldAccess*(n: PNode; owner: PSym): bool =
   var n = n
   while true:
-    if n.kind in {nkDotExpr, nkCheckedFieldExpr, nkHiddenSubConv, nkHiddenStdConv, nkObjDownConv, nkObjUpConv}:
+    case n.kind
+    of nkDotExpr, nkCheckedFieldExpr, nkHiddenSubConv, nkHiddenStdConv,
+       nkObjDownConv, nkObjUpConv, nkHiddenDeref:
       n = n[0]
-    elif n.kind == nkBracketExpr:
+    of nkBracketExpr:
       let x = n[0]
       if x.typ != nil and x.typ.skipTypes(abstractInst).kind == tyTuple:
         n = x
@@ -710,10 +733,9 @@ proc gen(c: var Con; n: PNode) =
     for x in n: gen(c, x)
   of nkPragmaBlock: gen(c, n.lastSon)
   of nkDiscardStmt: gen(c, n.sons[0])
-  of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkExprColonExpr, nkExprEqExpr,
-     nkCast:
+  of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast:
     gen(c, n.sons[1])
-  of nkObjDownConv, nkStringToCString, nkCStringToString: gen(c, n.sons[0])
+  of nkStringToCString, nkCStringToString: gen(c, n.sons[0])
   of nkVarSection, nkLetSection: genVarSection(c, n)
   of nkDefer:
     doAssert false, "dfa construction pass requires the elimination of 'defer'"