summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/system/assign.nim10
-rw-r--r--tests/gc/gcleak4.nim4
-rw-r--r--todo.txt2
3 files changed, 11 insertions, 5 deletions
diff --git a/lib/system/assign.nim b/lib/system/assign.nim
index 429a92d34..78995954f 100644
--- a/lib/system/assign.nim
+++ b/lib/system/assign.nim
@@ -27,7 +27,7 @@ proc genericAssignAux(dest, src: pointer, n: ptr TNimNode,
     var m = selectBranch(src, n)
     # reset if different branches are in use; note different branches also
     # imply that's not self-assignment (``x = x``)!
-    if m != dd and dd != nil: 
+    if m != dd and dd != nil:
       genericResetAux(dest, dd)
     copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
             n.typ.size)
@@ -205,9 +205,13 @@ proc genericReset(dest: pointer, mt: PNimType) =
   case mt.kind
   of tyString, tyRef, tySequence:
     unsureAsgnRef(cast[PPointer](dest), nil)
-  of tyObject, tyTuple:
-    # we don't need to reset m_type field for tyObject
+  of tyTuple:
+    genericResetAux(dest, mt.node)
+  of tyObject:
     genericResetAux(dest, mt.node)
+    # also reset the type field for tyObject, for correct branch switching!
+    var pint = cast[ptr PNimType](dest)
+    pint[] = nil
   of tyArray, tyArrayConstr:
     for i in 0..(mt.size div mt.base.size)-1:
       genericReset(cast[pointer](d +% i*% mt.base.size), mt.base)
diff --git a/tests/gc/gcleak4.nim b/tests/gc/gcleak4.nim
index 6f2b8a1fe..54e74ac7b 100644
--- a/tests/gc/gcleak4.nim
+++ b/tests/gc/gcleak4.nim
@@ -38,12 +38,14 @@ proc newPlus(a, b: ref TExpr): ref TPlusExpr =
   result.b = b
   result.op2 = $getOccupiedMem()
 
+const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 500_000
+
 for i in 0..100_000:
   var s: array[0..11, ref TExpr]
   for j in 0..high(s):
     s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4))
     if eval(s[j]) != j+6:
       quit "error: wrong result"
-  if getOccupiedMem() > 500_000: quit("still a leak!")
+  if getOccupiedMem() > Limit: quit("still a leak!")
 
 echo "no leak: ", getOccupiedMem()
diff --git a/todo.txt b/todo.txt
index fca43ad11..1c10fef8a 100644
--- a/todo.txt
+++ b/todo.txt
@@ -5,6 +5,7 @@ version 0.10.4
 - improve GC-unsafety warnings
 - get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}'
 - improve documentation (theindex!)
+- ensure (ref T)(a, b) works as a type conversion and type constructor
 
 
 version 1.0
@@ -66,7 +67,6 @@ version 0.9.x
 - memory manager: add a measure of fragmentation
 - implement 'bits' pragmas
 - we need a magic thisModule symbol
-- ensure (ref T)(a, b) works as a type conversion and type constructor
 - optimize 'genericReset'; 'newException' leads to code bloat
 - The 'do' notation might be trimmed so that its only purpose is to pass
   multiple multi line constructs to a macro.