fixes #11350
This commit is contained in:
parent
bab1f67971
commit
085a21ebf4
2 changed files with 50 additions and 3 deletions
|
|
@ -338,10 +338,23 @@ proc genOp(c: Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode =
|
||||||
addrExp.add(dest)
|
addrExp.add(dest)
|
||||||
result = newTree(nkCall, newSymNode(op), addrExp)
|
result = newTree(nkCall, newSymNode(op), addrExp)
|
||||||
|
|
||||||
|
when false:
|
||||||
|
proc preventMoveRef(dest, ri: PNode): bool =
|
||||||
|
let lhs = dest.typ.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
|
var ri = ri
|
||||||
|
if ri.kind in nkCallKinds and ri[0].kind == nkSym and ri[0].sym.magic == mUnown:
|
||||||
|
ri = ri[1]
|
||||||
|
let rhs = ri.typ.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
|
result = lhs.kind == tyRef and rhs.kind == tyOwned
|
||||||
|
|
||||||
|
proc canBeMoved(t: PType): bool {.inline.} =
|
||||||
|
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
|
result = t.kind != tyRef and t.attachedOps[attachedSink] != nil
|
||||||
|
|
||||||
proc genSink(c: Con; t: PType; dest, ri: PNode): PNode =
|
proc genSink(c: Con; t: PType; dest, ri: PNode): PNode =
|
||||||
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
let k = if t.attachedOps[attachedSink] != nil: attachedSink
|
let k = if t.attachedOps[attachedSink] != nil: attachedSink
|
||||||
else: attachedAsgn
|
else: attachedAsgn
|
||||||
if t.attachedOps[k] != nil:
|
if t.attachedOps[k] != nil:
|
||||||
result = genOp(c, t, k, dest, ri)
|
result = genOp(c, t, k, dest, ri)
|
||||||
else:
|
else:
|
||||||
|
|
@ -659,7 +672,8 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||||
var snk = genSink(c, dest.typ, dest, ri)
|
var snk = genSink(c, dest.typ, dest, ri)
|
||||||
snk.add ri
|
snk.add ri
|
||||||
result = newTree(nkStmtList, snk, genWasMoved(ri, c))
|
result = newTree(nkStmtList, snk, genWasMoved(ri, c))
|
||||||
elif ri.sym.kind != skParam and ri.sym.owner == c.owner and isLastRead(ri, c):
|
elif ri.sym.kind != skParam and ri.sym.owner == c.owner and
|
||||||
|
isLastRead(ri, c) and canBeMoved(dest.typ):
|
||||||
# Rule 3: `=sink`(x, z); wasMoved(z)
|
# Rule 3: `=sink`(x, z); wasMoved(z)
|
||||||
var snk = genSink(c, dest.typ, dest, ri)
|
var snk = genSink(c, dest.typ, dest, ri)
|
||||||
snk.add ri
|
snk.add ri
|
||||||
|
|
@ -691,7 +705,8 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||||
result = genCopy(c, dest.typ, dest, ri)
|
result = genCopy(c, dest.typ, dest, ri)
|
||||||
result.add p(ri, c)
|
result.add p(ri, c)
|
||||||
else:
|
else:
|
||||||
if isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c):
|
if isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c) and
|
||||||
|
canBeMoved(dest.typ):
|
||||||
# Rule 3: `=sink`(x, z); wasMoved(z)
|
# Rule 3: `=sink`(x, z); wasMoved(z)
|
||||||
var snk = genSink(c, dest.typ, dest, ri)
|
var snk = genSink(c, dest.typ, dest, ri)
|
||||||
snk.add ri
|
snk.add ri
|
||||||
|
|
|
||||||
32
tests/destructor/tdangingref_simple.nim
Normal file
32
tests/destructor/tdangingref_simple.nim
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
discard """
|
||||||
|
output: '''a
|
||||||
|
[FATAL] dangling references exist
|
||||||
|
'''
|
||||||
|
exitCode: 1
|
||||||
|
cmd: "nim c --newruntime $file"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #11350
|
||||||
|
|
||||||
|
type
|
||||||
|
Node = ref object
|
||||||
|
data: int
|
||||||
|
|
||||||
|
proc use(x: Node) = discard
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
var x = Node(data: 3) # inferred to be an ``owned ref``
|
||||||
|
var dangling = unown x
|
||||||
|
assert dangling.data == 3
|
||||||
|
#use x
|
||||||
|
#dangling = nil
|
||||||
|
# reassignment causes the memory of what ``x`` points to to be freed:
|
||||||
|
echo "a"
|
||||||
|
x = Node(data: 4)
|
||||||
|
echo "b"
|
||||||
|
# accessing 'dangling' here is invalid as it is nil.
|
||||||
|
# at scope exit the memory of what ``x`` points to is freed
|
||||||
|
if dangling != nil:
|
||||||
|
echo dangling.data
|
||||||
|
|
||||||
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue