Skip to content

Commit 9c46927

Browse files
committed
new feature: ability to turn specific warnings to errors
1 parent ed44e52 commit 9c46927

File tree

8 files changed

+43
-29
lines changed

8 files changed

+43
-29
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
## Compiler changes
1212

13+
- Specific warnings can now be turned into errors via `--warningAsError[X]:on|off`.
1314

1415
## Tool changes
1516

compiler/commands.nim

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,18 @@ proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
209209
incl(conf.modifiedyNotes, n)
210210
case val
211211
of "on":
212-
incl(conf.notes, n)
213-
incl(conf.mainPackageNotes, n)
212+
if state == wWarningAsError:
213+
incl(conf.warningAsErrors, n)
214+
else:
215+
incl(conf.notes, n)
216+
incl(conf.mainPackageNotes, n)
214217
of "off":
215-
excl(conf.notes, n)
216-
excl(conf.mainPackageNotes, n)
217-
excl(conf.foreignPackageNotes, n)
218+
if state == wWarningAsError:
219+
excl(conf.warningAsErrors, n)
220+
else:
221+
excl(conf.notes, n)
222+
excl(conf.mainPackageNotes, n)
223+
excl(conf.foreignPackageNotes, n)
218224

219225
proc processCompile(conf: ConfigRef; filename: string) =
220226
var found = findFile(conf, filename)
@@ -528,6 +534,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
528534
if processOnOffSwitchOrList(conf, {optWarns}, arg, pass, info): listWarnings(conf)
529535
of "warning": processSpecificNote(arg, wWarning, pass, info, switch, conf)
530536
of "hint": processSpecificNote(arg, wHint, pass, info, switch, conf)
537+
of "warningaserror": processSpecificNote(arg, wWarningAsError, pass, info, switch, conf)
531538
of "hints":
532539
if processOnOffSwitchOrList(conf, {optHints}, arg, pass, info): listHints(conf)
533540
of "threadanalysis": processOnOffSwitchG(conf, {optThreadAnalysis}, arg, pass, info)

compiler/msgs.nim

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ proc handleError(conf: ConfigRef; msg: TMsgKind, eh: TErrorHandling, s: string)
354354
if msg >= fatalMin and msg <= fatalMax:
355355
if conf.cmd == cmdIdeTools: log(s)
356356
quit(conf, msg)
357-
if msg >= errMin and msg <= errMax:
357+
if msg >= errMin and msg <= errMax or
358+
(msg in warnMin..warnMax and msg in conf.warningAsErrors):
358359
inc(conf.errorCounter)
359360
conf.exitcode = 1'i8
360361
if conf.errorCounter >= conf.errorMax:
@@ -412,7 +413,7 @@ proc rawMessage*(conf: ConfigRef; msg: TMsgKind, args: openArray[string]) =
412413
sev = Severity.Warning
413414
if not conf.hasWarn(msg): return
414415
writeContext(conf, unknownLineInfo)
415-
title = WarningTitle
416+
title = if msg in conf.warningAsErrors: ErrorTitle else: WarningTitle
416417
color = WarningColor
417418
kind = WarningsToStr[ord(msg) - ord(warnMin)]
418419
inc(conf.warnCounter)
@@ -500,7 +501,7 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
500501
sev = Severity.Warning
501502
ignoreMsg = not conf.hasWarn(msg)
502503
if not ignoreMsg: writeContext(conf, info)
503-
title = WarningTitle
504+
title = if msg in conf.warningAsErrors: ErrorTitle else: WarningTitle
504505
color = WarningColor
505506
kind = WarningsToStr[ord(msg) - ord(warnMin)]
506507
inc(conf.warnCounter)

compiler/options.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ type
237237
cmdlineNotes*: TNoteKinds # notes that have been set/unset from cmdline
238238
foreignPackageNotes*: TNoteKinds
239239
notes*: TNoteKinds # notes after resolving all logic(defaults, verbosity)/cmdline/configs
240+
warningAsErrors*: TNoteKinds
240241
mainPackageNotes*: TNoteKinds
241242
mainPackageId*: int
242243
errorCounter*: int

compiler/pragmas.nim

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -330,31 +330,28 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) =
330330
sym.typ.callConv = ccCDecl
331331

