mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
fixes #7179 ```nim var f = 751.0 echo f.int8 ``` In this case, `int8(float)` yields different numbers for different optimization levels, since float to int conversions are undefined behaviors. In this PR, it mitigates this problem by conversions to same size integers before converting to the final type: i.e. `int8(int64(float))`, which has UB problems but is better than before
This commit is contained in:
@@ -552,7 +552,34 @@ proc transformConv(c: PTransf, n: PNode): PNode =
|
||||
# we don't include uint and uint64 here as these are no ordinal types ;-)
|
||||
if not isOrdinalType(source):
|
||||
# float -> int conversions. ugh.
|
||||
result = transformSons(c, n)
|
||||
# generate a range check:
|
||||
if dest.kind in tyInt..tyInt64:
|
||||
if dest.kind == tyInt64 or source.kind == tyInt64:
|
||||
result = newTransNode(nkChckRange64, n, 3)
|
||||
else:
|
||||
result = newTransNode(nkChckRange, n, 3)
|
||||
dest = skipTypes(n.typ, abstractVar)
|
||||
|
||||
if dest.size < source.size:
|
||||
let intType =
|
||||
if source.size == 4:
|
||||
getSysType(c.graph, n.info, tyInt32)
|
||||
else:
|
||||
getSysType(c.graph, n.info, tyInt64)
|
||||
result[0] =
|
||||
newTreeIT(n.kind, n.info, n.typ, n[0],
|
||||
newTreeIT(nkConv, n.info, intType,
|
||||
newNodeIT(nkType, n.info, intType), transform(c, n[1]))
|
||||
)
|
||||
|
||||
else:
|
||||
result[0] = transformSons(c, n)
|
||||
|
||||
result[1] = newIntTypeNode(firstOrd(c.graph.config, dest), dest)
|
||||
result[2] = newIntTypeNode(lastOrd(c.graph.config, dest), dest)
|
||||
else:
|
||||
result = transformSons(c, n)
|
||||
|
||||
elif firstOrd(c.graph.config, n.typ) <= firstOrd(c.graph.config, n[1].typ) and
|
||||
lastOrd(c.graph.config, n[1].typ) <= lastOrd(c.graph.config, n.typ):
|
||||
# BUGFIX: simply leave n as it is; we need a nkConv node,
|
||||
|
||||
@@ -245,3 +245,32 @@ proc bar2() =
|
||||
|
||||
static: bar2()
|
||||
bar2()
|
||||
|
||||
when not defined(js):
|
||||
proc foo =
|
||||
block:
|
||||
var s1:int = -10
|
||||
doAssertRaises(RangeDefect):
|
||||
var n2:Natural = s1.Natural
|
||||
|
||||
block:
|
||||
var f = 751.0
|
||||
let m = f.int8
|
||||
|
||||
block:
|
||||
var s2:float = -10
|
||||
doAssertRaises(RangeDefect):
|
||||
var n2:Natural = s2.Natural
|
||||
|
||||
|
||||
block:
|
||||
type A = range[0..10]
|
||||
|
||||
let f = 156.0
|
||||
|
||||
doAssertRaises(RangeDefect):
|
||||
let a = f.A
|
||||
|
||||
echo a # 156
|
||||
|
||||
foo()
|
||||
|
||||
Reference in New Issue
Block a user