summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2017-09-05 01:03:23 +0200
committerAraq <rumpf_a@web.de>2017-09-05 01:03:23 +0200
commit21e22624a21b7ace0ba8e11aab7e7df583aa0c1e (patch)
tree468fb79fbf4324fb994540dd131edbf0ecf09e26
parent2db96d4f7b2b2698009af7336b3a3dcd61fe7cbd (diff)
downloadNim-21e22624a21b7ace0ba8e11aab7e7df583aa0c1e.tar.gz
fixes #6294
-rw-r--r--compiler/ccgexprs.nim41
-rw-r--r--tests/objects/tobjconstr.nim38
2 files changed, 67 insertions, 12 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 926f30985..4ba85c6b3 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -2237,20 +2237,22 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope =
   else:
     globalError(info, "cannot create null element for: " & $t.kind)
 
-proc getNullValueAux(p: BProc; obj, cons: PNode, result: var Rope) =
+proc getNullValueAux(p: BProc; t: PType; obj, cons: PNode, result: var Rope; count: var int) =
   case obj.kind
   of nkRecList:
-    for i in countup(0, sonsLen(obj) - 1): getNullValueAux(p, obj.sons[i], cons, result)
+    for i in countup(0, sonsLen(obj) - 1):
+      getNullValueAux(p, t, obj.sons[i], cons, result, count)
   of nkRecCase:
-    getNullValueAux(p, obj.sons[0], cons, result)
+    getNullValueAux(p, t, obj.sons[0], cons, result, count)
     for i in countup(1, sonsLen(obj) - 1):
-      getNullValueAux(p, lastSon(obj.sons[i]), cons, result)
+      getNullValueAux(p, t, lastSon(obj.sons[i]), cons, result, count)
   of nkSym:
-    if not result.isNil: result.add ", "
+    if count > 0: result.add ", "
+    inc count
     let field = obj.sym
     for i in 1..<cons.len:
       if cons[i].kind == nkExprColonExpr:
-        if cons[i][0].sym.name == field.name:
+        if cons[i][0].sym.name.id == field.name.id:
           result.add genConstExpr(p, cons[i][1])
           return
       elif i == field.position:
@@ -2261,14 +2263,31 @@ proc getNullValueAux(p: BProc; obj, cons: PNode, result: var Rope) =
   else:
     localError(cons.info, "cannot create null element for: " & $obj)
 
+proc getNullValueAuxT(p: BProc; orig, t: PType; obj, cons: PNode, result: var Rope; count: var int) =
+  var base = t.sons[0]
+  let oldRes = result
+  result.add "{"
+  let oldcount = count
+  if base != nil:
+    base = skipTypes(base, skipPtrs)
+    getNullValueAuxT(p, orig, base, base.n, cons, result, count)
+  elif not isObjLackingTypeField(t) and not p.module.compileToCpp:
+    addf(result, "$1", [genTypeInfo(p.module, orig)])
+    inc count
+  getNullValueAux(p, t, obj, cons, result, count)
+  # do not emit '{}' as that is not valid C:
+  if oldcount == count: result = oldres
+  else: result.add "}"
+
 proc genConstObjConstr(p: BProc; n: PNode): Rope =
-  var length = sonsLen(n)
   result = nil
   let t = n.typ.skipTypes(abstractInst)
-  if not isObjLackingTypeField(t) and not p.module.compileToCpp:
-    addf(result, "{$1}", [genTypeInfo(p.module, t)])
-  getNullValueAux(p, t.n, n, result)
-  result = "{$1}$n" % [result]
+  var count = 0
+  #if not isObjLackingTypeField(t) and not p.module.compileToCpp:
+  #  addf(result, "{$1}", [genTypeInfo(p.module, t)])
+  #  inc count
+  getNullValueAuxT(p, t, t, t.n, n, result, count)
+  #result = "{$1}$n" % [result]
 
 proc genConstSimpleList(p: BProc, n: PNode): Rope =
   var length = sonsLen(n)
diff --git a/tests/objects/tobjconstr.nim b/tests/objects/tobjconstr.nim
index 226fe98f7..12478f621 100644
--- a/tests/objects/tobjconstr.nim
+++ b/tests/objects/tobjconstr.nim
@@ -8,7 +8,14 @@ discard """
 (k: kindA, a: (x: abc, z: [1, 7, 3]), method: ())
 (k: kindA, a: (x: abc, z: [1, 8, 3]), method: ())
 (k: kindA, a: (x: abc, z: [1, 9, 3]), method: ())
-(k: kindA, a: (x: abc, z: [1, 10, 3]), method: ())'''
+(k: kindA, a: (x: abc, z: [1, 10, 3]), method: ())
+(x: 123)
+(x: 123)
+(z: 89, y: 0, x: 128)
+(y: 678, x: 123)
+(y: 678, x: 123)
+(y: 0, x: 123)
+(y: 678, x: 123)'''
 """
 
 type
@@ -39,3 +46,32 @@ proc main() =
 
 main()
 
+# bug #6294
+type
+  A = object of RootObj
+    x*: int
+  B = object of A
+    y*: int
+  BS = object of B
+  C = object of BS
+    z*: int
+# inherited fields are ignored, so no fields are set
+when true:
+  var
+    o: A
+  o = B(x: 123)
+  echo o
+  o = B(y: 678, x: 123)
+  echo o
+
+# inherited fields are ignored
+echo C(x: 128, z: 89)          # (y: 0, x: 0)
+echo B(y: 678, x: 123)  # (y: 678, x: 0)
+echo B(x: 123, y: 678)  # (y: 678, x: 0)
+
+when true:
+  # correct, both with `var` and `let`;
+  var b=B(x: 123)
+  echo b                  # (y: 0, x: 123)
+  b=B(y: 678, x: 123)
+  echo b                  # (y: 678, x: 123)