diff options
Diffstat (limited to 'compiler/sempass2.nim')
-rw-r--r-- | compiler/sempass2.nim | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index b2b91490c..6235fb76a 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -71,7 +71,7 @@ type init: seq[int] # list of initialized variables guards: TModel # nested guards locked: seq[PNode] # locked locations - gcUnsafe: bool + gcUnsafe, isRecursive: bool PEffects = var TEffects proc isLocalVar(a: PEffects, s: PSym): bool = @@ -113,7 +113,8 @@ proc useVar(a: PEffects, n: PNode) = if {sfGlobal, sfThread} * s.flags == {sfGlobal} and s.kind == skVar: when trackGlobals: a.addUse(copyNode(n)) - if tfHasGCedMem in s.typ.flags: + if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and + tfGcSafe notin s.typ.flags: message(n.info, warnGcUnsafe, renderTree(n)) a.gcUnsafe = true @@ -502,7 +503,9 @@ proc track(tracked: PEffects, n: PNode) = # are indistinguishable from normal procs (both have tyProc type) and # we can detect them only by checking for attached nkEffectList. if op != nil and op.kind == tyProc and op.n.sons[0].kind == nkEffectList: - if notGcSafe(op) and not importedFromC(a): + if a.kind == nkSym and a.sym == tracked.owner: + tracked.isRecursive = true + elif notGcSafe(op) and not importedFromC(a): message(n.info, warnGcUnsafe, renderTree(n)) tracked.gcUnsafe = true var effectList = op.n.sons[0] @@ -515,6 +518,7 @@ proc track(tracked: PEffects, n: PNode) = addEffect(tracked, createRaise(n)) addTag(tracked, createTag(n)) when trackGlobals: addUse(tracked, createAnyGlobal(n)) + # XXX handle 'gcsafe' properly for callbacks! else: mergeEffects(tracked, effectList.sons[exceptionEffects], n) mergeTags(tracked, effectList.sons[tagEffects], n) @@ -701,10 +705,12 @@ proc trackProc*(s: PSym, body: PNode) = checkRaisesSpec(usesSpec, t.uses, "uses an unlisted global variable: ", hints=on, symbolPredicate) effects.sons[usesEffects] = usesSpec - if sfThread in s.flags and t.gcUnsafe: - localError(s.info, "'$1' is not GC-safe" % s.name.s) - if not t.gcUnsafe: s.typ.flags.incl tfGcSafe - + if optThreadAnalysis in gGlobalOptions: + if sfThread in s.flags and t.gcUnsafe: + localError(s.info, warnGcUnsafe2, s.name.s) + #localError(s.info, "'$1' is not GC-safe" % s.name.s) + if not t.gcUnsafe: s.typ.flags.incl tfGcSafe + proc trackTopLevelStmt*(module: PSym; n: PNode) = if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef, nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}: |