Fix several float range issues
This commit is contained in:
parent
66a8856152
commit
def6234903
5 changed files with 30 additions and 3 deletions
|
|
@ -513,6 +513,12 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
|
||||||
if value < firstOrd(c.config, newType) or value > lastOrd(c.config, newType):
|
if value < firstOrd(c.config, newType) or value > lastOrd(c.config, newType):
|
||||||
localError(c.config, n.info, "cannot convert " & $value &
|
localError(c.config, n.info, "cannot convert " & $value &
|
||||||
" to " & typeToString(newType))
|
" to " & typeToString(newType))
|
||||||
|
of nkFloatLit..nkFloat64Lit:
|
||||||
|
if check:
|
||||||
|
echo newType.kind
|
||||||
|
if not floatRangeCheck(n.floatVal, newType):
|
||||||
|
localError(c.config, n.info, "cannot convert " & $n.floatVal &
|
||||||
|
" to " & typeToString(newType))
|
||||||
else: discard
|
else: discard
|
||||||
n.typ = newType
|
n.typ = newType
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,9 @@ proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode =
|
||||||
result = newFloatNode(nkFloatLit, BiggestFloat r1.intVal)
|
result = newFloatNode(nkFloatLit, BiggestFloat r1.intVal)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
result.typ = typ
|
result.typ = typ
|
||||||
|
if not floatRangeCheck(result.floatVal, typ):
|
||||||
|
localError(c.config, n.info, "cannot convert " & $result.floatVal &
|
||||||
|
" to " & typeToString(typ))
|
||||||
else:
|
else:
|
||||||
changeType(c, r1, typ, check=true)
|
changeType(c, r1, typ, check=true)
|
||||||
result = r1
|
result = r1
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
# this module does the semantic checking of type declarations
|
# this module does the semantic checking of type declarations
|
||||||
# included from sem.nim
|
# included from sem.nim
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
const
|
const
|
||||||
errStringOrIdentNodeExpected = "string or ident node expected"
|
errStringOrIdentNodeExpected = "string or ident node expected"
|
||||||
errStringLiteralExpected = "string literal expected"
|
errStringLiteralExpected = "string literal expected"
|
||||||
|
|
@ -236,6 +238,10 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||||
else:
|
else:
|
||||||
result.n.addSon semConstExpr(c, range[i])
|
result.n.addSon semConstExpr(c, range[i])
|
||||||
|
|
||||||
|
if (result.n[0].kind in {nkFloatLit..nkFloat64Lit} and classify(result.n[0].floatVal) == fcNan) or
|
||||||
|
(result.n[1].kind in {nkFloatLit..nkFloat64Lit} and classify(result.n[1].floatVal) == fcNan):
|
||||||
|
localError(c.config, n.info, "NaN is not a valid start or end for a range")
|
||||||
|
|
||||||
if weakLeValue(result.n[0], result.n[1]) == impNo:
|
if weakLeValue(result.n[0], result.n[1]) == impNo:
|
||||||
localError(c.config, n.info, "range is empty")
|
localError(c.config, n.info, "range is empty")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -414,9 +414,10 @@ proc isConvertibleToRange(f, a: PType): bool =
|
||||||
of tyUInt16: result = a.kind in {tyUInt8, tyUInt16, tyUInt}
|
of tyUInt16: result = a.kind in {tyUInt8, tyUInt16, tyUInt}
|
||||||
of tyUInt32: result = a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
of tyUInt32: result = a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
||||||
else: result = false
|
else: result = false
|
||||||
elif f.kind in {tyFloat..tyFloat128} and
|
elif f.kind in {tyFloat..tyFloat128}:
|
||||||
a.kind in {tyFloat..tyFloat128}:
|
# `isIntLit` is correct and should be used above as well, see PR:
|
||||||
result = true
|
# https://github.com/nim-lang/Nim/pull/11197
|
||||||
|
result = isIntLit(a) or a.kind in {tyFloat..tyFloat128}
|
||||||
|
|
||||||
proc handleFloatRange(f, a: PType): TTypeRelation =
|
proc handleFloatRange(f, a: PType): TTypeRelation =
|
||||||
if a.kind == f.kind:
|
if a.kind == f.kind:
|
||||||
|
|
|
||||||
|
|
@ -118,3 +118,14 @@ block:
|
||||||
x3 = R32(4)
|
x3 = R32(4)
|
||||||
|
|
||||||
doAssert $x1 & $x2 & $x3 == "444"
|
doAssert $x1 & $x2 & $x3 == "444"
|
||||||
|
|
||||||
|
block:
|
||||||
|
var x1: range[0'f..1'f] = 1
|
||||||
|
const x2: range[0'f..1'f] = 1
|
||||||
|
var x5: range[0'f32..1'f32] = 1'f64
|
||||||
|
const x6: range[0'f32..1'f32] = 1'f64
|
||||||
|
|
||||||
|
reject:
|
||||||
|
const x: range[0'f..1'f] = 2'f
|
||||||
|
reject:
|
||||||
|
const x: range[0'f..1'f] = 2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue