C++ ivars in Objc classes don't error about unimpl virtual methods

Originator:joachimb
Number:rdar://12095239 Date Originated:14-Aug-2012 05:33 PM
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode 4.4
Classification:Serious Bug Reproducible:Always
 
Summary:
If you try to instantiate a C++ object as an instance variable in your ObjC class, the error that would normally tell you that a pure virtual method is unimplemented is missing, and the application compiles anyway. This will crash at runtime instead.

Steps to Reproduce:
1. Implement an abstract base class in C++
2. Implement a concrete sub class in C++
3. Accidentally mistype or miss to override one or more of the pure abstract virtual method from super
4. Compile

Expected Results:
5. Build error, refusing to build since you have a method missing

Actual Results:
5. Application compiles without errors, but crashes at runtime when the missing method is called.

Regression:
The error works fine for C++ ivars, as well as for stack and heap allocations of the C++ object.

Notes:
This is a very easy mistake to make in C++, only slightly mitigated by 'override' since there is so much old code that doesn't use override yet. A single type change in super's signature will break the overloading of that method. This has caused several very serious crashers in our iOS app.

Sample code, also attached:

#import <Foundation/Foundation.h>

class CppAbstractBase {
public:
    virtual void testA() = 0;
    virtual void testB() = 0;
    int a;
};

class CppConcreteSub : public CppAbstractBase {
    virtual void testA() { }
};

@interface Objc : NSObject {
    CppConcreteSub _concrete; // <-- SHOULD ERROR
}
- (CppAbstractBase*)abstract;
@end
@implementation Objc
- (CppAbstractBase*)abstract {
    return &_concrete;
}
@end

class Cpp {
public:
    CppConcreteSub sub; // <-- ERRORS CORRECTLY
    // Field type 'CppConcreteSub' is an abstract class
};

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        CppConcreteSub sub; // <-- ERRORS CORRECTLY
        // Variable type 'CppConcreteSub' is an abstract class, Unimplemented pure virtual method 'testB' in CppConcreteSub
        
        Objc *objc = [Objc new];
        [objc abstract]->testB(); // <-- CRASHES HORRIBLY
        
        // insert code here...
        NSLog(@"Hello, World!");
        
    }
    return 0;
}

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!