diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2021-06-25 06:22:52 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-25 06:22:52 +0200 |
commit | 0d194cdbf90953f28450c4bf1db744d2c1332996 (patch) | |
tree | c174fe8462d29b06a4b05727f79d294eb50bfa51 | |
parent | 6be8a66833ee25ad183fa3e4a667e3c0948413d8 (diff) | |
download | Nim-0d194cdbf90953f28450c4bf1db744d2c1332996.tar.gz |
fixes #18287 (#18346)
-rw-r--r-- | compiler/varpartitions.nim | 48 | ||||
-rw-r--r-- | tests/arc/topt_no_cursor.nim | 51 |
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()) |