summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vmgen.nim23
-rw-r--r--tests/vm/tinheritance.nim34
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