This commit is contained in:
Andreas Rumpf 2021-06-25 06:22:52 +02:00 • committed by GitHub
commit 0d194cdbf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 25 deletions

View file

@ -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: