Clang 4.2: synthesized Objective-C properties can instantiate abstract C++ classes
| Originator: | Karoly.Lorentey | ||
| Number: | rdar://14261999 | Date Originated: | 25-Jun-2013 07:12 PM |
| Status: | Open | Resolved: | |
| Product: | Developer Tools | Product Version: | Xcode 4.6.3 (4H1503) |
| Classification: | Other Bug | Reproducible: | Always |
Summary:
Clang accepts code that synthesizes getters and setters for Objective-C properties with abstract C++ class reference types. No diagnostic is produced, but a backing ivar is silently generated with the abstract class type, which should not be possible: the generated code creates instances of the abstract class. When unrelated code attempts to call pure virtual methods via the returned reference, the C++ runtime produces an error that can be challenging to track down.
Clang should refuse to synthesize ivars and getters for Objective-C properties with abstract C++ types.
Example code:
class TestInterface
{
public:
TestInterface() {}
virtual ~TestInterface() {}
virtual int TestMethod() const = 0;
};
@interface TestClass : NSObject
@property (nonatomic, readonly) const TestInterface& test; // This should not compile without an explicit getter.
@end
@implementation TestClass
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
TestClass *testClass = [[TestClass alloc] init];
const TestInterface& testInterface = testClass.test;
NSLog(@"%d", testInterface.TestMethod()); // Runtime error: "libc++abi.dylib: pure virtual method called"
}
return 0;
}
As far as I can see, the compiler generates code that is roughly equivalent to the following (invalid) implementation:
@implementation TestClass
{
TestInterface _test;
}
- (const TestInterface&)test
{
return _test;
}
@end
Steps to Reproduce:
Open and run the attached project in Xcode 4.6.3 or Xcode 5 DP2.
Expected Results:
Compiler error complaining that @properties with abstract values cannot be synthesized.
Actual Results:
Runtime error "libc++abi.dylib: pure virtual method called" leading to abort().
Regression:
Unknown
Notes:
This issue is reproducible with the following compilers:
$ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
$ /Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang --version
Apple LLVM version 5.0 (clang-500.1.61) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
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!
Can't get this to link
Can you provide a specific invocation of clang that actually will compile and link this code? With
clang -o objcppabstract main.mm -framework Foundation
I get
Undefined symbols for architecture x86_64: "vtable for cxxabiv1::class_type_info", referenced from: typeinfo for TestInterface in main-5W24Ac.o NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. "operator delete(void*)", referenced from: TestInterface::~TestInterface() in main-5W24Ac.o "___cxa_pure_virtual", referenced from: vtable for TestInterface in main-5W24Ac.o "___gxx_personality_v0", referenced from: TestInterface::~TestInterface() in main-5W24Ac.o Dwarf Exception Unwind Info (__eh_frame) in main-5W24Ac.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)