Incorrect codegen when swapping two ivars with ARC and -O3

Originator:michael.ash
Number:rdar://11385244 Date Originated:04-May-2012 01:47 PM
Status:Open Resolved:
Product:Developer Tools Product Version:
Classification:Crash Reproducible:Always
 
Summary:

When swapping two ivars using a temporary variable, ARC can generate incorrect code that causes one of the ivars to be deallocated.


Steps to Reproduce:

Compile and run the following code (note that -O3 is necessary to reproduce):

// clang -framework Foundation -fobjc-arc -O3 test.m

#import <Foundation/Foundation.h>

@interface Test : NSObject
- (void)swap;
@end

@implementation Test {
    id a, b;
}

- (id)init
{
    if((self = [super init]))
    {
        a = [[NSObject alloc] init];
        b = [[NSObject alloc] init];
    }
    return self;
}

- (void)swap {
    id tmp = a;
    a = b;
    b = tmp;
    
    NSLog(@"Done swapping");
    
    [self self];
}

@end

int main(int argc, char **argv)
{
    @autoreleasepool
    {
        Test *test = [[Test alloc] init];
        [test swap];
    }
}


Expected Results:

The program should run and exit without comment.


Actual Results:

The program crashes due to incorrect retain/release management.

Regression:

Reproduced with both Xcode 4.3.2 and the latest 4.4 (DP4).

Notes:

Looking at the output assembly, it appears that the objc_retain for 'tmp = a' is being incorrectly moved below the objc_storeStrong for 'a = b'. This causes 'a' to be deallocated. It appears that the '[self self]' line is critical for triggering this for some reason; the assembly for a method which only contains the swap looks fine. The NSLog is also somehow necessary in order to trigger the crash in my testing, although the generated assembly without it still looks bad from what I can see.

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!