summary refs log tree commit diff stats
path: root/lib/system/sysstr.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/system/sysstr.nim')
-rwxr-xr-xlib/system/sysstr.nim15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index 5d2113439..55223d6c6 100755
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -204,10 +204,21 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
     # we need to decref here, otherwise the GC leaks!
     when not defined(boehmGC) and not defined(nogc):
       for i in newLen..result.len-1:
+        let len0 = gch.tempStack.len
         forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
                           GenericSeqSize +% (i*%elemSize)),
-                          extGetCellType(result).base, waZctDecRef)
-    # and set the memory to nil:
+                          extGetCellType(result).base, waPush)
+        let len1 = gch.tempStack.len
+        for i in len0 .. <len1:
+          doDecRef(gch.tempStack.d[i], LocalHeap, MaybeCyclic)
+        gch.tempStack.len = len0
+                          
+    # XXX: zeroing out the memory can still result in crashes if a wiped-out
+    # cell is aliased by another pointer (ie proc paramter or a let variable).
+    # This is a tought problem, because even if we don't zeroMem here, in the
+    # presense of user defined destructors, the user will expect the cell to be
+    # "destroyed" thus creating the same problem. We can destoy the cell in the
+    # finalizer of the sequence, but this makes destruction non-deterministic.
     zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +%
            (newLen*%elemSize)), (result.len-%newLen) *% elemSize)
   result.len = newLen