From 1f1d7b1088fd258a4ce659a3c942290a3c6b3a85 Mon Sep 17 00:00:00 2001 From: Neelesh Chandola Date: Thu, 13 Dec 2018 12:09:54 +0530 Subject: [PATCH 1/4] Fix semRecordCase --- compiler/semstmts.nim | 7 ------- compiler/semtypes.nim | 30 ++++++++++++++++++++---------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index aec03b492c..d814108912 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -95,13 +95,6 @@ proc semWhile(c: PContext, n: PNode; flags: TExprFlags): PNode = elif efInTypeof in flags: result.typ = n[1].typ -proc toCover(c: PContext, t: PType): BiggestInt = - let t2 = skipTypes(t, abstractVarRange-{tyTypeDesc}) - if t2.kind == tyEnum and enumHasHoles(t2): - result = sonsLen(t2.n) - else: - result = lengthOrd(c.config, skipTypes(t, abstractVar-{tyTypeDesc})) - proc semProc(c: PContext, n: PNode): PNode proc semExprBranch(c: PContext, n: PNode; flags: TExprFlags = {}): PNode = diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index f4ff97ba4a..cb0402018c 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -591,6 +591,13 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, for i in lastIndex.succ..(sonsLen(branch) - 2): checkForOverlap(c, t, i, branchIndex) +proc toCover(c: PContext, t: PType): BiggestInt = + let t2 = skipTypes(t, abstractVarRange-{tyTypeDesc}) + if t2.kind == tyEnum and enumHasHoles(t2): + result = sonsLen(t2.n) + else: + result = lengthOrd(c.config, skipTypes(t, abstractVar-{tyTypeDesc})) + proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, father: PNode, rectype: PType, hasCaseFields = false) proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, @@ -603,15 +610,16 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, return incl(a.sons[0].sym.flags, sfDiscriminant) var covered: BiggestInt = 0 + var chckCovered = false var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc}) - if not isOrdinalType(typ): - localError(c.config, n.info, "selector must be of an ordinal type") - elif firstOrd(c.config, typ) != 0: - localError(c.config, n.info, "low(" & $a.sons[0].sym.name.s & - ") must be 0 for discriminant") - elif lengthOrd(c.config, typ) > 0x00007FFF: - localError(c.config, n.info, "len($1) must be less than 32768" % a.sons[0].sym.name.s) - var chckCovered = true + case typ.kind + of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool: + chckCovered = true + of tyFloat..tyFloat128, tyString, tyError: + discard + else: + localError(c.config, n.info, "selector must be of an ordinal type, float or string") + return for i in countup(1, sonsLen(n) - 1): var b = copyTree(n.sons[i]) addSon(a, b) @@ -620,12 +628,14 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, checkMinSonsLen(b, 2, c.config) semCaseBranch(c, a, b, i, covered) of nkElse: - chckCovered = false checkSonsLen(b, 1, c.config) + if chckCovered and covered == toCover(c, a.sons[0].typ): + localError(c.config, b.info, "invalid else, all cases are already covered") + chckCovered = false else: illFormedAst(n, c.config) delSon(b, sonsLen(b) - 1) semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype, hasCaseFields = true) - if chckCovered and covered != lengthOrd(c.config, a.sons[0].typ): + if chckCovered and covered != toCover(c, a.sons[0].typ): localError(c.config, a.info, "not all cases are covered") addSon(father, a) From abcf4d8b5dd4988c952a232d4a610d0491ff79ff Mon Sep 17 00:00:00 2001 From: Neelesh Chandola Date: Thu, 13 Dec 2018 12:45:47 +0530 Subject: [PATCH 2/4] Fix ftpclient.nim --- lib/deprecated/pure/ftpclient.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/deprecated/pure/ftpclient.nim b/lib/deprecated/pure/ftpclient.nim index d70f9556a8..206c21f27d 100644 --- a/lib/deprecated/pure/ftpclient.nim +++ b/lib/deprecated/pure/ftpclient.nim @@ -81,7 +81,6 @@ type oneSecond: BiggestInt # Bytes transferred in one second. lastProgressReport: float # Time toStore: string # Data left to upload (Only used with async) - else: nil FtpClientObj* = FtpBaseObj[Socket] FtpClient* = ref FtpClientObj From fa4644006a618924985bc95bf899b60ea73d8c94 Mon Sep 17 00:00:00 2001 From: Neelesh Chandola Date: Thu, 13 Dec 2018 14:12:22 +0530 Subject: [PATCH 3/4] Check for ordinal type --- compiler/semtypes.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index cb0402018c..9961deee0d 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -618,8 +618,8 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, of tyFloat..tyFloat128, tyString, tyError: discard else: - localError(c.config, n.info, "selector must be of an ordinal type, float or string") - return + if not isOrdinalType(typ): + localError(c.config, n.info, "selector must be of an ordinal type, float or string") for i in countup(1, sonsLen(n) - 1): var b = copyTree(n.sons[i]) addSon(a, b) From e6c510bbbd9fbd076a722c5b2b2626485a16b93e Mon Sep 17 00:00:00 2001 From: Neelesh Chandola Date: Thu, 13 Dec 2018 14:40:22 +0530 Subject: [PATCH 4/4] Check tyRange for exhaustiveness --- compiler/semtypes.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 9961deee0d..d1e119de39 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -613,7 +613,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, var chckCovered = false var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc}) case typ.kind - of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool: + of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool, tyRange: chckCovered = true of tyFloat..tyFloat128, tyString, tyError: discard