Issue 56680
Summary Retain count imbalanced when calling ObjC synthesized property getters for structs with ARC object pointer fields
Labels
Assignees
Reporter patters
    In 2018 [Apple announced](https://devstreaming-cdn.apple.com/videos/wwdc/2018/409t8zw7rumablsh/409/409_whats_new_in_llvm.pdf) support for ARC object pointers in C structures in LLVM. We have observed that when such a `struct` is the type of a property with a **synthesized** getter, the implementation lacks any reference counting semantics. This leads to crashes when using the getter:

```objc
#import <Foundation/Foundation.h>

struct Box {
    NSObject *value;
};

@interface Container : NSObject
@property (nonatomic, readonly) struct Box box;
@end

@implementation Container

- (instancetype)init {
    self = [super init];
    if (self) {
        _box.value = [NSObject new];
    }
    return self;
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Container *c = [Container new];
        [c box];
        c = nil;
    }
    return 0;
}
```

Build and run on macOS, and observe the overrelease by enabling zombies:

```
% clang -fobjc-arc main.m   
% NSZombieEnabled=YES ./a.out 
2022-07-22 18:00:34.449 a.out[30814:150315661] *** -[NSObject release]: message sent to deallocated instance 0x600001004040
zsh: illegal hardware instruction  NSZombieEnabled=YES ./a.out
```

Here, we construct an Objective-C object that holds a struct with ARC fields, and allow a property getter to be synthesized. Callers of the getter assume copies are returned, so clean them up afterwards (calling `__destructor_8_s0`). As we nil the reference to the Objective-C object, it is deallocated, which attempts to release the struct fields again, and we crash.

If we implement the getter ourselves (e.g. `- (struct Box)box { return _box; }`), the compiled output **does** create a copy (via `__copy_constructor_8_8_s0`) of the `struct`, bumping the right retain counts, we don't overrelease and don't crash.

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to