Incorrect codegen with ARC, @autoreleasepool, an if statement, and -O3

Originator:michael.ash
Number:rdar://11207070 Date Originated:07-Apr-2012 11:46 PM
Status:Open Resolved:
Product:Mac OS X SDK Product Version:Xcode 4.3.2
Classification:Crash Reproducible:Always
 
Summary:

In a method with an @autoreleasepool, an if statement, and a return within the if statement, clang can emit code that autoreleases the return value before popping the autorelease pool, causing a crash.

Steps to Reproduce:

Compile and run the following program with clang -O3:

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
+ (id)test: (int)x;
@end

@implementation MyClass

+ (id)test: (int)x
{
    @autoreleasepool
    {
        if (x)
            return [NSMutableDictionary dictionary];
        return nil;
    }
}

@end

int main()
{
    @autoreleasepool
    {
        NSLog(@"%@", [MyClass test: 1]);
    }
}


Expected Results:

It should print an empty dictionary.

Actual Results:

It crashes with a segmentation fault. The problem is obvious in a disassembly of the binary:

0000000100000e23	callq	0x100000ec0	; symbol stub for: _objc_retainAutoreleasedReturnValue
0000000100000e28	movq	%rax,%rdi
0000000100000e2b	callq	0x100000eb4	; symbol stub for: _objc_autoreleaseReturnValue
0000000100000e30	movq	%r14,%rdi
0000000100000e33	callq	0x100000ea8	; symbol stub for: _objc_autoreleasePoolPop
0000000100000e38	movq	%rbx,%rax
0000000100000e3b	popq	%rbx
0000000100000e3c	popq	%r14
0000000100000e3e	popq	%rbp
0000000100000e3f	ret

Note the autoreleaseReturnValue before the autoreleasePoolPop. This means the return value is destroyed before being returned to the caller. When the caller tries to use it, it crashes.

Regression:

Unknown.

Notes:

B flat, A.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!