diff options
author | Araq <rumpf_a@web.de> | 2014-11-21 02:26:49 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-11-21 02:26:49 +0100 |
commit | 326bdae8ca14a981f5ab8c553fbba45e28a36082 (patch) | |
tree | d30e680097fb0476e8a0b1d4a4d74e717b93e284 /compiler | |
parent | 5ab3542c1801ba042fbe964245be004c0683abb2 (diff) | |
download | Nim-326bdae8ca14a981f5ab8c553fbba45e28a36082.tar.gz |
fixes #837
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 32 | ||||
-rw-r--r-- | compiler/cgen.nim | 2 |
2 files changed, 25 insertions, 9 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 0bf2359c5..e05828f8f 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1872,18 +1872,34 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) = expr(p, n.sons[0], d) # downcast does C++ for us else: var dest = skipTypes(n.typ, abstractPtrs) - var src = skipTypes(n.sons[0].typ, abstractPtrs) + + var arg = n.sons[0] + while arg.kind == nkObjDownConv: arg = arg.sons[0] + + var src = skipTypes(arg.typ, abstractPtrs) var a: TLoc - initLocExpr(p, n.sons[0], a) + initLocExpr(p, arg, a) var r = rdLoc(a) - if skipTypes(n.sons[0].typ, abstractInst).kind in {tyRef, tyPtr, tyVar} and - n.sons[0].kind notin {nkHiddenAddr, nkAddr, nkObjDownConv}: + let isRef = skipTypes(arg.typ, abstractInst).kind in {tyRef, tyPtr, tyVar} + if isRef: app(r, "->Sup") - for i in countup(2, abs(inheritanceDiff(dest, src))): app(r, ".Sup") - r = con("&", r) else: - for i in countup(1, abs(inheritanceDiff(dest, src))): app(r, ".Sup") - putIntoDest(p, d, n.typ, r) + app(r, ".Sup") + for i in countup(2, abs(inheritanceDiff(dest, src))): app(r, ".Sup") + if isRef: + # it can happen that we end up generating '&&x->Sup' here, so we pack + # the '&x->Sup' into a temporary and then those address is taken + # (see bug #837). However sometimes using a temporary is not correct: + # init(TFigure(my)) # where it is passed to a 'var TFigure'. We test + # this by ensuring the destination is also a pointer: + if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}: + getTemp(p, n.typ, d) + linefmt(p, cpsStmts, "$1 = &$2;$n", rdLoc(d), r) + else: + r = con("&", r) + putIntoDest(p, d, n.typ, r) + else: + putIntoDest(p, d, n.typ, r) proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) = var t = getUniqueType(n.typ) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 112203ef1..b00c0b0a7 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -310,7 +310,7 @@ proc rdLoc(a: TLoc): PRope = proc addrLoc(a: TLoc): PRope = result = a.r if lfIndirect notin a.flags and mapType(a.t) != ctArray: - result = con("&", result) + result = con("(&", result).con(")") proc rdCharLoc(a: TLoc): PRope = # read a location that may need a char-cast: |