]> granicus.if.org Git - clang/commitdiff
Fix another crash on invalid code. In this case, handle ObjC categories (with no...
authorTed Kremenek <kremenek@apple.com>
Tue, 23 Feb 2010 19:39:46 +0000 (19:39 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 23 Feb 2010 19:39:46 +0000 (19:39 +0000)
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
test/SemaObjC/category-1.m

index e40e8fedc07980201a4677f6ae87ba9cba48ecab..925c0db4e40da4544a46654488d0542e10dea40c 100644 (file)
@@ -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)
index 33e4646837a0ea3437c2604e4060230d9aa2f127..24324f8500afd5ec9a637fc6e0be7e5cb9ea9bf1 100644 (file)
@@ -73,3 +73,7 @@
 
 @implementation MultipleCat_I // expected-warning {{incomplete implementation}}, expected-warning {{method definition for 'im0' not found}}
 @end
+
+// <rdar://problem/7680391> - Handle nameless categories with no name that refer
+// to an undefined class
+@interface RDar7680391 () @end // expected-error{{cannot find interface declaration}}