diff options
author | Araq <rumpf_a@web.de> | 2015-02-12 14:40:50 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-02-12 14:56:56 +0100 |
commit | 8763bffa845c2c17e7e70acfc21b556f407d9ecd (patch) | |
tree | f7a2a872b46ead54de92a6d9ed0c4946fc86dbac | |
parent | 10335fd7264560e9b5a6ca4b2b5fe8e28e78209b (diff) | |
download | Nim-8763bffa845c2c17e7e70acfc21b556f407d9ecd.tar.gz |
better handling of gcsafety with --threadAnalysis:off
-rw-r--r-- | compiler/pragmas.nim | 9 | ||||
-rw-r--r-- | compiler/sempass2.nim | 43 |
2 files changed, 27 insertions, 25 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 90f87696b..78ee490e2 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -735,11 +735,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, incl(sym.flags, sfProcvar) if sym.typ != nil: incl(sym.typ.flags, tfThread) of wGcSafe: - if optThreadAnalysis in gGlobalOptions: - noVal(it) - if sym.kind != skType: incl(sym.flags, sfThread) - if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) - else: invalidPragma(it) + noVal(it) + if sym.kind != skType: incl(sym.flags, sfThread) + if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) + else: invalidPragma(it) of wPacked: noVal(it) if sym.typ == nil: invalidPragma(it) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 6fa7c756e..3f78629c8 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -194,6 +194,9 @@ proc warnAboutGcUnsafe(n: PNode) = #assert false message(n.info, warnGcUnsafe, renderTree(n)) +template markGcUnsafe(a: PEffects) = + a.gcUnsafe = true + proc useVar(a: PEffects, n: PNode) = let s = n.sym if isLocalVar(a, s): @@ -209,7 +212,7 @@ proc useVar(a: PEffects, n: PNode) = if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and tfGcSafe notin s.typ.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - a.gcUnsafe = true + markGcUnsafe(a) type TIntersection = seq[tuple[id, count: int]] # a simple count table @@ -448,7 +451,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = if notGcSafe(s.typ) and sfImportc notin s.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) mergeLockLevels(tracked, n, s.getLockLevel) proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = @@ -502,13 +505,13 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) = # assume GcUnsafe unless in its type; 'forward' does not matter: if notGcSafe(op) and not isOwnedProcVar(a, tracked.owner): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) else: mergeEffects(tracked, effectList.sons[exceptionEffects], n) mergeTags(tracked, effectList.sons[tagEffects], n) if notGcSafe(op): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) notNilCheck(tracked, n, paramType) proc breaksBlock(n: PNode): bool = @@ -656,7 +659,7 @@ proc track(tracked: PEffects, n: PNode) = # and it's not a recursive call: if not (a.kind == nkSym and a.sym == tracked.owner): warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) for i in 1 .. <len(n): trackOperand(tracked, n.sons[i], paramType(op, i)) if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}: # may not look like an assignment, but it is: @@ -825,7 +828,7 @@ proc trackProc*(s: PSym, body: PNode) = # effects already computed? if sfForward in s.flags: return if effects.len == effectListLen: return - + var t: TEffects initEffects(effects, s, t) track(t, body) @@ -849,20 +852,20 @@ proc trackProc*(s: PSym, body: PNode) = # after the check, use the formal spec: effects.sons[tagEffects] = tagsSpec - if optThreadAnalysis in gGlobalOptions: - if sfThread in s.flags and t.gcUnsafe: - if optThreads in gGlobalOptions: - localError(s.info, "'$1' is not GC-safe" % s.name.s) - else: - localError(s.info, warnGcUnsafe2, s.name.s) - if not t.gcUnsafe: s.typ.flags.incl tfGcSafe - if s.typ.lockLevel == UnspecifiedLockLevel: - s.typ.lockLevel = t.maxLockLevel - elif t.maxLockLevel > s.typ.lockLevel: - #localError(s.info, - message(s.info, warnLockLevel, - "declared lock level is $1, but real lock level is $2" % - [$s.typ.lockLevel, $t.maxLockLevel]) + if sfThread in s.flags and t.gcUnsafe: + if optThreads in gGlobalOptions and optThreadAnalysis in gGlobalOptions: + localError(s.info, "'$1' is not GC-safe" % s.name.s) + else: + localError(s.info, warnGcUnsafe2, s.name.s) + if not t.gcUnsafe: + s.typ.flags.incl tfGcSafe + if s.typ.lockLevel == UnspecifiedLockLevel: + s.typ.lockLevel = t.maxLockLevel + elif t.maxLockLevel > s.typ.lockLevel: + #localError(s.info, + message(s.info, warnLockLevel, + "declared lock level is $1, but real lock level is $2" % + [$s.typ.lockLevel, $t.maxLockLevel]) proc trackTopLevelStmt*(module: PSym; n: PNode) = if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef, |