The following script will fail to release one Leaker object.
int g_int;
class Leaker
{
Leaker@ Foo() { return this; }
Leaker@ Bar() { return this; }
Leaker@ Goo() { return this; }
Leaker@ opDiv(int) { return this; }
int& Car() { return g_int; }
}
void main()
{
Leaker x;
x.Foo().Goo() / x.Foo().Bar().Goo().Car();
}
I haven't been able to find the specific bug yet. It is quite touchy. Changing the prototype from "int& Car()" to "int Car()" will avoid the bug. Also, removing or adding a Foo, Bar, or Goo call to or from the denominator of the main expression will avoid the bug.
If I run the above script in your test project, I get the following output.
(0, 0) : Error : Object {8}. GC cannot destroy an object of type '_builtin_objecttype_' as it can't see all references. Current ref count is 1.
(0, 0) : Info : The builtin type in previous message is named 'Leaker'
It looks like the compiler is improperly ordering FREE codes.
void main()
Temps: 2, 3, 4, 5
Variables:
001: Leaker x
002: Leaker {noname}
003: Leaker {noname}
004: Leaker {noname}
- 13,2 -
0 5 * SUSPEND
1 5 * VarDecl 0
1 5 * CALL 39 (Leaker@ Leaker())
3 5 * STOREOBJ v1
- 14,2 -
4 5 * SUSPEND
5 5 * PshVPtr v1
6 6 * CALLINTF 41 (Leaker@ Leaker::Foo())
8 5 * STOREOBJ v2
9 5 * PshVPtr v2
10 6 * CALLINTF 42 (Leaker@ Leaker::Bar())
12 5 * STOREOBJ v4
13 5 * FREE v2, 2873960
15 5 * PshVPtr v4
16 6 * CALLINTF 43 (Leaker@ Leaker::Goo())
18 5 * STOREOBJ v2
19 5 * FREE v4, 2873960
21 5 * PshVPtr v2
22 6 * CALLINTF 45 (int& Leaker::Car())
24 5 * RDR4 v5
25 5 * PshV4 v5
26 6 * PshVPtr v1
27 7 * CALLINTF 41 (Leaker@ Leaker::Foo())
29 6 * STOREOBJ v2
30 6 * PshVPtr v2
31 7 * CALLINTF 43 (Leaker@ Leaker::Goo())
33 6 * STOREOBJ v3
34 6 * FREE v2, 2873960
36 6 * PshVPtr v3
37 7 * CALLINTF 44 (Leaker@ Leaker::opDiv(int))
39 5 * STOREOBJ v4
40 5 * FREE v3, 2873960
42 5 * FREE v2, 2873960
44 5 * FREE v4, 2873960
- 15,2 -
46 5 * SUSPEND
47 5 * FREE v1, 2873960
49 5 * 0:
49 5 * RET 0