diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2017-01-18 12:55:33 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-01-18 12:55:33 +0100 |
commit | 2f08fdf6238baefca633ebbd2776ec366288e96d (patch) | |
tree | 55d99a3138b458f8786ab78632a1dd1737ee64e8 /compiler | |
parent | b6b5a11be78961cebd4f3d0b354b227373f64427 (diff) | |
download | Nim-2f08fdf6238baefca633ebbd2776ec366288e96d.tar.gz |
implements {.gcsafe.} enforcement as a pragma block
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/pragmas.nim | 11 | ||||
-rw-r--r-- | compiler/sempass2.nim | 30 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 |
3 files changed, 27 insertions, 16 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index a21705208..85e850834 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -38,7 +38,7 @@ const wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern, wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises, wTags, wLocks, wGcSafe, wExportNims} - exprPragmas* = {wLine, wLocks, wNoRewrite} + exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe} stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, @@ -775,9 +775,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, if sym.typ.callConv == ccClosure: sym.typ.callConv = ccDefault of wGcSafe: noVal(it) - if sym.kind != skType: incl(sym.flags, sfThread) - if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) - else: invalidPragma(it) + if sym != nil: + if sym.kind != skType: incl(sym.flags, sfThread) + if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) + else: invalidPragma(it) + else: + discard "no checking if used as a code block" of wPacked: noVal(it) if sym.typ == nil: invalidPragma(it) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 8aa8f15c8..437a45817 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -59,7 +59,7 @@ type init: seq[int] # list of initialized variables guards: TModel # nested guards locked: seq[PNode] # locked locations - gcUnsafe, isRecursive, isToplevel, hasSideEffect: bool + gcUnsafe, isRecursive, isToplevel, hasSideEffect, inEnforcedGcSafe: bool maxLockLevel, currLockLevel: TLockLevel PEffects = var TEffects @@ -180,17 +180,19 @@ proc warnAboutGcUnsafe(n: PNode) = message(n.info, warnGcUnsafe, renderTree(n)) proc markGcUnsafe(a: PEffects; reason: PSym) = - a.gcUnsafe = true - if a.owner.kind in routineKinds: a.owner.gcUnsafetyReason = reason + if not a.inEnforcedGcSafe: + a.gcUnsafe = true + if a.owner.kind in routineKinds: a.owner.gcUnsafetyReason = reason proc markGcUnsafe(a: PEffects; reason: PNode) = - a.gcUnsafe = true - if a.owner.kind in routineKinds: - if reason.kind == nkSym: - a.owner.gcUnsafetyReason = reason.sym - else: - a.owner.gcUnsafetyReason = newSym(skUnknown, getIdent("<unknown>"), - a.owner, reason.info) + if not a.inEnforcedGcSafe: + a.gcUnsafe = true + if a.owner.kind in routineKinds: + if reason.kind == nkSym: + a.owner.gcUnsafetyReason = reason.sym + else: + a.owner.gcUnsafetyReason = newSym(skUnknown, getIdent("<unknown>"), + a.owner, reason.info) when true: template markSideEffect(a: PEffects; reason: typed) = @@ -803,10 +805,16 @@ proc track(tracked: PEffects, n: PNode) = let pragmaList = n.sons[0] let oldLocked = tracked.locked.len let oldLockLevel = tracked.currLockLevel + var enforcedGcSafety = false for i in 0 .. <pragmaList.len: - if whichPragma(pragmaList.sons[i]) == wLocks: + let pragma = whichPragma(pragmaList.sons[i]) + if pragma == wLocks: lockLocations(tracked, pragmaList.sons[i]) + elif pragma == wGcSafe: + enforcedGcSafety = true + if enforcedGcSafety: tracked.inEnforcedGcSafe = true track(tracked, n.lastSon) + if enforcedGcSafety: tracked.inEnforcedGcSafe = false setLen(tracked.locked, oldLocked) tracked.currLockLevel = oldLockLevel of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef, diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 365109249..bbc83eca4 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1444,7 +1444,7 @@ proc semPragmaBlock(c: PContext, n: PNode): PNode = for i in 0 .. <pragmaList.len: case whichPragma(pragmaList.sons[i]) of wLine: setLine(result, pragmaList.sons[i].info) - of wLocks: + of wLocks, wGcSafe: result = n result.typ = n.sons[1].typ of wNoRewrite: |