From: Fariborz Jahanian Date: Thu, 9 Jul 2009 22:08:26 +0000 (+0000) Subject: don't crash if class is using itself as its super class. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fdee089b11e0bb57aa2c7291dd5e4201c2f906ff;p=clang 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 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7078530dc6..2a492fb14d 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 5cf48d6da0..62d28f326f 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -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(PrevDecl); - ObjCInterfaceDecl *SuperClassDecl = - dyn_cast_or_null(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(PrevDecl)) { - QualType T = TDecl->getUnderlyingType(); - if (T->isObjCInterfaceType()) { - if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl()) - SuperClassDecl = dyn_cast(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(PrevDecl)) { + QualType T = TDecl->getUnderlyingType(); + if (T->isObjCInterfaceType()) { + if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl()) + SuperClassDecl = dyn_cast(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(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(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); } diff --git a/test/SemaObjC/undef-superclass-1.m b/test/SemaObjC/undef-superclass-1.m index 0d670f8c08..cb15dc39a3 100644 --- a/test/SemaObjC/undef-superclass-1.m +++ b/test/SemaObjC/undef-superclass-1.m @@ -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 +