nimskull
nimskull copied to clipboard
value is implicitly moved even though it's used afterwards
Example
type Object = object
has: bool
var wasDestroyed = false
proc `=destroy`(x: var Object) =
if x.has:
wasDestroyed = true
proc f_sink(x: sink Object) =
discard
proc test() =
var o = Object(has: true)
try:
try:
f_sink(o) # must not be sunken
raise CatchableError.newException("")
except IOError:
# omitting the inner try makes the code work as expected
discard "not reached"
except CatchableError:
doAssert not wasDestroyed
discard o # use `o`, preventing it from being moved earlier
test()
Actual Output
The assertion fails, as o
was erroneously sunken into the call argument.
Expected Output
The program compiles and runs without error. o
is used beyond the procedure call, so it should not be moved.
Additional Information
The culprit is here: https://github.com/nim-works/nimskull/blob/f401e73639c2d15f2aefbad04c96199c8308b3dc/compiler/sem/mirexec.nim#L524-L533
There's no connection between the raise
and the outer except
in the control-flow graph, due to a missing edge between the inner and outer except
.