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:
Fariborz Jahanian 2009-07-09 22:08:26 +00:00
Родитель d5940ce01c
Коммит fdee089b11
3 изменённых файлов: 51 добавлений и 36 удалений

Просмотреть файл

@ -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