From 09b6897d967c50db36ad83b910060ea7d68a21bc Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 23 Feb 2010 19:39:46 +0000 Subject: [PATCH] Fix another crash on invalid code. In this case, handle ObjC categories (with no names) that refer to an undefined class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96976 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclObjC.cpp | 29 +++++++++++++++++++---------- test/SemaObjC/category-1.m | 4 ++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index e40e8fedc0..925c0db4e4 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -599,22 +599,31 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, SourceLocation EndProtoLoc) { ObjCCategoryDecl *CDecl = 0; ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc); - if (!CategoryName) + + /// Check that class of this category is already completely declared. + if (!IDecl || IDecl->isForwardDecl()) { + // Create an invalid ObjCCategoryDecl to serve as context for + // the enclosing method declarations. We mark the decl invalid + // to make it clear that this isn't a valid AST. + CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, + ClassLoc, CategoryLoc, CategoryName); + CDecl->setInvalidDecl(); + Diag(ClassLoc, diag::err_undef_interface) << ClassName; + return DeclPtrTy::make(CDecl); + } + + if (!CategoryName) { // Class extensions require a special treatment. Use an existing one. + // Note that 'getClassExtension()' can return NULL. CDecl = IDecl->getClassExtension(); + } + if (!CDecl) { - CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, ClassLoc, - CategoryLoc, CategoryName); + CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, + ClassLoc, CategoryLoc, CategoryName); // FIXME: PushOnScopeChains? CurContext->addDecl(CDecl); - /// Check that class of this category is already completely declared. - if (!IDecl || IDecl->isForwardDecl()) { - CDecl->setInvalidDecl(); - Diag(ClassLoc, diag::err_undef_interface) << ClassName; - return DeclPtrTy::make(CDecl); - } - CDecl->setClassInterface(IDecl); // Insert first use of class extension to the list of class's categories. if (!CategoryName) diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m index 33e4646837..24324f8500 100644 --- a/test/SemaObjC/category-1.m +++ b/test/SemaObjC/category-1.m @@ -73,3 +73,7 @@ @implementation MultipleCat_I // expected-warning {{incomplete implementation}}, expected-warning {{method definition for 'im0' not found}} @end + +// - Handle nameless categories with no name that refer +// to an undefined class +@interface RDar7680391 () @end // expected-error{{cannot find interface declaration}} -- 2.50.1