[bugfix] VM: finally do inheritance properly

This commit is contained in:
Araq 2019-07-12 12:15:30 +02:00
commit 7606efc0bf
2 changed files with 36 additions and 21 deletions

View file

@ -1719,19 +1719,24 @@ proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
else: else:
genArrAccess2(c, n, dest, opcLdArr, flags) genArrAccess2(c, n, dest, opcLdArr, flags)
proc getNullValueAux(obj: PNode, result: PNode; conf: ConfigRef) = proc getNullValueAux(t: PType; obj: PNode, result: PNode; conf: ConfigRef; currPosition: var int) =
if t != nil and t.len > 0 and t.sons[0] != nil:
let b = skipTypes(t.sons[0], skipPtrs)
getNullValueAux(b, b.n, result, conf, currPosition)
case obj.kind case obj.kind
of nkRecList: of nkRecList:
for i in 0 ..< sonsLen(obj): getNullValueAux(obj.sons[i], result, conf) for i in 0 ..< sonsLen(obj): getNullValueAux(nil, obj.sons[i], result, conf, currPosition)
of nkRecCase: of nkRecCase:
getNullValueAux(obj.sons[0], result, conf) getNullValueAux(nil, obj.sons[0], result, conf, currPosition)
for i in 1 ..< sonsLen(obj): for i in 1 ..< sonsLen(obj):
getNullValueAux(lastSon(obj.sons[i]), result, conf) getNullValueAux(nil, lastSon(obj.sons[i]), result, conf, currPosition)
of nkSym: of nkSym:
let field = newNodeI(nkExprColonExpr, result.info) let field = newNodeI(nkExprColonExpr, result.info)
field.add(obj) field.add(obj)
field.add(getNullValue(obj.sym.typ, result.info, conf)) field.add(getNullValue(obj.sym.typ, result.info, conf))
addSon(result, field) addSon(result, field)
doAssert obj.sym.position == currPosition
inc currPosition
else: globalError(conf, result.info, "cannot create null element for: " & $obj) else: globalError(conf, result.info, "cannot create null element for: " & $obj)
proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
@ -1759,13 +1764,9 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
of tyObject: of tyObject:
result = newNodeIT(nkObjConstr, info, t) result = newNodeIT(nkObjConstr, info, t)
result.add(newNodeIT(nkEmpty, info, t)) result.add(newNodeIT(nkEmpty, info, t))
# initialize inherited fields: # initialize inherited fields, and all in the correct order:
var base = t.sons[0] var currPosition = 0
while base != nil: getNullValueAux(t, t.n, result, conf, currPosition)
let b = skipTypes(base, skipPtrs)
getNullValueAux(b.n, result, conf)
base = b.sons[0]
getNullValueAux(t.n, result, conf)
of tyArray: of tyArray:
result = newNodeIT(nkBracket, info, t) result = newNodeIT(nkBracket, info, t)
for i in 0 ..< int(lengthOrd(conf, t)): for i in 0 ..< int(lengthOrd(conf, t)):

View file

@ -1,6 +1,7 @@
discard """ discard """
nimout: '''Hello fred, managed by sally nimout: '''Hello fred, managed by sally
Hello sally , managed by bob''' Hello sally, managed by bob
0'''
""" """
# bug #3973 # bug #3973
@ -78,3 +79,16 @@ check_proc(bb, kB)
let cc = new(C) let cc = new(C)
check_templ(cc, kC) check_templ(cc, kC)
check_proc(cc, kC) check_proc(cc, kC)
type
BBar = object of RootObj
bbarField: set[char]
xbarField: string
d, e: int
FooBar = object of BBar
a: int
b: string
static:
var fb: FooBar
echo fb.a