| 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