fixes #23837; cursor now processes distinct types with a destructor (#23845)

fixes #23837
This commit is contained in:
ringabout
2024-07-17 11:17:52 +08:00
committed by GitHub
parent cd946084ab
commit fe48de4406
2 changed files with 62 additions and 2 deletions

View File

@@ -106,6 +106,7 @@ type
unanalysableMutation: bool
inAsgnSource, inConstructor, inNoSideEffectSection: int
inConditional, inLoop: int
inConvHasDestructor: int
owner: PSym
g: ModuleGraph
@@ -427,9 +428,17 @@ proc destMightOwn(c: var Partitions; dest: var VarIndex; n: PNode) =
# primitive literals including the empty are harmless:
discard
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv, nkCast, nkConv:
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv, nkCast:
destMightOwn(c, dest, n[1])
of nkConv:
if hasDestructor(n.typ):
inc c.inConvHasDestructor
destMightOwn(c, dest, n[1])
dec c.inConvHasDestructor
else:
destMightOwn(c, dest, n[1])
of nkIfStmt, nkIfExpr:
for i in 0..<n.len:
destMightOwn(c, dest, n[i].lastSon)
@@ -481,7 +490,7 @@ proc destMightOwn(c: var Partitions; dest: var VarIndex; n: PNode) =
of nkCallKinds:
if n.typ != nil:
if hasDestructor(n.typ):
if hasDestructor(n.typ) or c.inConvHasDestructor > 0:
# calls do construct, what we construct must be destroyed,
# so dest cannot be a cursor:
dest.flags.incl ownsData

View File

@@ -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()