This commit is contained in:
Araq
2013-05-19 02:49:10 +02:00
parent 62c80cd570
commit 38ed2373ab
3 changed files with 39 additions and 4 deletions

View File

@@ -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)

View File

@@ -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:

View File

@@ -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