fixes #837
This commit is contained in:
parent
5ab3542c18
commit
326bdae8ca
6 changed files with 61 additions and 16 deletions
|
|
@ -1872,17 +1872,33 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
expr(p, n.sons[0], d) # downcast does C++ for us
|
expr(p, n.sons[0], d) # downcast does C++ for us
|
||||||
else:
|
else:
|
||||||
var dest = skipTypes(n.typ, abstractPtrs)
|
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
|
var a: TLoc
|
||||||
initLocExpr(p, n.sons[0], a)
|
initLocExpr(p, arg, a)
|
||||||
var r = rdLoc(a)
|
var r = rdLoc(a)
|
||||||
if skipTypes(n.sons[0].typ, abstractInst).kind in {tyRef, tyPtr, tyVar} and
|
let isRef = skipTypes(arg.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}
|
||||||
n.sons[0].kind notin {nkHiddenAddr, nkAddr, nkObjDownConv}:
|
if isRef:
|
||||||
app(r, "->Sup")
|
app(r, "->Sup")
|
||||||
for i in countup(2, abs(inheritanceDiff(dest, src))): app(r, ".Sup")
|
|
||||||
r = con("&", r)
|
|
||||||
else:
|
else:
|
||||||
for i in countup(1, abs(inheritanceDiff(dest, src))): app(r, ".Sup")
|
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)
|
putIntoDest(p, d, n.typ, r)
|
||||||
|
|
||||||
proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
|
proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ proc rdLoc(a: TLoc): PRope =
|
||||||
proc addrLoc(a: TLoc): PRope =
|
proc addrLoc(a: TLoc): PRope =
|
||||||
result = a.r
|
result = a.r
|
||||||
if lfIndirect notin a.flags and mapType(a.t) != ctArray:
|
if lfIndirect notin a.flags and mapType(a.t) != ctArray:
|
||||||
result = con("&", result)
|
result = con("(&", result).con(")")
|
||||||
|
|
||||||
proc rdCharLoc(a: TLoc): PRope =
|
proc rdCharLoc(a: TLoc): PRope =
|
||||||
# read a location that may need a char-cast:
|
# read a location that may need a char-cast:
|
||||||
|
|
|
||||||
|
|
@ -35,3 +35,4 @@ type
|
||||||
cb: proc (future: PFuture[T]) {.closure.}
|
cb: proc (future: PFuture[T]) {.closure.}
|
||||||
|
|
||||||
var k = PFuture[void]()
|
var k = PFuture[void]()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ proc newInstance(T: typedesc): T =
|
||||||
var o = TObj.newInstance()
|
var o = TObj.newInstance()
|
||||||
|
|
||||||
type
|
type
|
||||||
TestObj* = object of TObject
|
TestObj* = object of RootObj
|
||||||
t:int
|
t:int
|
||||||
SubObject* = object of TestObj
|
SubObject* = object of TestObj
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
|
|
||||||
|
# It turned out that it's hard to generate correct for these two test cases at
|
||||||
|
# the same time.
|
||||||
|
|
||||||
type
|
type
|
||||||
TFoo = ref object of TObject
|
TFoo = ref object of RootObj
|
||||||
Data: int
|
Data: int
|
||||||
TBar = ref object of TFoo
|
TBar = ref object of TFoo
|
||||||
nil
|
nil
|
||||||
|
|
@ -26,3 +30,30 @@ var b: TBar2
|
||||||
new(b)
|
new(b)
|
||||||
|
|
||||||
Foo(b)
|
Foo(b)
|
||||||
|
|
||||||
|
# bug #837
|
||||||
|
type
|
||||||
|
PView* = ref TView
|
||||||
|
TView* {.inheritable.} = object
|
||||||
|
data: int
|
||||||
|
|
||||||
|
PWindow* = ref TWindow
|
||||||
|
TWindow* = object of TView
|
||||||
|
data3: int
|
||||||
|
|
||||||
|
PDesktop* = ref TDesktop
|
||||||
|
TDesktop* = object of TView
|
||||||
|
data2: int
|
||||||
|
|
||||||
|
proc makeDesktop(): PDesktop = new(TDesktop)
|
||||||
|
|
||||||
|
proc makeWindow(): PWindow = new(TWindow)
|
||||||
|
|
||||||
|
proc thisCausesError(a: var PView, b: PView) =
|
||||||
|
discard
|
||||||
|
|
||||||
|
var dd = makeDesktop()
|
||||||
|
var aa = makeWindow()
|
||||||
|
|
||||||
|
thisCausesError(dd, aa)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ discard """
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
type
|
type
|
||||||
TFigure = object of TObject # abstract base class:
|
TFigure = object of RootObj # abstract base class:
|
||||||
draw: proc (my: var TFigure) {.nimcall.} # concrete classes implement this
|
draw: proc (my: var TFigure) {.nimcall.} # concrete classes implement this
|
||||||
|
|
||||||
proc init(f: var TFigure) =
|
proc init(f: var TFigure) =
|
||||||
|
|
@ -56,7 +56,7 @@ macro `!` (n: expr): stmt {.immediate.} =
|
||||||
result.add(n[1]) # obj
|
result.add(n[1]) # obj
|
||||||
|
|
||||||
type
|
type
|
||||||
TSocket* = object of TObject
|
TSocket* = object of RootObj
|
||||||
FHost: int # cannot be accessed from the outside of the module
|
FHost: int # cannot be accessed from the outside of the module
|
||||||
# the `F` prefix is a convention to avoid clashes since
|
# the `F` prefix is a convention to avoid clashes since
|
||||||
# the accessors are named `host`
|
# the accessors are named `host`
|
||||||
|
|
@ -84,6 +84,3 @@ r!draw
|
||||||
c!draw()
|
c!draw()
|
||||||
|
|
||||||
#OUT 34[]o 5
|
#OUT 34[]o 5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue