What steps will reproduce the problem?
import crack.io cout;
class Obj {
String val;
oper init(String val0) : val = val0 {}
oper del() {
cout `$val deleted\n`;
}
}
void f(Obj o) {
o = Obj('internal');
}
Obj j = {'external'};
f(j);
cout `done\n`;
What is the expected output?
internal
done
external
What do you see instead?
external
done
Please use labels and text to provide additional information.
For performance reasons, arguments don't bind/release on function enter/leave.
However, when they are reassigned they do. In the example above, the external
reference is incorrectly decremented and the internal reference is leaked.
The only solutions I can think of are:
1) treat arguments like other variables and do bind/release for their scope
2) abandon "single pass" and convert arguments to true "owning" variables if we
see an assignment.
3) make it illegal to assign argument types that have a "release"
option 1 would be a huge performance hit, option 2 changes a fundamental
assumption that I am not willing to abandon, so it seems like option 3 is the
only viable solution for crack 1.0.
We should add this to the list of decisions to revisit if we ever abandon
single-pass.
Original issue reported on code.google.com by mind...@gmail.com on 22 Jan 2011 at 6:13
Original issue reported on code.google.com by
mind...@gmail.com
on 22 Jan 2011 at 6:13