332332
proc processNote(c: PContext, n: PNode) =
333+
template handleNote(toStrArray, msgMin, notes) =
334+
let x = findStr(toStrArray, n[0][1].ident.s)
335+
if x >= 0:
336+
nk = TNoteKind(x + ord(msgMin))
337+
let x = c.semConstBoolExpr(c, n[1])
338+
n[1] = x
339+
if x.kind == nkIntLit and x.intVal != 0: incl(notes, nk)
340+
else: excl(notes, nk)
341+
else:
342+
invalidPragma(c, n)
343+
333344
if n.kind in nkPragmaCallKinds and n.len == 2 and
334345
n[0].kind == nkBracketExpr and
335346
n[0].len == 2 and
336347
n[0][1].kind == nkIdent and n[0][0].kind == nkIdent:
337348
var nk: TNoteKind
338349
case whichKeyword(n[0][0].ident)
339-
of wHint:
340-
var x = findStr(HintsToStr, n[0][1].ident.s)
341-
if x >= 0: nk = TNoteKind(x + ord(hintMin))
342-
else: invalidPragma(c, n); return
343-
of wWarning:
344-
var x = findStr(WarningsToStr, n[0][1].ident.s)
345-
if x >= 0: nk = TNoteKind(x + ord(warnMin))
346-
else: invalidPragma(c, n); return
347-
else:
348-
invalidPragma(c, n)
349-
return
350-
351-
let x = c.semConstBoolExpr(c, n[1])
352-
n[1] = x
353-
if x.kind == nkIntLit and x.intVal != 0: incl(c.config.notes, nk)
354-
else: excl(c.config.notes, nk)
355-
# checkme: honor cmdlineNotes with: c.setNote(nk, x.kind == nkIntLit and x.intVal != 0)
356-
else:
357-
invalidPragma(c, n)
350+
of wHint: handleNote(HintsToStr, hintMin, c.config.notes)
351+
of wWarning: handleNote(WarningsToStr, warnMin, c.config.notes)
352+
of wWarningAsError: handleNote(WarningsToStr, warnMin, c.config.warningAsErrors)
353+
else: invalidPragma(c, n)
354+
else: invalidPragma(c, n)
358355

359356
proc pragmaToOptions(w: TSpecialWord): TOptions {.inline.} =
360357
case w

compiler/semdata.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type
2121
notes*: TNoteKinds
2222
features*: set[Feature]
2323
otherPragmas*: PNode # every pragma can be pushed
24+
warningAsErrors*: TNoteKinds
2425

2526
POptionEntry* = ref TOptionEntry
2627
PProcCon* = ref TProcCon
@@ -213,6 +214,7 @@ proc newOptionEntry*(conf: ConfigRef): POptionEntry =
213214
result.defaultCC = ccDefault
214215
result.dynlib = nil
215216
result.notes = conf.notes
217+
result.warningAsErrors = conf.warningAsErrors
216218

217219
proc pushOptionEntry*(c: PContext): POptionEntry =
218220
new(result)
@@ -221,12 +223,14 @@ proc pushOptionEntry*(c: PContext): POptionEntry =
221223
result.defaultCC = prev.defaultCC
222224
result.dynlib = prev.dynlib
223225
result.notes = c.config.notes
226+
result.warningAsErrors = c.config.warningAsErrors
224227
result.features = c.features
225228
c.optionStack.add(result)
226229

227230
proc popOptionEntry*(c: PContext) =
228231
c.config.options = c.optionStack[^1].options
229232
c.config.notes = c.optionStack[^1].notes
233+
c.config.warningAsErrors = c.optionStack[^1].warningAsErrors
230234
c.features = c.optionStack[^1].features
231235
c.optionStack.setLen(c.optionStack.len - 1)
232236

compiler/wordrecg.nim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type
4444
wAlign, wNodecl, wPure, wSideEffect, wHeader,
4545
wNoSideEffect, wGcSafe, wNoreturn, wNosinks, wMerge, wLib, wDynlib,
4646
wCompilerProc, wCore, wProcVar, wBase, wUsed,
47-
wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef,
47+
wFatal, wError, wWarning, wHint, wWarningAsError, wLine, wPush, wPop, wDefine, wUndef,
4848
wLineDir, wStackTrace, wLineTrace, wLink, wCompile,
4949
wLinksys, wDeprecated, wVarargs, wCallconv, wDebugger,
5050
wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline,
@@ -131,7 +131,7 @@ const
131131
"requiresinit", "align", "nodecl", "pure", "sideeffect",
132132
"header", "nosideeffect", "gcsafe", "noreturn", "nosinks", "merge", "lib", "dynlib",
133133
"compilerproc", "core", "procvar", "base", "used",
134-
"fatal", "error", "warning", "hint", "line",
134+
"fatal", "error", "warning", "hint", "warningaserror", "line",
135135
"push", "pop", "define", "undef", "linedir", "stacktrace", "linetrace",
136136
"link", "compile", "linksys", "deprecated", "varargs",
137137
"callconv", "debugger", "nimcall", "stdcall",
@@ -212,4 +212,5 @@ proc canonPragmaSpelling*(w: TSpecialWord): string =
212212
of wCodegenDecl: "codegenDecl"
213213
of wLiftLocals: "liftLocals"
214214
of wLocalPassc: "localPassc"
215+
of wWarningAsError: "warningAsError"
215216
else: specialWords[w]

doc/advopt.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ Advanced options:
3838
--warning[X]:on|off turn specific warning X on|off
3939
--hints:on|off|list turn all hints on|off or list all available
4040
--hint[X]:on|off turn specific hint X on|off
41+
--warningAsError[X]:on|off
42+
turn specific warning X into an error on|off
4143
--styleCheck:off|hint|error
4244
produce hints or errors for Nim identifiers that
4345
do not adhere to Nim's official style guide

0 commit comments

Comments
 (0)