diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-09 22:08:26 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-09 22:08:26 +0000 |
commit | fdee089b11e0bb57aa2c7291dd5e4201c2f906ff (patch) | |
tree | 0f6ff887a22d1f5b344be92bd928b67715103e45 /lib/Sema/SemaDeclObjC.cpp | |
parent | d5940ce01c5f6235c88a8b92e80b86e5b5abe212 (diff) |
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
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 78 |
1 files changed, 42 insertions, 36 deletions
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<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); } |