conversions to unsigned numbers are not checked anymore; implements /… (#12688) [backport]

* conversions to unsigned numbers are not checked anymore; implements / fixes https://github.com/nim-lang/RFCs/issues/175

* change the spec yet again to be less consistent but to make more sense; updated the changelog
This commit is contained in:
Andreas Rumpf 2019-11-20 17:08:43 +01:00 • committed by GitHub
commit c98e0e22ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 29 additions and 6 deletions

View file

@ -1929,7 +1929,8 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
var a: TLoc
var dest = skipTypes(n.typ, abstractVar)
if optRangeCheck notin p.options:
if optRangeCheck notin p.options or (dest.kind in {tyUInt..tyUInt64} and
checkUnsignedConversions notin p.config.legacyFeatures):
initLocExpr(p, n.sons[0], a)
putIntoDest(p, d, n, "(($1) ($2))" %
[getTypeDesc(p.module, dest), rdCharLoc(a)], a.storage)

View file

@ -2155,7 +2155,10 @@ proc upConv(p: PProc, n: PNode, r: var TCompRes) =
proc genRangeChck(p: PProc, n: PNode, r: var TCompRes, magic: string) =
var a, b: TCompRes
gen(p, n.sons[0], r)
if optRangeCheck in p.options:
if optRangeCheck notin p.options or (skipTypes(n.typ, abstractVar).kind in {tyUInt..tyUInt64} and
checkUnsignedConversions notin p.config.legacyFeatures):
discard "XXX maybe emit masking instructions here"
else:
gen(p, n.sons[1], a)
gen(p, n.sons[2], b)
useMagic(p, "chckRange")

View file

@ -146,6 +146,10 @@ type
## Allows to modify a NimNode where the type has already been
## flagged with nfSem. If you actually do this, it will cause
## bugs.
checkUnsignedConversions
## Historically and especially in version 1.0.0 of the language
## conversions to unsigned numbers were checked. In 1.0.4 they
## are not anymore.
SymbolFilesOption* = enum
disabledSf, writeOnlySf, readOnlySf, v2Sf

View file

@ -434,15 +434,12 @@ proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
let dstTyp = skipTypes(n.typ, abstractRange - {tyTypeDesc})
let srcTyp = skipTypes(a.typ, abstractRange - {tyTypeDesc})
# if srcTyp.kind == tyUInt64 and "FFFFFF" in $n:
# echo "n: ", n, " a: ", a
# echo "from: ", srcTyp, " to: ", dstTyp, " check: ", check
# echo getInt(a)
# echo high(int64)
# writeStackTrace()
# XXX range checks?
case dstTyp.kind
of tyInt..tyInt64, tyUInt..tyUInt64:
case srcTyp.kind
@ -450,9 +447,10 @@ proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
result = newIntNodeT(toInt128(getFloat(a)), n, g)
of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
var val = a.getOrdValue
if check: rangeCheck(n, val, g)
result = newIntNodeT(val, n, g)
if dstTyp.kind in {tyUInt .. tyUInt64}:
if dstTyp.kind in {tyUInt..tyUInt64}:
result.kind = nkUIntLit
else:
result = a