mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
@@ -2577,40 +2577,32 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||
[getTypeDesc(p.module, dest), addrLoc(p.config, a)], a.storage)
|
||||
|
||||
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]
|
||||
while arg.kind == nkObjDownConv: arg = arg[0]
|
||||
|
||||
var arg = n[0]
|
||||
while arg.kind == nkObjDownConv: arg = arg[0]
|
||||
|
||||
var src = skipTypes(arg.typ, abstractPtrs)
|
||||
discard getTypeDesc(p.module, src)
|
||||
let dest = skipTypes(n.typ, abstractPtrs)
|
||||
let src = skipTypes(arg.typ, abstractPtrs)
|
||||
discard getTypeDesc(p.module, src)
|
||||
let isRef = skipTypes(arg.typ, abstractInstOwned).kind in {tyRef, tyPtr, tyVar, tyLent}
|
||||
if isRef and d.k == locNone and n.typ.skipTypes(abstractInstOwned).kind in {tyRef, tyPtr} and n.isLValue:
|
||||
# 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:
|
||||
var a: TLoc
|
||||
initLocExpr(p, arg, a)
|
||||
var r = rdLoc(a)
|
||||
let isRef = skipTypes(arg.typ, abstractInstOwned).kind in {tyRef, tyPtr, tyVar, tyLent}
|
||||
if isRef:
|
||||
r.add("->Sup")
|
||||
else:
|
||||
r.add(".Sup")
|
||||
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:
|
||||
var a: TLoc
|
||||
initLocExpr(p, arg, a)
|
||||
var r = rdLoc(a) & (if isRef: "->Sup" else: ".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
|
||||
# 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, abstractInstOwned).kind in {tyRef, tyPtr, tyVar, tyLent}:
|
||||
getTemp(p, n.typ, d)
|
||||
linefmt(p, cpsStmts, "$1 = &$2;$n", [rdLoc(d), r])
|
||||
else:
|
||||
r = "&" & r
|
||||
putIntoDest(p, d, n, r, a.storage)
|
||||
else:
|
||||
putIntoDest(p, d, n, r, a.storage)
|
||||
putIntoDest(p, d, n, if isRef: "&" & r else: r, a.storage)
|
||||
|
||||
proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
|
||||
let t = n.typ
|
||||
|
||||
@@ -1143,9 +1143,9 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||
gcomma(g, n)
|
||||
put(g, tkParRi, ")")
|
||||
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])
|
||||
put(g, tkParLe, "(")
|
||||
gcomma(g, n, 1)
|
||||
put(g, tkParRi, ")")
|
||||
of nkClosedSymChoice, nkOpenSymChoice:
|
||||
if renderIds in g.flags:
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
discard """
|
||||
matrix: "--gc:refc; --gc:arc"
|
||||
"""
|
||||
|
||||
# bug #14160
|
||||
|
||||
type
|
||||
TPassContext = object of RootObj
|
||||
PPassContext = ref TPassContext
|
||||
@@ -11,5 +17,16 @@ type
|
||||
proc main() =
|
||||
var g = ModuleGraph(vm: new(Pctx))
|
||||
PCtx(g.vm) = nil #This generates invalid C code
|
||||
doAssert g.vm == nil
|
||||
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user