summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2021-06-25 06:22:52 +0200
committerGitHub <noreply@github.com>2021-06-25 06:22:52 +0200
commit0d194cdbf90953f28450c4bf1db744d2c1332996 (patch)
treec174fe8462d29b06a4b05727f79d294eb50bfa51
parent6be8a66833ee25ad183fa3e4a667e3c0948413d8 (diff)
downloadNim-0d194cdbf90953f28450c4bf1db744d2c1332996.tar.gz
fixes #18287 (#18346)
-rw-r--r--compiler/varpartitions.nim48
-rw-r--r--tests/arc/topt_no_cursor.nim51
2 files changed, 74 insertions, 25 deletions
diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim
index 213c3b80e..8f422face 100644
--- a/compiler/varpartitions.nim
+++ b/compiler/varpartitions.nim
@@ -416,7 +416,6 @@ proc allRoots(n: PNode; result: var seq[(PSym, int)]; level: int) =
 proc destMightOwn(c: var Partitions; dest: var VarIndex; n: PNode) =
   ## Analyse if 'n' is an expression that owns the data, if so mark 'dest'
   ## with 'ownsData'.
-  if n.typ == nil: return
   case n.kind
   of nkEmpty, nkCharLit..nkNilLit:
     # primitive literals including the empty are harmless:
@@ -475,30 +474,31 @@ proc destMightOwn(c: var Partitions; dest: var VarIndex; n: PNode) =
     destMightOwn(c, dest, n[0])
 
   of nkCallKinds:
-    if hasDestructor(n.typ):
-      # calls do construct, what we construct must be destroyed,
-      # so dest cannot be a cursor:
-      dest.flags.incl ownsData
-    elif n.typ.kind in {tyLent, tyVar}:
-      # we know the result is derived from the first argument:
-      var roots: seq[(PSym, int)]
-      allRoots(n[1], roots, RootEscapes)
-      for r in roots:
-        connect(c, dest.sym, r[0], n[1].info)
+    if n.typ != nil:
+      if hasDestructor(n.typ):
+        # calls do construct, what we construct must be destroyed,
+        # so dest cannot be a cursor:
+        dest.flags.incl ownsData
+      elif n.typ.kind in {tyLent, tyVar}:
+        # we know the result is derived from the first argument:
+        var roots: seq[(PSym, int)]
+        allRoots(n[1], roots, RootEscapes)
+        for r in roots:
+          connect(c, dest.sym, r[0], n[1].info)
 
-    else:
-      let magic = if n[0].kind == nkSym: n[0].sym.magic else: mNone
-      # this list is subtle, we try to answer the question if after 'dest = f(src)'
-      # there is a connection betwen 'src' and 'dest' so that mutations to 'src'
-      # also reflect 'dest':
-      if magic in {mNone, mMove, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mArrToSeq}:
-        for i in 1..<n.len:
-          # we always have to assume a 'select(...)' like mechanism.
-          # But at least we do filter out simple POD types from the
-          # list of dependencies via the 'hasDestructor' check for
-          # the root's symbol.
-          if hasDestructor(n[i].typ.skipTypes({tyVar, tySink, tyLent, tyGenericInst, tyAlias})):
-            destMightOwn(c, dest, n[i])
+      else:
+        let magic = if n[0].kind == nkSym: n[0].sym.magic else: mNone
+        # this list is subtle, we try to answer the question if after 'dest = f(src)'
+        # there is a connection betwen 'src' and 'dest' so that mutations to 'src'
+        # also reflect 'dest':
+        if magic in {mNone, mMove, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mArrToSeq}:
+          for i in 1..<n.len:
+            # we always have to assume a 'select(...)' like mechanism.
+            # But at least we do filter out simple POD types from the
+            # list of dependencies via the 'hasDestructor' check for
+            # the root's symbol.
+            if hasDestructor(n[i].typ.skipTypes({tyVar, tySink, tyLent, tyGenericInst, tyAlias})):
+              destMightOwn(c, dest, n[i])
 
   else:
     # something we cannot handle:
diff --git a/tests/arc/topt_no_cursor.nim b/tests/arc/topt_no_cursor.nim
index 06cc4eda8..824d6bd08 100644
--- a/tests/arc/topt_no_cursor.nim
+++ b/tests/arc/topt_no_cursor.nim
@@ -8,7 +8,7 @@ doing shady stuff...
 192.168.0.1
 192.168.0.1
 192.168.0.1'''
-  cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig --expandArc:mergeShadowScope $file'''
+  cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig --expandArc:mergeShadowScope --expandArc:check $file'''
   nimout: '''--expandArc: newTarget
 
 var
@@ -127,6 +127,36 @@ block :tmp:
         :tmpD
       inc(i, 1)
 `=destroy`(shadowScope)
+-- end of expandArc ------------------------
+--expandArc: check
+
+var par
+this.isValid = fileExists(this.value)
+if dirExists(this.value):
+  var :tmpD
+  par = (dir:
+    wasMoved(:tmpD)
+    `=copy`(:tmpD, this.value)
+    :tmpD, front: "") else:
+  var
+    :tmpD_1
+    :tmpD_2
+    :tmpD_3
+  par = (dir_1: parentDir(this.value), front_1:
+    wasMoved(:tmpD_1)
+    `=copy`(:tmpD_1,
+      :tmpD_3 = splitPath do:
+        wasMoved(:tmpD_2)
+        `=copy`(:tmpD_2, this.value)
+        :tmpD_2
+      :tmpD_3.tail)
+    :tmpD_1)
+  `=destroy`(:tmpD_3)
+if dirExists(par.dir):
+  `=sink`(this.matchDirs, getSubDirs(par.dir, par.front))
+else:
+  `=sink`(this.matchDirs, [])
+`=destroy`(par)
 -- end of expandArc ------------------------'''
 """
 
@@ -322,3 +352,22 @@ proc mergeShadowScope*(c: PContext) =
     c.addInterfaceDecl(sym)
 
 mergeShadowScope(PContext(currentScope: Scope(parent: Scope())))
+
+type
+  Foo = ref object
+    isValid*: bool
+    value*: string
+    matchDirs*: seq[string]
+
+proc getSubDirs(parent, front: string): seq[string] = @[]
+
+method check(this: Foo) {.base.} =
+  this.isValid = fileExists(this.value)
+  let par = if dirExists(this.value): (dir: this.value, front: "")
+            else: (dir: parentDir(this.value), front: splitPath(this.value).tail)
+  if dirExists(par.dir):
+    this.matchDirs = getSubDirs(par.dir, par.front)
+  else:
+    this.matchDirs = @[]
+
+check(Foo())