mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
fixes #14522 fixes #22085 fixes #12700 fixes #23132 closes https://github.com/nim-lang/Nim/pull/22343 (succeeded by this PR) completes https://github.com/nim-lang/RFCs/issues/175 follow up https://github.com/nim-lang/Nim/pull/12688
This commit is contained in:
@@ -270,7 +270,8 @@ proc checkConvertible(c: PContext, targetTyp: PType, src: PNode): TConvStatus =
|
||||
discard "convOk"
|
||||
elif targetTyp.isOrdinalType:
|
||||
if src.kind in nkCharLit..nkUInt64Lit and
|
||||
src.getInt notin firstOrd(c.config, targetTyp)..lastOrd(c.config, targetTyp):
|
||||
src.getInt notin firstOrd(c.config, targetTyp)..lastOrd(c.config, targetTyp) and
|
||||
targetTyp.kind notin {tyUInt..tyUInt64}:
|
||||
result = convNotInRange
|
||||
elif src.kind in nkFloatLit..nkFloat64Lit and
|
||||
(classify(src.floatVal) in {fcNan, fcNegInf, fcInf} or
|
||||
|
||||
@@ -420,14 +420,17 @@ proc foldConv(n, a: PNode; idgen: IdGenerator; g: ModuleGraph; check = false): P
|
||||
result = newIntNodeT(toInt128(getFloat(a)), n, idgen, g)
|
||||
of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
|
||||
var val = a.getOrdValue
|
||||
if check: rangeCheck(n, val, g)
|
||||
result = newIntNodeT(val, n, idgen, g)
|
||||
if dstTyp.kind in {tyUInt..tyUInt64}:
|
||||
result = newIntNodeT(val, n, idgen, g)
|
||||
result.transitionIntKind(nkUIntLit)
|
||||
else:
|
||||
if check: rangeCheck(n, val, g)
|
||||
result = newIntNodeT(val, n, idgen, g)
|
||||
else:
|
||||
result = a
|
||||
result.typ = n.typ
|
||||
if check and result.kind in {nkCharLit..nkUInt64Lit}:
|
||||
if check and result.kind in {nkCharLit..nkUInt64Lit} and
|
||||
dstTyp.kind notin {tyUInt..tyUInt64}:
|
||||
rangeCheck(n, getInt(result), g)
|
||||
of tyFloat..tyFloat64:
|
||||
case srcTyp.kind
|
||||
@@ -747,6 +750,8 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||
if leValueConv(n[1], a) and leValueConv(a, n[2]):
|
||||
result = a # a <= x and x <= b
|
||||
result.typ = n.typ
|
||||
elif n.typ.kind in {tyUInt..tyUInt64}:
|
||||
discard "don't check uints"
|
||||
else:
|
||||
localError(g.config, n.info,
|
||||
"conversion from $1 to $2 is invalid" %
|
||||
|
||||
@@ -3788,9 +3788,6 @@ type conversions to unsigned integers and between unsigned integers. The
|
||||
rationale for this is mostly better interoperability with the C Programming
|
||||
language when algorithms are ported from C to Nim.
|
||||
|
||||
Exception: Values that are converted to an unsigned type at compile time
|
||||
are checked so that code like `byte(-1)` does not compile.
|
||||
|
||||
**Note**: Historically the operations
|
||||
were unchecked and the conversions were sometimes checked but starting with
|
||||
the revision 1.0.4 of this document and the language implementation the
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
discard """
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
doAssert typeOf(1.int64 + 1.int) is int64
|
||||
doAssert typeOf(1.uint64 + 1.uint) is uint64
|
||||
doAssert int64 is SomeNumber
|
||||
@@ -12,3 +16,24 @@ doAssert typeOf(myInt16 + myInt) is int # of type `int`
|
||||
doAssert typeOf(myInt16 + 2i32) is int32 # of type `int32`
|
||||
doAssert int32 isnot int64
|
||||
doAssert int32 isnot int
|
||||
|
||||
block:
|
||||
# bug #22085
|
||||
const
|
||||
x = uint32(uint64.high) # vm error
|
||||
u = uint64.high
|
||||
v = uint32(u) # vm error
|
||||
|
||||
let
|
||||
z = uint64.high
|
||||
y = uint32(z) # runtime ok
|
||||
|
||||
let
|
||||
w = uint32(uint64.high) # semfold error
|
||||
|
||||
doAssert x == w
|
||||
doAssert v == y
|
||||
|
||||
# bug #14522
|
||||
doAssert 0xFF000000_00000000.uint64 == 18374686479671623680'u64
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
discard """
|
||||
cmd: "nim check --hint:Processing:off --hint:Conf:off $file"
|
||||
errormsg: "18446744073709551615 can't be converted to int8"
|
||||
nimout: '''tcompiletime_range_checks.nim(36, 21) Error: 2147483648 can't be converted to int32
|
||||
tcompiletime_range_checks.nim(37, 23) Error: -1 can't be converted to uint64
|
||||
nimout: '''
|
||||
tcompiletime_range_checks.nim(36, 21) Error: 2147483648 can't be converted to int32
|
||||
tcompiletime_range_checks.nim(38, 34) Error: 255 can't be converted to FullNegativeRange
|
||||
tcompiletime_range_checks.nim(39, 34) Error: 18446744073709551615 can't be converted to HalfNegativeRange
|
||||
tcompiletime_range_checks.nim(40, 34) Error: 300 can't be converted to FullPositiveRange
|
||||
|
||||
Reference in New Issue
Block a user