diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2021-06-25 14:12:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-25 14:12:23 +0200 |
commit | ceb9e3efc9111f7dda47726c71d2476624ce92c2 (patch) | |
tree | 49a4bc1c671d5ccd4a38a4ee0f05ddacf4a31076 /compiler | |
parent | 0d194cdbf90953f28450c4bf1db744d2c1332996 (diff) | |
download | Nim-ceb9e3efc9111f7dda47726c71d2476624ce92c2.tar.gz |
fixes #18240 (#18354)
* ORC: track escaping parameters properly * fixes #18240
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/sempass2.nim | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index e66c9596a..e124baf26 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -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: |