parent
3ce27511ad
commit
3cbc80045d
3 changed files with 41 additions and 32 deletions
|
|
@ -2577,40 +2577,32 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
[getTypeDesc(p.module, dest), addrLoc(p.config, a)], a.storage)
|
[getTypeDesc(p.module, dest), addrLoc(p.config, a)], a.storage)
|
||||||
|
|
||||||
proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
if p.module.compileToCpp:
|
|
||||||
discard getTypeDesc(p.module, skipTypes(n[0].typ, abstractPtrs))
|
|
||||||
expr(p, n[0], d) # downcast does C++ for us
|
|
||||||
else:
|
|
||||||
var dest = skipTypes(n.typ, abstractPtrs)
|
|
||||||
|
|
||||||
var arg = n[0]
|
var arg = n[0]
|
||||||
while arg.kind == nkObjDownConv: arg = arg[0]
|
while arg.kind == nkObjDownConv: arg = arg[0]
|
||||||
|
|
||||||
var src = skipTypes(arg.typ, abstractPtrs)
|
let dest = skipTypes(n.typ, abstractPtrs)
|
||||||
|
let src = skipTypes(arg.typ, abstractPtrs)
|
||||||
discard getTypeDesc(p.module, src)
|
discard getTypeDesc(p.module, src)
|
||||||
var a: TLoc
|
|
||||||
initLocExpr(p, arg, a)
|
|
||||||
var r = rdLoc(a)
|
|
||||||
let isRef = skipTypes(arg.typ, abstractInstOwned).kind in {tyRef, tyPtr, tyVar, tyLent}
|
let isRef = skipTypes(arg.typ, abstractInstOwned).kind in {tyRef, tyPtr, tyVar, tyLent}
|
||||||
if isRef:
|
if isRef and d.k == locNone and n.typ.skipTypes(abstractInstOwned).kind in {tyRef, tyPtr} and n.isLValue:
|
||||||
r.add("->Sup")
|
|
||||||
else:
|
|
||||||
r.add(".Sup")
|
|
||||||
for i in 2..abs(inheritanceDiff(dest, src)): r.add(".Sup")
|
|
||||||
if isRef:
|
|
||||||
# it can happen that we end up generating '&&x->Sup' here, so we pack
|
# 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
|
# the '&x->Sup' into a temporary and then those address is taken
|
||||||
# (see bug #837). However sometimes using a temporary is not correct:
|
# (see bug #837). However sometimes using a temporary is not correct:
|
||||||
# init(TFigure(my)) # where it is passed to a 'var TFigure'. We test
|
# init(TFigure(my)) # where it is passed to a 'var TFigure'. We test
|
||||||
# this by ensuring the destination is also a pointer:
|
# this by ensuring the destination is also a pointer:
|
||||||
if d.k == locNone and skipTypes(n.typ, abstractInstOwned).kind in {tyRef, tyPtr, tyVar, tyLent}:
|
var a: TLoc
|
||||||
getTemp(p, n.typ, d)
|
initLocExpr(p, arg, a)
|
||||||
linefmt(p, cpsStmts, "$1 = &$2;$n", [rdLoc(d), r])
|
putIntoDest(p, d, n,
|
||||||
|
"(*(($1*) (&($2))))" % [getTypeDesc(p.module, n.typ), rdLoc(a)], a.storage)
|
||||||
|
elif p.module.compileToCpp:
|
||||||
|
# C++ implicitly downcasts for us
|
||||||
|
expr(p, arg, d)
|
||||||
else:
|
else:
|
||||||
r = "&" & r
|
var a: TLoc
|
||||||
putIntoDest(p, d, n, r, a.storage)
|
initLocExpr(p, arg, a)
|
||||||
else:
|
var r = rdLoc(a) & (if isRef: "->Sup" else: ".Sup")
|
||||||
putIntoDest(p, d, n, r, a.storage)
|
for i in 2..abs(inheritanceDiff(dest, src)): r.add(".Sup")
|
||||||
|
putIntoDest(p, d, n, if isRef: "&" & r else: r, a.storage)
|
||||||
|
|
||||||
proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
|
proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
|
||||||
let t = n.typ
|
let t = n.typ
|
||||||
|
|
|
||||||
|
|
@ -1143,9 +1143,9 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||||
gcomma(g, n)
|
gcomma(g, n)
|
||||||
put(g, tkParRi, ")")
|
put(g, tkParRi, ")")
|
||||||
of nkObjDownConv, nkObjUpConv:
|
of nkObjDownConv, nkObjUpConv:
|
||||||
|
let typ = if (n.typ != nil) and (n.typ.sym != nil): n.typ.sym.name.s else: ""
|
||||||
|
put(g, tkParLe, typ & "(")
|
||||||
if n.len >= 1: gsub(g, n[0])
|
if n.len >= 1: gsub(g, n[0])
|
||||||
put(g, tkParLe, "(")
|
|
||||||
gcomma(g, n, 1)
|
|
||||||
put(g, tkParRi, ")")
|
put(g, tkParRi, ")")
|
||||||
of nkClosedSymChoice, nkOpenSymChoice:
|
of nkClosedSymChoice, nkOpenSymChoice:
|
||||||
if renderIds in g.flags:
|
if renderIds in g.flags:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
discard """
|
||||||
|
matrix: "--gc:refc; --gc:arc"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #14160
|
||||||
|
|
||||||
type
|
type
|
||||||
TPassContext = object of RootObj
|
TPassContext = object of RootObj
|
||||||
PPassContext = ref TPassContext
|
PPassContext = ref TPassContext
|
||||||
|
|
@ -11,5 +17,16 @@ type
|
||||||
proc main() =
|
proc main() =
|
||||||
var g = ModuleGraph(vm: new(Pctx))
|
var g = ModuleGraph(vm: new(Pctx))
|
||||||
PCtx(g.vm) = nil #This generates invalid C code
|
PCtx(g.vm) = nil #This generates invalid C code
|
||||||
|
doAssert g.vm == nil
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
# bug #14325
|
||||||
|
|
||||||
|
proc main2() =
|
||||||
|
var g = ModuleGraph(vm: new(Pctx))
|
||||||
|
PPassContext(PCtx(g.vm)) = nil #This compiles, but crashes at runtime with gc:arc
|
||||||
|
doAssert g.vm == nil
|
||||||
|
|
||||||
|
main2()
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue