diff options
-rw-r--r-- | compiler/vmgen.nim | 23 | ||||
-rw-r--r-- | tests/vm/tinheritance.nim | 34 |
2 files changed, 36 insertions, 21 deletions
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index e63eb1fd9..37706f1ea 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1719,19 +1719,24 @@ proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) = else: 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 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: - getNullValueAux(obj.sons[0], result, conf) + getNullValueAux(nil, obj.sons[0], result, conf, currPosition) for i in 1 ..< sonsLen(obj): - getNullValueAux(lastSon(obj.sons[i]), result, conf) + getNullValueAux(nil, lastSon(obj.sons[i]), result, conf, currPosition) of nkSym: let field = newNodeI(nkExprColonExpr, result.info) field.add(obj) field.add(getNullValue(obj.sym.typ, result.info, conf)) addSon(result, field) + doAssert obj.sym.position == currPosition + inc currPosition else: globalError(conf, result.info, "cannot create null element for: " & $obj) proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = @@ -1759,13 +1764,9 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = of tyObject: result = newNodeIT(nkObjConstr, info, t) result.add(newNodeIT(nkEmpty, info, t)) - # initialize inherited fields: - var base = t.sons[0] - while base != nil: - let b = skipTypes(base, skipPtrs) - getNullValueAux(b.n, result, conf) - base = b.sons[0] - getNullValueAux(t.n, result, conf) + # initialize inherited fields, and all in the correct order: + var currPosition = 0 + getNullValueAux(t, t.n, result, conf, currPosition) of tyArray: result = newNodeIT(nkBracket, info, t) for i in 0 ..< int(lengthOrd(conf, t)): diff --git a/tests/vm/tinheritance.nim b/tests/vm/tinheritance.nim index a94ccafcd..2a98ed923 100644 --- a/tests/vm/tinheritance.nim +++ b/tests/vm/tinheritance.nim @@ -1,6 +1,7 @@ discard """ - nimout: '''Hello fred , managed by sally -Hello sally , managed by bob''' + nimout: '''Hello fred, managed by sally +Hello sally, managed by bob +0''' """ # bug #3973 @@ -10,20 +11,20 @@ type ecCode2 Person* = object of RootObj - name* : string + name*: string last_name*: string Employee* = object of Person - empl_code* : EmployeeCode - mgr_name* : string + empl_code*: EmployeeCode + mgr_name*: string proc test() = var empl1 = Employee(name: "fred", last_name: "smith", mgr_name: "sally", empl_code: ecCode1) empl2 = Employee(name: "sally", last_name: "jones", mgr_name: "bob", empl_code: ecCode2) - echo "Hello ", empl1.name, " , managed by ", empl1.mgr_name - echo "Hello ", empl2.name, " , managed by ", empl2.mgr_name + echo "Hello ", empl1.name, ", managed by ", empl1.mgr_name + echo "Hello ", empl2.name, ", managed by ", empl2.mgr_name static: test() @@ -50,13 +51,13 @@ template check_templ(n: Base, k: MyKind) = if k == kA: doAssert(n of A) else: doAssert(not (n of A)) if k in {kB, kC}: doAssert(n of B) else: doAssert(not (n of B)) if k == kC: doAssert(n of C) else: doAssert(not (n of C)) - doAssert(n of Base) + doAssert(n of Base) proc check_proc(n: Base, k: MyKind) = if k == kA: doAssert(n of A) else: doAssert(not (n of A)) if k in {kB, kC}: doAssert(n of B) else: doAssert(not (n of B)) if k == kC: doAssert(n of C) else: doAssert(not (n of C)) - doAssert(n of Base) + doAssert(n of Base) static: let aa = new(A) @@ -68,7 +69,7 @@ static: let cc = new(C) check_templ(cc, kC) check_proc(cc, kC) - + let aa = new(A) check_templ(aa, kA) check_proc(aa, kA) @@ -78,3 +79,16 @@ check_proc(bb, kB) let cc = new(C) check_templ(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 |