diff options
Diffstat (limited to 'tests/destructor')
-rw-r--r-- | tests/destructor/const_smart_ptr.nim | 10 | ||||
-rw-r--r-- | tests/destructor/t23748.nim | 31 | ||||
-rw-r--r-- | tests/destructor/t23837.nim | 51 | ||||
-rw-r--r-- | tests/destructor/tatomicptrs.nim | 2 | ||||
-rw-r--r-- | tests/destructor/tdistinctseq.nim | 8 | ||||
-rw-r--r-- | tests/destructor/tgotoexc_leak.nim | 19 | ||||
-rw-r--r-- | tests/destructor/tmove.nim | 18 | ||||
-rw-r--r-- | tests/destructor/tmove_objconstr.nim | 35 | ||||
-rw-r--r-- | tests/destructor/tnonvardestructor.nim | 31 | ||||
-rw-r--r-- | tests/destructor/tsink.nim | 70 | ||||
-rw-r--r-- | tests/destructor/tv2_cast.nim | 52 |
11 files changed, 262 insertions, 65 deletions
diff --git a/tests/destructor/const_smart_ptr.nim b/tests/destructor/const_smart_ptr.nim index 4d8c7c9a3..25dd46500 100644 --- a/tests/destructor/const_smart_ptr.nim +++ b/tests/destructor/const_smart_ptr.nim @@ -2,13 +2,12 @@ type ConstPtr*[T] = object val: ptr T -proc `=destroy`*[T](p: var ConstPtr[T]) = +proc `=destroy`*[T](p: ConstPtr[T]) = if p.val != nil: `=destroy`(p.val[]) dealloc(p.val) - p.val = nil -proc `=`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.error.} +proc `=copy`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.error.} proc `=sink`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.inline.} = if dest.val != nil and dest.val != src.val: @@ -31,12 +30,11 @@ type len: int data: ptr UncheckedArray[float] -proc `=destroy`*(m: var MySeqNonCopyable) {.inline.} = +proc `=destroy`*(m: MySeqNonCopyable) {.inline.} = if m.data != nil: deallocShared(m.data) - m.data = nil -proc `=`*(m: var MySeqNonCopyable, m2: MySeqNonCopyable) {.error.} +proc `=copy`*(m: var MySeqNonCopyable, m2: MySeqNonCopyable) {.error.} proc `=sink`*(m: var MySeqNonCopyable, m2: MySeqNonCopyable) {.inline.} = if m.data != m2.data: diff --git a/tests/destructor/t23748.nim b/tests/destructor/t23748.nim new file mode 100644 index 000000000..a3738733e --- /dev/null +++ b/tests/destructor/t23748.nim @@ -0,0 +1,31 @@ +discard """ + matrix: "--gc:refc; --gc:arc" + output: ''' +hello 42 +hello 42 +len = 2 +''' +""" + +# bug #23748 + +type + O = ref object + s: string + cb: seq[proc()] + +proc push1(o: O, i: int) = + let o = o + echo o.s, " ", i + o.cb.add(proc() = echo o.s, " ", i) + +proc push2(o: O, i: int) = + let o = o + echo o.s, " ", i + proc p() = echo o.s, " ", i + o.cb.add(p) + +let o = O(s: "hello", cb: @[]) +o.push1(42) +o.push2(42) +echo "len = ", o.cb.len diff --git a/tests/destructor/t23837.nim b/tests/destructor/t23837.nim new file mode 100644 index 000000000..e219dd6b5 --- /dev/null +++ b/tests/destructor/t23837.nim @@ -0,0 +1,51 @@ +discard """ + output: ''' +Deallocating OwnedString +HelloWorld +''' + matrix: "--cursorinference:on; --cursorinference:off" + target: "c" +""" + +# bug #23837 +{. + emit: [ + """ +#include <stdlib.h> +#include <string.h> +char *allocCString() { + char *result = (char *) malloc(10 + 1); + strcpy(result, "HelloWorld"); + return result; +} + +""" + ] +.} + +proc rawWrapper(): cstring {.importc: "allocCString", cdecl.} +proc free(p: pointer) {.importc: "free", cdecl.} + +# ------------------------- + +type OwnedString = distinct cstring + +proc `=destroy`(s: OwnedString) = + free(cstring s) + echo "Deallocating OwnedString" + +func `$`(s: OwnedString): string {.borrow.} + +proc leakyWrapper(): string = + let ostring = rawWrapper().OwnedString + $ostring + +# ------------------------- + +proc main() = + # destructor not called - definitely lost: 11 bytes in 1 blocks + # doesn't leak with --cursorInference:off + let s = leakyWrapper() + echo s + +main() \ No newline at end of file diff --git a/tests/destructor/tatomicptrs.nim b/tests/destructor/tatomicptrs.nim index 7bd5482b2..82870ac82 100644 --- a/tests/destructor/tatomicptrs.nim +++ b/tests/destructor/tatomicptrs.nim @@ -143,11 +143,13 @@ proc `=sink`*[T](m: var MySeq[T], m2: MySeq[T]) {.inline.} = `=destroy`(m) m.len = m2.len m.data = m2.data + m.refcount = m2.refcount proc len*[T](m: MySeq[T]): int {.inline.} = m.len proc newMySeq*[T](size: int, initial_value: T): MySeq[T] = result.len = size + result.refcount = 1 if size > 0: result.data = cast[ptr UncheckedArray[T]](allocShared(sizeof(T) * size)) diff --git a/tests/destructor/tdistinctseq.nim b/tests/destructor/tdistinctseq.nim new file mode 100644 index 000000000..5a2ac5ead --- /dev/null +++ b/tests/destructor/tdistinctseq.nim @@ -0,0 +1,8 @@ +discard """ + matrix: "-u:nimPreviewNonVarDestructor;" +""" +type DistinctSeq* = distinct seq[int] + +# `=destroy`(cast[ptr DistinctSeq](0)[]) +var x = @[].DistinctSeq +`=destroy`(x) diff --git a/tests/destructor/tgotoexc_leak.nim b/tests/destructor/tgotoexc_leak.nim new file mode 100644 index 000000000..c8a234085 --- /dev/null +++ b/tests/destructor/tgotoexc_leak.nim @@ -0,0 +1,19 @@ +discard """ + output: '''0 +true''' + cmd: "nim c --gc:arc $file" +""" + +# bug #22398 + +for i in 0 ..< 10_000: + try: + try: + raise newException(ValueError, "") + except CatchableError: + discard + raise newException(ValueError, "") # or raise getCurrentException(), just raise works ok + except ValueError: + discard +echo getOccupiedMem() +echo getCurrentException() == nil diff --git a/tests/destructor/tmove.nim b/tests/destructor/tmove.nim new file mode 100644 index 000000000..2762aff90 --- /dev/null +++ b/tests/destructor/tmove.nim @@ -0,0 +1,18 @@ +discard """ + targets: "c cpp" +""" + +block: + var called = 0 + + proc bar(a: var int): var int = + inc called + result = a + + proc foo = + var a = 2 + var s = move bar(a) + doAssert called == 1 + doAssert s == 2 + + foo() diff --git a/tests/destructor/tmove_objconstr.nim b/tests/destructor/tmove_objconstr.nim index a583a1704..cdc1eb1c0 100644 --- a/tests/destructor/tmove_objconstr.nim +++ b/tests/destructor/tmove_objconstr.nim @@ -137,28 +137,29 @@ doAssert seq3[0] == 1.0 var seq4, seq5: MySeqNonCopyable (seq4, i, seq5) = myfunc2(2, 3) -seq4 = block: - var tmp = newMySeq(4, 1.0) - tmp[0] = 3.0 - tmp +proc foo = + seq4 = block: + var tmp = newMySeq(4, 1.0) + tmp[0] = 3.0 + tmp -doAssert seq4[0] == 3.0 + doAssert seq4[0] == 3.0 -import macros -seq4 = - if i > 0: newMySeq(2, 5.0) - elif i < -100: raise newException(ValueError, "Parse Error") - else: newMySeq(2, 3.0) + seq4 = + if i > 0: newMySeq(2, 5.0) + elif i < -100: raise newException(ValueError, "Parse Error") + else: newMySeq(2, 3.0) -seq4 = - case (char) i: - of 'A', {'W'..'Z'}: newMySeq(2, 5.0) - of 'B': quit(-1) - else: - let (x1, x2, x3) = myfunc2(2, 3) - x3 + seq4 = + case (char) i: + of 'A', {'W'..'Z'}: newMySeq(2, 5.0) + of 'B': quit(-1) + else: + let (x1, x2, x3) = myfunc2(2, 3) + x3 +foo() #------------------------------------------------------------ #-- Move into array constructor diff --git a/tests/destructor/tnonvardestructor.nim b/tests/destructor/tnonvardestructor.nim index 1f59a3978..1b4413790 100644 --- a/tests/destructor/tnonvardestructor.nim +++ b/tests/destructor/tnonvardestructor.nim @@ -152,7 +152,7 @@ type Graph = object nodes: seq[Node] -proc `=destroy`(x: var NodeObj) = +proc `=destroy`(x: NodeObj) = `=destroy`(x.neighbors) `=destroy`(x.label) @@ -210,7 +210,7 @@ block: # bug #22197 ## If this does not exist, it also works! proc newFileID(): FileID = FileID(H5Id()) - proc `=destroy`(grp: var H5GroupObj) = + proc `=destroy`(grp: H5GroupObj) = ## Closes the group and resets all references to nil. if cast[pointer](grp.fileId) != nil: `=destroy`(grp.file_id) @@ -218,3 +218,30 @@ block: # bug #22197 var grp = H5Group() reset(grp.file_id) reset(grp) + +import std/tables + +block: # bug #22286 + type + A = object + B = object + a: A + C = object + b: B + + proc `=destroy`(self: A) = + echo "destroyed" + + proc `=destroy`(self: C) = + `=destroy`(self.b) + + var c = C() + +block: # https://forum.nim-lang.org/t/10642 + type AObj = object + name: string + tableField: Table[string, string] + + proc `=destroy`(x: AObj) = + `=destroy`(x.name) + `=destroy`(x.tableField) diff --git a/tests/destructor/tsink.nim b/tests/destructor/tsink.nim new file mode 100644 index 000000000..e8750ad7c --- /dev/null +++ b/tests/destructor/tsink.nim @@ -0,0 +1,70 @@ +discard """ + matrix: "--mm:arc" +""" + +type AnObject = object of RootObj + value*: int + +proc mutate(shit: sink AnObject) = + shit.value = 1 + +proc foo = # bug #23359 + var bar = AnObject(value: 42) + mutate(bar) + doAssert bar.value == 42 + +foo() + +block: # bug #23902 + proc foo(a: sink string): auto = (a, a) + + proc bar(a: sink int): auto = return a + + proc foo(a: sink string) = + var x = (a, a) + +block: # bug #24175 + block: + func mutate(o: sink string): string = + o[1] = '1' + result = o + + static: + let s = "999" + let m = mutate(s) + doAssert s == "999" + doAssert m == "919" + + func foo() = + let s = "999" + let m = mutate(s) + doAssert s == "999" + doAssert m == "919" + + static: + foo() + foo() + + block: + type O = object + a: int + + func mutate(o: sink O): O = + o.a += 1 + o + + static: + let x = O(a: 1) + let y = mutate(x) + doAssert x.a == 1 + doAssert y.a == 2 + + proc foo() = + let x = O(a: 1) + let y = mutate(x) + doAssert x.a == 1 + doAssert y.a == 2 + + static: + foo() + foo() diff --git a/tests/destructor/tv2_cast.nim b/tests/destructor/tv2_cast.nim index 6fcb5994c..48bdf67dd 100644 --- a/tests/destructor/tv2_cast.nim +++ b/tests/destructor/tv2_cast.nim @@ -10,17 +10,10 @@ destroying O1''' var data :tmpD - :tmpD_1 - :tmpD_2 -data = - :tmpD = `=dup`(cast[string]( - :tmpD_2 = encode(cast[seq[byte]]( - :tmpD_1 = newString(100) - :tmpD_1)) - :tmpD_2)) - :tmpD -`=destroy`(:tmpD_2) -`=destroy`(:tmpD_1) +data = cast[string](encode(cast[seq[byte]]( + :tmpD = newString(100) + :tmpD))) +`=destroy`(:tmpD) `=destroy`(data) -- end of expandArc ------------------------ --expandArc: main1 @@ -28,15 +21,8 @@ data = var s data - :tmpD - :tmpD_1 s = newString(100) -data = - :tmpD = `=dup`(cast[string]( - :tmpD_1 = encode(toOpenArrayByte(s, 0, len(s) - 1)) - :tmpD_1)) - :tmpD -`=destroy`(:tmpD_1) +data = cast[string](encode(toOpenArrayByte(s, 0, len(s) - 1))) `=destroy`(data) `=destroy`(s) -- end of expandArc ------------------------ @@ -45,35 +31,21 @@ data = var s data - :tmpD - :tmpD_1 s = newSeq(100) -data = - :tmpD = `=dup`(cast[string]( - :tmpD_1 = encode(s) - :tmpD_1)) - :tmpD -`=destroy`(:tmpD_1) +data = cast[string](encode(s)) `=destroy`(data) -`=destroy`(s) +`=destroy_1`(s) -- end of expandArc ------------------------ --expandArc: main3 var data :tmpD - :tmpD_1 - :tmpD_2 -data = - :tmpD = `=dup`(cast[string]( - :tmpD_2 = encode do: - :tmpD_1 = newSeq(100) - :tmpD_1 - :tmpD_2)) - :tmpD -`=destroy`(:tmpD_2) -`=destroy`(:tmpD_1) -`=destroy`(data) +data = cast[string](encode do: + :tmpD = newSeq(100) + :tmpD) +`=destroy`(:tmpD) +`=destroy_1`(data) -- end of expandArc ------------------------ ''' """ |