From 16573f6a30e38011f9c25f5c87690607b9510da8 Mon Sep 17 00:00:00 2001 From: Clyybber Date: Fri, 11 Feb 2022 17:54:41 +0100 Subject: [PATCH] Replace all localReport errors with nkError in pragmas.nim --- compiler/ast/report_enums.nim | 1 - compiler/front/cli_reporter.nim | 3 - compiler/sem/pragmas.nim | 130 +++++++++++++----------------- compiler/sem/semexprs.nim | 14 ++-- compiler/sem/semstmts.nim | 10 ++- tests/errmsgs/tinvalidasmstmt.nim | 34 ++++++++ tests/errmsgs/tinvalidpragma.nim | 7 +- 7 files changed, 109 insertions(+), 90 deletions(-) create mode 100644 tests/errmsgs/tinvalidasmstmt.nim diff --git a/compiler/ast/report_enums.nim b/compiler/ast/report_enums.nim index c8a5973fa64..b9c8cadb8f8 100644 --- a/compiler/ast/report_enums.nim +++ b/compiler/ast/report_enums.nim @@ -680,7 +680,6 @@ type # Pragma rsemInvalidPragma ## suplied pragma is invalid - rsemCannotAttachPragma rsemUnexpectedPragma rsemPropositionExpected rsemIllegalCustomPragma diff --git a/compiler/front/cli_reporter.nim b/compiler/front/cli_reporter.nim index b9742fb09e6..1c4551bd0d1 100644 --- a/compiler/front/cli_reporter.nim +++ b/compiler/front/cli_reporter.nim @@ -2156,9 +2156,6 @@ proc reportBody*(conf: ConfigRef, r: SemReport): string = of rsemUnexpectedPragma: result = "unexpected pragma" - of rsemCannotAttachPragma: - result = "cannot attach a custom pragma to '" & r.symstr & "'" - of rsemDisallowedReprForNewruntime: result = "'repr' is not available for --newruntime" diff --git a/compiler/sem/pragmas.nim b/compiler/sem/pragmas.nim index e507739c2e0..6e9a0b49846 100644 --- a/compiler/sem/pragmas.nim +++ b/compiler/sem/pragmas.nim @@ -136,18 +136,11 @@ proc recordPragma(c: PContext; n: PNode; args: varargs[string]) = recorded.add newStrNode(args[i], n.info) addPragmaComputation(c, recorded) -proc invalidPragma*(c: PContext; n: PNode) = - localReport(c.config, n.info, reportAst(rsemInvalidPragma, n)) - -proc illegalCustomPragma*(c: PContext, n: PNode, s: PSym) = - localReport(c.config, n.info, reportSym( - rsemCannotAttachPragma, s, ast = n)) - -proc newInvalidPragmaNode*(c: PContext; n: PNode): PNode = +proc invalidPragma*(c: PContext; n: PNode): PNode = ## create an error node (`nkError`) for an invalid pragma error c.config.newError(n, reportAst(rsemInvalidPragma, n)) -proc newIllegalCustomPragmaNode*(c: PContext; n: PNode, s: PSym): PNode = +proc illegalCustomPragma*(c: PContext; n: PNode, s: PSym): PNode = ## create an error node (`nkError`) for an illegal custom pragma error c.config.newError( n, @@ -156,19 +149,20 @@ proc newIllegalCustomPragmaNode*(c: PContext; n: PNode, s: PSym): PNode = n.info ) -proc pragmaAsm*(c: PContext, n: PNode): char = - result = '\0' +proc pragmaAsm*(c: PContext, n: PNode): tuple[marker: char, err: PNode] = + ## Gets the marker out of an asm stmts pragma list + ## Returns ` as the default marker if no other markers are found + result.marker = '`' if n != nil: for i in 0.. 1: - newInvalidPragmaNode(c, n) + invalidPragma(c, n) else: n proc pragmaUnroll(c: PContext, n: PNode): PNode = result = n if c.p.nestedLoopCounter <= 0: - result = newInvalidPragmaNode(c, n) + result = invalidPragma(c, n) elif n.kind in nkPragmaCallKinds and n.len == 2: var (unrollFactor, err) = intLitToIntOrErr(c, n) if err.isNil: if unrollFactor <% 32: n[1] = newIntNode(nkIntLit, unrollFactor) else: - result = newInvalidPragmaNode(c, n) + result = invalidPragma(c, n) else: result = err @@ -904,7 +896,7 @@ proc processPragma(c: PContext, n: PNode, i: int): PNode = result = it if it.kind notin nkPragmaCallKinds and it.safeLen == 2 or it.safeLen != 2 or it[0].kind != nkIdent or it[1].kind != nkIdent: - n[i] = newInvalidPragmaNode(c, it) + n[i] = invalidPragma(c, it) result = n[i] return @@ -945,12 +937,12 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode): PNode = result = wrapErrorInSubTree(c.config, n) return else: - result = newInvalidPragmaNode(c, n) + result = invalidPragma(c, n) proc pragmaLockStmt(c: PContext; it: PNode): PNode = result = it if it.kind notin nkPragmaCallKinds or it.len != 2: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: let n = it[1] if n.kind != nkBracket: @@ -963,7 +955,7 @@ proc pragmaLockStmt(c: PContext; it: PNode): PNode = proc pragmaLocks(c: PContext, it: PNode): (TLockLevel, PNode) = if it.kind notin nkPragmaCallKinds or it.len != 2: - result = (UnknownLockLevel, newInvalidPragmaNode(c, it)) + result = (UnknownLockLevel, invalidPragma(c, it)) else: case it[1].kind of nkStrLit, nkRStrLit, nkTripleStrLit: @@ -1059,7 +1051,7 @@ proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym = if it.kind notin nkPragmaCallKinds or it.len != 2: result = newSym(skError, getIdent(c.cache, "err:" & renderTree(it)), nextSymId(c.idgen), getCurrOwner(c), it.info, {}) - result.ast = newInvalidPragmaNode(c, it) + result.ast = invalidPragma(c, it) return let n = it[1] if n.kind == nkSym: @@ -1092,17 +1084,13 @@ proc semCustomPragma(c: PContext, n: PNode): PNode = elif n.kind in nkPragmaCallKinds: callNode = n else: - result = c.config.newError(n, reportAst(rsemInvalidPragma, n)) + result = invalidPragma(c, n) return - # invalidPragma(c, n) - # return n let r = c.semOverloadedCall(c, callNode, {skTemplate}, {efNoUndeclared}) if r.isNil or sfCustomPragma notin r[0].sym.flags: - result = c.config.newError(n, reportAst(rsemInvalidPragma, n)) + result = invalidPragma(c, n) return - # invalidPragma(c, n) - # return n result = r # Transform the nkCall node back to its original form if possible @@ -1154,8 +1142,6 @@ proc prepareSinglePragma( ## * whether it's `isStatement` ## ## what this does: - ## * return an nkError if `invalidPragma` would have been called - ## * all the localReports and what not should be nkErrors ## * flag with nfImplicitPragma if it's an implcit pragma :D ## * return the pragma after prep and it's good to go var @@ -1291,7 +1277,7 @@ proc prepareSinglePragma( incl(sym.flags, sfDirty) it else: - newInvalidPragmaNode(c, it) + invalidPragma(c, it) of wImportCpp: let nameLit = getOptionalStrLit(c, it, "$1") case nameLit.kind @@ -1347,7 +1333,7 @@ proc prepareSinglePragma( of wSize: result = if sym.typ == nil: - newInvalidPragmaNode(c, it) + invalidPragma(c, it) else: it var (size, err) = intLitToIntOrErr(c, it) @@ -1385,7 +1371,7 @@ proc prepareSinglePragma( result = noVal(c, it) if sym != nil: if k == wPure and sym.kind in routineKinds: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.flags, sfPure) of wVolatile: @@ -1499,7 +1485,7 @@ proc prepareSinglePragma( of wVarargs: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfVarargs) of wBorrow: @@ -1511,27 +1497,27 @@ proc prepareSinglePragma( of wFinal: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfFinal) of wInheritable: result = noVal(c, it) if sym.typ == nil or tfFinal in sym.typ.flags: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfInheritable) of wPackage: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.flags, sfForward) of wAcyclic: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfAcyclic) of wShallow: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfShallow) of wThread: result = noVal(c, it) @@ -1547,13 +1533,13 @@ proc prepareSinglePragma( if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) else: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: discard "no checking if used as a code block" of wPacked: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfPacked) of wHint: @@ -1676,7 +1662,7 @@ proc prepareSinglePragma( assert(sym != nil) result = it if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: sym.typ.callConv = wordToCallConv(k) sym.typ.flags.incl tfExplicitCallConv @@ -1692,19 +1678,19 @@ proc prepareSinglePragma( of wIncompleteStruct: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfIncompleteStruct) of wCompleteStruct: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfCompleteStruct) of wUnchecked: result = noVal(c, it) if sym.typ == nil or sym.typ.kind notin {tyArray, tyUncheckedArray}: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: sym.typ.kind = tyUncheckedArray of wUnion: @@ -1713,7 +1699,7 @@ proc prepareSinglePragma( else: result = noVal(c, it) if sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfUnion) of wRequiresInit: @@ -1723,7 +1709,7 @@ proc prepareSinglePragma( elif sym.typ != nil: incl(sym.typ.flags, tfNeedsFullInit) else: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) of wByRef: result = noVal(c, it) if sym == nil or sym.typ == nil: @@ -1735,20 +1721,20 @@ proc prepareSinglePragma( of wByCopy: result = noVal(c, it) if sym.kind != skType or sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfByCopy) of wPartial: result = noVal(c, it) if sym.kind != skType or sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: incl(sym.typ.flags, tfPartial) of wInject, wGensym: # We check for errors, but do nothing with these pragmas otherwise # as they are handled directly in 'evalTemplate'. result = noVal(c, it) - if sym == nil: result = newInvalidPragmaNode(c, it) + if sym == nil: result = invalidPragma(c, it) of wLine: result = pragmaLine(c, it) of wRaises, wTags: @@ -1757,14 +1743,14 @@ proc prepareSinglePragma( if sym == nil: result = pragmaLockStmt(c, it) elif sym.typ == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: (sym.typ.lockLevel, result) = pragmaLocks(c, it) if result.isNil: result = it of wBitsize: if sym == nil or sym.kind != skField: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: (sym.bitsize, result) = intLitToIntOrErr(c, it) if result.isNil: result = it @@ -1773,7 +1759,7 @@ proc prepareSinglePragma( of wGuard: result = it if sym == nil or sym.kind notin {skVar, skLet, skField}: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: sym.guard = pragmaGuard(c, it, sym.kind) if sym.guard != nil and sym.guard.kind == skError and sym.guard.ast != nil and sym.guard.ast.kind == nkError: @@ -1783,13 +1769,13 @@ proc prepareSinglePragma( of wGoto: result = it if sym == nil or sym.kind notin {skVar, skLet}: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: sym.flags.incl sfGoto of wExportNims: result = it if sym == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: result = magicsys.registerNimScriptSymbol2(c.graph, sym) if result.kind != nkError: @@ -1833,7 +1819,7 @@ proc prepareSinglePragma( of wUsed: result = noVal(c, it) if sym == nil: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) else: sym.flags.incl sfUsed of wLiftLocals: @@ -1841,7 +1827,7 @@ proc prepareSinglePragma( of wEnforceNoRaises: sym.flags.incl sfNeverRaises else: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) elif comesFromPush and whichKeyword(ident) != wInvalid: discard "ignore the .push pragma; it doesn't apply" else: @@ -1850,9 +1836,9 @@ proc prepareSinglePragma( n[i] = semCustomPragma(c, it) result = n[i] elif sym != nil: - result = newIllegalCustomPragmaNode(c, it, sym) + result = illegalCustomPragma(c, it, sym) else: - result = newInvalidPragmaNode(c, it) + result = invalidPragma(c, it) proc overwriteLineInfo(n: PNode; info: TLineInfo) = n.info = info diff --git a/compiler/sem/semexprs.nim b/compiler/sem/semexprs.nim index febe8f9b33d..fac28b0f976 100644 --- a/compiler/sem/semexprs.nim +++ b/compiler/sem/semexprs.nim @@ -3122,23 +3122,19 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkCurlyExpr: result = semExpr(c, buildOverloadedSubscripts(n, getIdent(c.cache, "{}")), flags) of nkPragmaExpr: - var + let pragma = n[1] pragmaName = considerQuotedIdent(c, pragma[0]) - flags = flags - finalNodeFlags: TNodeFlags = {} case whichKeyword(pragmaName) of wExplain: - flags.incl efExplain + result = semExpr(c, n[0], flags + {efExplain}) of wExecuteOnReload: - finalNodeFlags.incl nfExecuteOnReload + result = semExpr(c, n[0], flags) + result.flags.incl nfExecuteOnReload else: # what other pragmas are allowed for expressions? `likely`, `unlikely` - invalidPragma(c, n) - - result = semExpr(c, n[0], flags) - result.flags.incl finalNodeFlags + result = invalidPragma(c, n) of nkPar, nkTupleConstr: case checkPar(c, n) of paNone: result = errorNode(c, n) diff --git a/compiler/sem/semstmts.nim b/compiler/sem/semstmts.nim index 1f4977f0bbe..44acfee3806 100644 --- a/compiler/sem/semstmts.nim +++ b/compiler/sem/semstmts.nim @@ -55,9 +55,13 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode = proc semAsm(c: PContext, n: PNode): PNode = checkSonsLen(n, 2, c.config) - var marker = pragmaAsm(c, n[0]) - if marker == '\0': marker = '`' # default marker - result = semAsmOrEmit(c, n, marker) + let (marker, err) = pragmaAsm(c, n[0]) + if err.isNil: + result = semAsmOrEmit(c, n, marker) + else: + result = n + result[0] = err + result = c.config.wrapErrorInSubTree(result) proc semWhile(c: PContext, n: PNode; flags: TExprFlags): PNode = result = n diff --git a/tests/errmsgs/tinvalidasmstmt.nim b/tests/errmsgs/tinvalidasmstmt.nim new file mode 100644 index 00000000000..6c09ca48fce --- /dev/null +++ b/tests/errmsgs/tinvalidasmstmt.nim @@ -0,0 +1,34 @@ +discard """ + cmd: "nim check $options $file" + action: reject + nimout: ''' +tinvalidasmstmt.nim(14, 3) Error: empty 'asm' statement +tinvalidasmstmt.nim(19, 22) Error: illformed AST: asm ha +tinvalidasmstmt.nim(30, 9) Error: invalid pragma: invalid +tinvalidasmstmt.nim(31, 16) Error: invalid pragma: invalid("a") +tinvalidasmstmt.nim(32, 17) Error: invalid pragma: subschar(1) +''' +""" + +proc emptyAsmStmt = + asm "" +emptyAsmStmt() + +import macros +macro defA = + result = newNimNode(nnkAsmStmt) + result.add( + newEmptyNode(), + ident "ha" + ) + +proc invalidAST = + defA +invalidAST() + +proc invalidPragma = + asm {.invalid.} "" + asm {.invalid("a").} "" + asm {.subschar(1).} "" # subschar('`') would be valid for example + +invalidPragma() diff --git a/tests/errmsgs/tinvalidpragma.nim b/tests/errmsgs/tinvalidpragma.nim index 9d10804413b..90697c63ad1 100644 --- a/tests/errmsgs/tinvalidpragma.nim +++ b/tests/errmsgs/tinvalidpragma.nim @@ -2,10 +2,13 @@ discard """ cmd: "nim check $options $file" action: reject nimout: ''' -tinvalidpragma.nim(10, 20) Error: invalid pragma: warning[XYZ]: off -tinvalidpragma.nim(11, 15) Error: invalid pragma: warning[XYZ]: off +tinvalidpragma.nim(11, 20) Error: invalid pragma: warning[XYZ]: off +tinvalidpragma.nim(12, 15) Error: invalid pragma: warning[XYZ]: off +tinvalidpragma.nim(14, 22) Error: invalid pragma: "expression" {.invalid.} ''' """ {.push warning[XYZ]: off.} {.warning[XYZ]: off, push warning[XYZ]: off.} + +discard "expression" {.invalid.}