diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-02-23 19:39:46 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-02-23 19:39:46 +0000 |
commit | 09b6897d967c50db36ad83b910060ea7d68a21bc (patch) | |
tree | 39193df6dc8977b6fcdda9ebfd83e201b57d0ead /lib/Sema/SemaDeclObjC.cpp | |
parent | c0cd21d2a3301a7a88e0052aebdd09c2441f826d (diff) |
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
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 29 |
1 files changed, 19 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) |