diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-08-16 22:38:41 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-08-16 22:38:41 +0000 |
commit | 7f90b531818ad772f6e407f88101dc618c738fa4 (patch) | |
tree | cebafeeaaa0a2a0d42c01a7f9fbc8f5e9b6d1749 | |
parent | eeff8ce11d687429d545cb6ce9bdaa44319ca72f (diff) |
objective-C++: issue diagnostic when ivar type is
an abstract c++ class. // rdar://12095239
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162052 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | test/SemaObjCXX/abstract-class-type-ivar.mm | 29 |
4 files changed, 39 insertions, 3 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 4733505a00..bff9a34318 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index b320a2452d..d1a7017fb0 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -4461,6 +4461,7 @@ public: AbstractParamType, AbstractVariableType, AbstractFieldType, + AbstractIvarType, AbstractArrayType }; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d37fbf5378..01b2f2c839 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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, diff --git a/test/SemaObjCXX/abstract-class-type-ivar.mm b/test/SemaObjCXX/abstract-class-type-ivar.mm new file mode 100644 index 0000000000..823e9c197d --- /dev/null +++ b/test/SemaObjCXX/abstract-class-type-ivar.mm @@ -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}} +}; |