diff options
author | metagn <metagngn@gmail.com> | 2023-04-17 21:55:22 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-17 20:55:22 +0200 |
commit | b0a98cc01e14a33d75866c10c290f63031dc2112 (patch) | |
tree | 8d73def13ac7699326e885be4b9bd6260aa454ea /compiler | |
parent | 2621f78b683592dced21cd93aa241deac8a9232f (diff) | |
download | Nim-b0a98cc01e14a33d75866c10c290f63031dc2112.tar.gz |
warn on set types bigger than max size, default to 0..255 for int literals (#21659)
* test implicitly huge set types refs https://github.com/nim-lang/RFCs/issues/298 * oh my god * boot at least * don't error, fix remaining issues, no 2 len arrays * fix runnable example * test assuming 0..255 for int literal * test refactor, add changelog, test
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgstmts.nim | 2 | ||||
-rw-r--r-- | compiler/commands.nim | 2 | ||||
-rw-r--r-- | compiler/lineinfos.nim | 2 | ||||
-rw-r--r-- | compiler/lowerings.nim | 3 | ||||
-rw-r--r-- | compiler/nversion.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 33 | ||||
-rw-r--r-- | compiler/semtypes.nim | 2 | ||||
-rw-r--r-- | compiler/suggest.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 3 |
9 files changed, 31 insertions, 20 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index db86af3b0..63fb17527 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -653,7 +653,7 @@ proc genParForStmt(p: BProc, t: PNode) = #initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack) #discard mangleName(forLoopVar) let call = t[1] - assert(call.len in {4, 5}) + assert(call.len == 4 or call.len == 5) initLocExpr(p, call[1], rangeA) initLocExpr(p, call[2], rangeB) diff --git a/compiler/commands.nim b/compiler/commands.nim index 4ed21d282..c31476b45 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -876,7 +876,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "verbosity": expectArg(conf, switch, arg, pass, info) let verbosity = parseInt(arg) - if verbosity notin {0..3}: + if verbosity notin 0..3: localError(conf, info, "invalid verbosity level: '$1'" % arg) conf.verbosity = verbosity var verb = NotesVerbosity[conf.verbosity] diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index 532478e4b..44e9cb716 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -84,6 +84,7 @@ type warnPtrToCstringConv = "PtrToCstringConv", warnEffect = "Effect", warnCastSizes = "CastSizes" + warnAboveMaxSizeSet = "AboveMaxSizeSet", warnImplicitTemplateRedefinition = "ImplicitTemplateRedefinition", warnUnnamedBreak = "UnnamedBreak", warnStmtListLambda = "StmtListLambda", @@ -186,6 +187,7 @@ const warnPtrToCstringConv: "unsafe conversion to 'cstring' from '$1'; this will become a compile time error in the future", warnEffect: "$1", warnCastSizes: "$1", + warnAboveMaxSizeSet: "$1", warnImplicitTemplateRedefinition: "template '$1' is implicitly redefined; this is deprecated, add an explicit .redefine pragma", warnUnnamedBreak: "Using an unnamed break in a block is deprecated; Use a named block with a named break instead", warnStmtListLambda: "statement list expression assumed to be anonymous proc; this is deprecated, use `do (): ...` or `proc () = ...` instead", diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index fc66fc9fa..54a59c80a 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -347,7 +347,8 @@ proc genDeref*(n: PNode; k = nkHiddenDeref): PNode = proc callCodegenProc*(g: ModuleGraph; name: string; info: TLineInfo = unknownLineInfo; - arg1, arg2, arg3, optionalArgs: PNode = nil): PNode = + arg1: PNode = nil, arg2: PNode = nil, + arg3: PNode = nil, optionalArgs: PNode = nil): PNode = result = newNodeI(nkCall, info) let sym = magicsys.getCompilerProc(g, name) if sym == nil: diff --git a/compiler/nversion.nim b/compiler/nversion.nim index 2da39b138..811008989 100644 --- a/compiler/nversion.nim +++ b/compiler/nversion.nim @@ -12,6 +12,8 @@ const MaxSetElements* = 1 shl 16 # (2^16) to support unicode character sets? + DefaultSetElements* = 1 shl 8 + ## assumed set element count when using int literals VersionAsString* = system.NimVersion RodFileVersion* = "1223" # modify this if the rod-format changes! diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 848874810..e5d5498a8 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2563,34 +2563,39 @@ proc semSetConstr(c: PContext, n: PNode, expectedType: PType = nil): PNode = # only semantic checking for all elements, later type checking: var typ: PType = nil for i in 0..<n.len: + let doSetType = typ == nil if isRange(n[i]): checkSonsLen(n[i], 3, c.config) n[i][1] = semExprWithType(c, n[i][1], {efTypeAllowed}, expectedElementType) n[i][2] = semExprWithType(c, n[i][2], {efTypeAllowed}, expectedElementType) - if typ == nil: + if doSetType: typ = skipTypes(n[i][1].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) - if expectedElementType == nil: - expectedElementType = typ n[i].typ = n[i][2].typ # range node needs type too elif n[i].kind == nkRange: # already semchecked - if typ == nil: + if doSetType: typ = skipTypes(n[i][0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) - if expectedElementType == nil: - expectedElementType = typ else: n[i] = semExprWithType(c, n[i], {efTypeAllowed}, expectedElementType) - if typ == nil: + if doSetType: typ = skipTypes(n[i].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) - if expectedElementType == nil: - expectedElementType = typ - if not isOrdinalType(typ, allowEnumWithHoles=true): - localError(c.config, n.info, errOrdinalTypeExpected % typeToString(typ, preferDesc)) - typ = makeRangeType(c, 0, MaxSetElements-1, n.info) - elif lengthOrd(c.config, typ) > MaxSetElements: - typ = makeRangeType(c, 0, MaxSetElements-1, n.info) + if doSetType: + if not isOrdinalType(typ, allowEnumWithHoles=true): + localError(c.config, n.info, errOrdinalTypeExpected % typeToString(typ, preferDesc)) + typ = makeRangeType(c, 0, MaxSetElements-1, n.info) + elif isIntLit(typ): + # set of int literal, use a default range smaller than the max range + typ = makeRangeType(c, 0, DefaultSetElements-1, n.info) + elif lengthOrd(c.config, typ) > MaxSetElements: + message(c.config, n.info, warnAboveMaxSizeSet, "type '" & + typeToString(typ, preferDesc) & "' is too big to be a `set` element, " & + "assuming a range of 0.." & $(MaxSetElements - 1) & + ", explicitly write this range to get rid of warning") + typ = makeRangeType(c, 0, MaxSetElements-1, n.info) + if expectedElementType == nil: + expectedElementType = typ addSonSkipIntLit(result.typ, typ, c.idgen) for i in 0..<n.len: var m: PNode diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index d82748883..cd742c90a 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1843,7 +1843,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = semTypeExpr(c, n, prev) else: let op = considerQuotedIdent(c, n[0]) - if op.id in {ord(wAnd), ord(wOr)} or op.s == "|": + if op.id == ord(wAnd) or op.id == ord(wOr) or op.s == "|": checkSonsLen(n, 3, c.config) var t1 = semTypeNode(c, n[1], nil) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 384ceb271..8407670ba 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -213,7 +213,7 @@ proc `$`*(suggest: Suggest): string = result.add(sep) when defined(nimsuggest) and not defined(noDocgen) and not defined(leanCompiler): result.add(suggest.doc.escape) - if suggest.version in {0, 3}: + if suggest.version == 0 or suggest.version == 3: result.add(sep) result.add($suggest.quality) if suggest.section == ideSug: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index aa4a83900..5183f2def 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -115,7 +115,8 @@ proc echoCode*(c: PCtx; start=0; last = -1) {.deprecated.} = codeListing(c, buf, start, last) echo buf -proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) = +proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; + a: TRegister = 0, b: TRegister = 0, c: TRegister = 0) = ## Takes the registers `b` and `c`, applies the operation `opc` to them, and ## stores the result into register `a` ## The node is needed for debug information |