* ORC: track escaping parameters properly

* fixes #18240
This commit is contained in:
Andreas Rumpf 2021-06-25 14:12:23 +02:00 • committed by GitHub
commit ceb9e3efc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 12 deletions

View file

@ -77,6 +77,7 @@ type
config: ConfigRef
graph: ModuleGraph
c: PContext
escapingParams: IntSet
PEffects = var TEffects
proc `<`(a, b: TLockLevel): bool {.borrow.}
@ -900,6 +901,25 @@ proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) =
localError(tracked.config, pragma.info,
"invalid pragma block: " & $pragma)
proc trackInnerProc(tracked: PEffects, n: PNode) =
case n.kind
of nkSym:
let s = n.sym
if s.kind == skParam and s.owner == tracked.owner:
tracked.escapingParams.incl s.id
of nkNone..pred(nkSym), succ(nkSym)..nkNilLit:
discard
of nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef, nkLambda, nkFuncDef, nkDo:
if n[0].kind == nkSym and n[0].sym.ast != nil:
trackInnerProc(tracked, getBody(tracked.graph, n[0].sym))
of nkTypeSection, nkMacroDef, nkTemplateDef, nkError,
nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt,
nkExportStmt, nkPragma, nkCommentStmt, nkBreakState,
nkTypeOfExpr, nkMixinStmt, nkBindStmt:
discard
else:
for ch in n: trackInnerProc(tracked, ch)
proc track(tracked: PEffects, n: PNode) =
case n.kind
of nkSym:
@ -1095,8 +1115,10 @@ proc track(tracked: PEffects, n: PNode) =
track(tracked, n.lastSon)
unapplyBlockContext(tracked, bc)
of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef,
nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef:
of nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef, nkLambda, nkFuncDef, nkDo:
if n[0].kind == nkSym and n[0].sym.ast != nil:
trackInnerProc(tracked, getBody(tracked.graph, n[0].sym))
of nkTypeSection, nkMacroDef, nkTemplateDef:
discard
of nkCast:
if n.len == 2:
@ -1259,15 +1281,6 @@ proc hasRealBody(s: PSym): bool =
## which is not a real implementation, refs #14314
result = {sfForward, sfImportc} * s.flags == {}
proc maybeWrappedInClosure(tracked: PEffects; t: PType): bool {.inline.} =
## The spec does say when to produce destructors. However, the spec
## was written in mind with the idea that "lambda lifting" already
## happened. Not true in our implementation, so we need to workaround
## here:
result = tracked.isInnerProc and
sfSystemModule notin tracked.c.module.flags and
tfCheckedForDestructor notin t.flags and containsGarbageCollectedRef(t)
proc trackProc*(c: PContext; s: PSym, body: PNode) =
let g = c.graph
var effects = s.typ.n[0]
@ -1287,7 +1300,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
let typ = param.typ
if isSinkTypeForParam(typ) or
(t.config.selectedGC in {gcArc, gcOrc} and
(isClosure(typ.skipTypes(abstractInst)) or maybeWrappedInClosure(t, typ))):
(isClosure(typ.skipTypes(abstractInst)) or param.id in t.escapingParams)):
createTypeBoundOps(t, typ, param.info)
when false:
if typ.kind == tyOut and param.id notin t.init: