зеркало из https://github.com/microsoft/clang-1.git
don't crash if class is using itself as its super class.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75178 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d5940ce01c
Коммит
fdee089b11
|
@ -145,6 +145,8 @@ def err_duplicate_class_def : Error<
|
|||
"duplicate interface definition for class %0">;
|
||||
def err_undef_superclass : Error<
|
||||
"cannot find interface declaration for %0, superclass of %1">;
|
||||
def err_recursive_superclass : Error<
|
||||
"trying to recursively use %0 as superclass of %1">;
|
||||
def warn_previous_alias_decl : Warning<"previously declared alias is ignored">;
|
||||
def err_conflicting_aliasing_type : Error<"conflicting types for alias %0">;
|
||||
def warn_undef_interface : Warning<"cannot find interface declaration for %0">;
|
||||
|
|
|
@ -124,48 +124,54 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
if (SuperName) {
|
||||
// Check if a different kind of symbol declared in this scope.
|
||||
PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
|
||||
if (PrevDecl == IDecl) {
|
||||
Diag(SuperLoc, diag::err_recursive_superclass)
|
||||
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
IDecl->setLocEnd(ClassLoc);
|
||||
}
|
||||
else {
|
||||
ObjCInterfaceDecl *SuperClassDecl =
|
||||
dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
|
||||
|
||||
ObjCInterfaceDecl *SuperClassDecl =
|
||||
dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
|
||||
|
||||
// Diagnose classes that inherit from deprecated classes.
|
||||
if (SuperClassDecl)
|
||||
(void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
|
||||
// Diagnose classes that inherit from deprecated classes.
|
||||
if (SuperClassDecl)
|
||||
(void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
|
||||
|
||||
if (PrevDecl && SuperClassDecl == 0) {
|
||||
// The previous declaration was not a class decl. Check if we have a
|
||||
// typedef. If we do, get the underlying class type.
|
||||
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
|
||||
QualType T = TDecl->getUnderlyingType();
|
||||
if (T->isObjCInterfaceType()) {
|
||||
if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl())
|
||||
SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
|
||||
if (PrevDecl && SuperClassDecl == 0) {
|
||||
// The previous declaration was not a class decl. Check if we have a
|
||||
// typedef. If we do, get the underlying class type.
|
||||
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
|
||||
QualType T = TDecl->getUnderlyingType();
|
||||
if (T->isObjCInterfaceType()) {
|
||||
if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl())
|
||||
SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
|
||||
}
|
||||
}
|
||||
|
||||
// This handles the following case:
|
||||
//
|
||||
// typedef int SuperClass;
|
||||
// @interface MyClass : SuperClass {} @end
|
||||
//
|
||||
if (!SuperClassDecl) {
|
||||
Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
}
|
||||
}
|
||||
|
||||
// This handles the following case:
|
||||
//
|
||||
// typedef int SuperClass;
|
||||
// @interface MyClass : SuperClass {} @end
|
||||
//
|
||||
if (!SuperClassDecl) {
|
||||
Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
|
||||
if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
|
||||
if (!SuperClassDecl)
|
||||
Diag(SuperLoc, diag::err_undef_superclass)
|
||||
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
else if (SuperClassDecl->isForwardDecl())
|
||||
Diag(SuperLoc, diag::err_undef_superclass)
|
||||
<< SuperClassDecl->getDeclName() << ClassName
|
||||
<< SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
}
|
||||
IDecl->setSuperClass(SuperClassDecl);
|
||||
IDecl->setSuperClassLoc(SuperLoc);
|
||||
IDecl->setLocEnd(SuperLoc);
|
||||
}
|
||||
|
||||
if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
|
||||
if (!SuperClassDecl)
|
||||
Diag(SuperLoc, diag::err_undef_superclass)
|
||||
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
else if (SuperClassDecl->isForwardDecl())
|
||||
Diag(SuperLoc, diag::err_undef_superclass)
|
||||
<< SuperClassDecl->getDeclName() << ClassName
|
||||
<< SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
}
|
||||
IDecl->setSuperClass(SuperClassDecl);
|
||||
IDecl->setSuperClassLoc(SuperLoc);
|
||||
IDecl->setLocEnd(SuperLoc);
|
||||
} else { // we have a root class.
|
||||
IDecl->setLocEnd(ClassLoc);
|
||||
}
|
||||
|
|
|
@ -24,3 +24,10 @@
|
|||
[super dealloc]; // expected-error {{no super class declared in @interface for 'SUPER'}}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface RecursiveClass : RecursiveClass // expected-error {{trying to recursively use 'RecursiveClass' as superclass of 'RecursiveClass'}}
|
||||
@end
|
||||
|
||||
@implementation RecursiveClass
|
||||
@end
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче