forked from OSchip/llvm-project
objective-C++: issue diagnostic when ivar type is
an abstract c++ class. // rdar://12095239 llvm-svn: 162052
This commit is contained in:
parent
50cf25c72d
commit
78f565b0a0
|
@ -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<
|
||||
|
|
|
@ -4461,6 +4461,7 @@ public:
|
|||
AbstractParamType,
|
||||
AbstractVariableType,
|
||||
AbstractFieldType,
|
||||
AbstractIvarType,
|
||||
AbstractArrayType
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}}
|
||||
};
|
Loading…
Reference in New Issue