mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 17:34:43 +00:00
@@ -1378,7 +1378,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
proc genOrd(p: BProc, e: PNode, d: var TLoc) =
|
||||
unaryExprChar(p, e, d, "$1")
|
||||
|
||||
proc genCast(p: BProc, e: PNode, d: var TLoc) =
|
||||
proc genSomeCast(p: BProc, e: PNode, d: var TLoc) =
|
||||
const
|
||||
ValueTypes = {tyTuple, tyObject, tyArray, tyOpenArray, tyVarargs,
|
||||
tyArrayConstr}
|
||||
@@ -1397,6 +1397,31 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
|
||||
putIntoDest(p, d, e.typ, ropef("(($1) ($2))",
|
||||
[getTypeDesc(p.module, e.typ), rdCharLoc(a)]))
|
||||
|
||||
proc genCast(p: BProc, e: PNode, d: var TLoc) =
|
||||
const floatTypes = {tyFloat..tyFloat128}
|
||||
let
|
||||
destt = skipTypes(e.typ, abstractRange)
|
||||
srct = skipTypes(e.sons[1].typ, abstractRange)
|
||||
if destt.kind in floatTypes or srct.kind in floatTypes:
|
||||
# 'cast' and some float type involved? --> use a union.
|
||||
inc(p.labels)
|
||||
var lbl = p.labels.toRope
|
||||
var tmp: TLoc
|
||||
tmp.r = ropef("LOC$1.source", lbl)
|
||||
linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n",
|
||||
getTypeDesc(p.module, srct), getTypeDesc(p.module, destt), lbl)
|
||||
tmp.k = locExpr
|
||||
tmp.a = -1
|
||||
tmp.t = srct
|
||||
tmp.s = OnStack
|
||||
tmp.flags = {}
|
||||
expr(p, e.sons[1], tmp)
|
||||
putIntoDest(p, d, e.typ, ropef("LOC$#.dest", lbl))
|
||||
else:
|
||||
# I prefer the shorter cast version for pointer types -> generate less
|
||||
# C code; plus it's the right thing to do for closures:
|
||||
genSomeCast(p, e, d)
|
||||
|
||||
proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
|
||||
var a: TLoc
|
||||
var dest = skipTypes(n.typ, abstractVar)
|
||||
@@ -1418,7 +1443,7 @@ proc genConv(p: BProc, e: PNode, d: var TLoc) =
|
||||
if compareTypes(e.typ, e.sons[1].typ, dcEqIgnoreDistinct):
|
||||
expr(p, e.sons[1], d)
|
||||
else:
|
||||
genCast(p, e, d)
|
||||
genSomeCast(p, e, d)
|
||||
|
||||
proc convStrToCStr(p: BProc, n: PNode, d: var TLoc) =
|
||||
var a: TLoc
|
||||
@@ -1531,7 +1556,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
let t = e.sons[1].typ.skipTypes({tyTypeDesc})
|
||||
putIntoDest(p, d, e.typ, ropef("((NI)sizeof($1))",
|
||||
[getTypeDesc(p.module, t)]))
|
||||
of mChr: genCast(p, e, d)
|
||||
of mChr: genSomeCast(p, e, d)
|
||||
of mOrd: genOrd(p, e, d)
|
||||
of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray:
|
||||
genArrayLen(p, e, d, op)
|
||||
|
||||
@@ -698,10 +698,17 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
|
||||
if a == nil: return
|
||||
result = a
|
||||
result.typ = n.typ
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkCast:
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
var a = getConstExpr(m, n.sons[1])
|
||||
if a == nil: return
|
||||
result = foldConv(n, a, check=n.kind == nkHiddenStdConv)
|
||||
of nkCast:
|
||||
var a = getConstExpr(m, n.sons[1])
|
||||
if a == nil: return
|
||||
if n.typ.kind in NilableTypes:
|
||||
# we allow compile-time 'cast' for pointer types:
|
||||
result = a
|
||||
result.typ = n.typ
|
||||
of nkBracketExpr: result = foldArrayAccess(m, n)
|
||||
of nkDotExpr: result = foldFieldAccess(m, n)
|
||||
else:
|
||||
|
||||
@@ -16,6 +16,9 @@ Bugfixes
|
||||
or not at all. There is also a new GC you can activate
|
||||
with ``--gc:markAndSweep`` which does not have this problem but is slower in
|
||||
general and has no realtime guarantees.
|
||||
- ``cast`` for floating point types now does the bitcast as specified in the
|
||||
manual. This breaks code that erroneously uses ``cast`` to convert different
|
||||
floating point values.
|
||||
|
||||
|
||||
Library Additions
|
||||
|
||||
Reference in New Issue
Block a user