diff options
author | Araq <rumpf_a@web.de> | 2013-05-19 02:49:10 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-05-19 02:49:10 +0200 |
commit | 38ed2373aba94832db01e387c592915c8eec4e60 (patch) | |
tree | a96c41d8fa14852a411356ef3ffa6a05689a5c2d /compiler | |
parent | 62c80cd570dfcfbb3117e09dea90f4fa10eec33b (diff) | |
download | Nim-38ed2373aba94832db01e387c592915c8eec4e60.tar.gz |
fixes #432, fixes #427
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 31 | ||||
-rw-r--r-- | compiler/semfold.nim | 9 |
2 files changed, 36 insertions, 4 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 3a419393d..410e65ac9 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -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) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index cc1f4b5ee..6fdb780c9 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -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: |