summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/lowerings.nim8
-rw-r--r--compiler/sempass2.nim5
-rw-r--r--lib/core/runtime_v2.nim7
-rw-r--r--tests/destructor/tarc.nim (renamed from tests/destructor/tlists.nim)17
4 files changed, 32 insertions, 5 deletions
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim
index d372ac0c1..0922ab088 100644
--- a/compiler/lowerings.nim
+++ b/compiler/lowerings.nim
@@ -150,11 +150,18 @@ proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType
   s.typ = result
   result.sym = s
 
+template fieldCheck {.dirty.} =
+  when false:
+    if tfCheckedForDestructor in obj.flags:
+      echo "missed field ", field.name.s
+      writeStackTrace()
+
 proc rawAddField*(obj: PType; field: PSym) =
   assert field.kind == skField
   field.position = len(obj.n)
   addSon(obj.n, newSymNode(field))
   propagateToOwner(obj, field.typ)
+  fieldCheck()
 
 proc rawIndirectAccess*(a: PNode; field: PSym; info: TLineInfo): PNode =
   # returns a[].field as a node
@@ -208,6 +215,7 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache) =
   propagateToOwner(obj, t)
   field.position = len(obj.n)
   addSon(obj.n, newSymNode(field))
+  fieldCheck()
 
 proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable.} =
   result = lookupInRecord(obj.n, s.id)
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index ef0dcec00..00afb737d 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -855,6 +855,8 @@ proc track(tracked: PEffects, n: PNode) =
       if x.sons[0].kind == nkSym and sfDiscriminant in x.sons[0].sym.flags:
         addDiscriminantFact(tracked.guards, x)
     setLen(tracked.guards.s, oldFacts)
+    if tracked.owner.kind != skMacro:
+      createTypeBoundOps(tracked, n.typ, n.info)
   of nkPragmaBlock:
     let pragmaList = n.sons[0]
     let oldLocked = tracked.locked.len
@@ -885,7 +887,8 @@ proc track(tracked: PEffects, n: PNode) =
     if n.len == 1: track(tracked, n.sons[0])
   of nkBracket:
     for i in 0 ..< safeLen(n): track(tracked, n.sons[i])
-    createTypeBoundOps(tracked, n.typ, n.info)
+    if tracked.owner.kind != skMacro:
+      createTypeBoundOps(tracked, n.typ, n.info)
   else:
     for i in 0 ..< safeLen(n): track(tracked, n.sons[i])
 
diff --git a/lib/core/runtime_v2.nim b/lib/core/runtime_v2.nim
index 0d55ff4ac..3dd4a77c6 100644
--- a/lib/core/runtime_v2.nim
+++ b/lib/core/runtime_v2.nim
@@ -68,6 +68,7 @@ proc nimIncRef(p: pointer) {.compilerRtl, inl.} =
     atomicInc head(p).rc
   else:
     inc head(p).rc
+    #cprintf("[INCREF] %p\n", p)
 
 proc nimRawDispose(p: pointer) {.compilerRtl.} =
   when not defined(nimscript):
@@ -113,13 +114,15 @@ proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} =
       if atomicLoadN(addr head(p).rc, ATOMIC_RELAXED) == 0:
         result = true
       else:
-        if atomicDec(head(p).rc) <= 0:
-          result = true
+        discard atomicDec(head(p).rc)
     else:
       if head(p).rc == 0:
         result = true
+        #cprintf("[DESTROY] %p\n", p)
       else:
         dec head(p).rc
+        # According to Lins it's correct to do nothing else here.
+        #cprintf("[DeCREF] %p\n", p)
 
 proc GC_unref*[T](x: ref T) =
   ## New runtime only supports this operation for 'ref T'.
diff --git a/tests/destructor/tlists.nim b/tests/destructor/tarc.nim
index f5786d936..5c78605d2 100644
--- a/tests/destructor/tlists.nim
+++ b/tests/destructor/tarc.nim
@@ -4,7 +4,7 @@ discard """
 Success
 @["a", "b", "c"]
 0'''
-  cmd: '''nim c --gc:destructors $file'''
+  cmd: '''nim c --gc:arc $file'''
 """
 
 import os
@@ -69,10 +69,23 @@ proc take3 =
   for x in infinite.take(3):
     discard
 
+
+type
+  A = ref object of RootObj
+    x: int
+
+  B = ref object of A
+    more: string
+
+proc inheritanceBug(param: string) =
+  var s: (A, A)
+  s[0] = B(more: "a" & param)
+  s[1] = B(more: "a" & param)
+
 let startMem = getOccupiedMem()
 take3()
 tlazyList()
-
+inheritanceBug("whatever")
 mkManyLeaks()
 tsimpleClosureIterator()
 tleakingNewStmt()