objective-C++: issue diagnostic when ivar type is

an abstract c++ class. // rdar://12095239

llvm-svn: 162052
This commit is contained in:
Fariborz Jahanian 2012-08-16 22:38:41 +00:00
parent 50cf25c72d
commit 78f565b0a0
4 changed files with 39 additions and 3 deletions

View File

@ -815,7 +815,7 @@ def err_friend_def_in_local_class : Error<
"friend function cannot be defined in a local class">;
def err_abstract_type_in_decl : Error<
"%select{return|parameter|variable|field}0 type %1 is an abstract class">;
"%select{return|parameter|variable|field|ivar}0 type %1 is an abstract class">;
def err_allocation_of_abstract_type : Error<
"allocating an object of abstract class type %0">;
def err_throw_abstract_type : Error<

View File

@ -4461,6 +4461,7 @@ public:
AbstractParamType,
AbstractVariableType,
AbstractFieldType,
AbstractIvarType,
AbstractArrayType
};

View File

@ -9913,6 +9913,13 @@ void Sema::ActOnFields(Scope* S,
}
}
}
if (isa<ObjCContainerDecl>(EnclosingDecl) &&
RequireNonAbstractType(FD->getLocation(), FD->getType(),
diag::err_abstract_type_in_decl,
AbstractIvarType)) {
// Ivars can not have abstract class types
FD->setInvalidDecl();
}
if (Record && FDTTy->getDecl()->hasObjectMember())
Record->setHasObjectMember(true);
} else if (FDTy->isObjCObjectType()) {
@ -9921,8 +9928,7 @@ void Sema::ActOnFields(Scope* S,
<< FixItHint::CreateInsertion(FD->getLocation(), "*");
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
}
else if (!getLangOpts().CPlusPlus) {
} else if (!getLangOpts().CPlusPlus) {
if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported) {
// It's an error in ARC if a field has lifetime.
// We don't want to report this in a system header, though,

View File

@ -0,0 +1,29 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
// rdar://12095239
class CppAbstractBase {
public:
virtual void testA() = 0;
virtual void testB() = 0; // expected-note {{unimplemented pure virtual method 'testB' in 'CppConcreteSub}}
int a;
};
class CppConcreteSub : public CppAbstractBase {
virtual void testA() { }
};
@interface Objc {
CppConcreteSub _concrete; // expected-error{{ivar type 'CppConcreteSub' is an abstract class}}
}
- (CppAbstractBase*)abstract;
@end
@implementation Objc
- (CppAbstractBase*)abstract {
return &_concrete;
}
@end
class Cpp {
public:
CppConcreteSub sub; // expected-error {{field type 'CppConcreteSub' is an abstract class}}
};