mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 14:23:45 +00:00
```nim
proc foo =
var x = "1234"
var y = x
when nimvm:
discard
else:
var s = x
doAssert s == "1234"
doAssert y == "1234"
static: foo()
foo()
```
`dfa` chooses the `nimvm` branch, `x` is misread as a last read and
`wasMoved`.
`injectDestructor` is used for codegen and is not used for vmgen. It's
reasonable to choose the codegen path instead of the `nimvm` path so the
code works for codegen. Though the problem is often hidden by
`cursorinference` or `optimizer`.
found in https://github.com/nim-lang/Nim/pull/24831
66 lines
1.1 KiB
Nim
66 lines
1.1 KiB
Nim
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()
|
|
|
|
block:
|
|
proc foo =
|
|
var x = "1234"
|
|
var y = x
|
|
when nimvm:
|
|
discard
|
|
else:
|
|
var s = x
|
|
doAssert s == "1234"
|
|
doAssert y == "1234"
|
|
|
|
static: foo()
|
|
foo()
|