Closed lcampbel closed 2 years ago
Thanks. I can trigger it with this test case. I'll try make a PR with the fix.
#include "Test.h"
static BOOL called;
@interface Canary : Test
@end
@implementation Canary
- (void)dealloc
{
called = YES;
[super dealloc];
}
@end
@interface Creator : Test
@end
@implementation Creator
- (void)dealloc
{
for (int i = 0; i < 512; i++)
[[Test new] autorelease];
[super dealloc];
}
@end
int main()
{
called = NO;
@autoreleasepool
{
[[Canary new] autorelease];
[[Creator new] autorelease];
}
assert(called == YES);
return 0;
}
In arc.mm/emptyPool, in this snippet:
if the second release() calls something (a dealloc method typically) that autoreleases one or more objects, a new arc pool (I'm calling it that to distinguish it from an autorelease pool) could be pushed; in that case, the loop will stop when it's finished emptying the new pool, possibly leaving the previous pool partially unemptied.
I think this can be fixed by wrapping the entire snippet above inside