]> granicus.if.org Git - clang/commitdiff
Fix crashes on missing @interface for category
authorBen Langmuir <blangmuir@apple.com>
Tue, 20 Jan 2015 20:41:36 +0000 (20:41 +0000)
committerBen Langmuir <blangmuir@apple.com>
Tue, 20 Jan 2015 20:41:36 +0000 (20:41 +0000)
In a few places we didn't check that Category->getClassInterface() was
not null before using it.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@226605 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExpr.cpp
test/SemaObjC/attr-deprecated.m
test/SemaObjC/attr-designated-init.m

index 9eb5993f2a2db00b63860397438c0759a71b5798..8fbe82fd88124ecbc26e02fef8b34e5efc45df99 100644 (file)
@@ -13979,7 +13979,10 @@ Decl *Sema::getObjCDeclContext() const {
 }
 
 AvailabilityResult Sema::getCurContextAvailability() const {
-  const Decl *D = cast<Decl>(getCurObjCLexicalContext());
+  const Decl *D = cast_or_null<Decl>(getCurObjCLexicalContext());
+  if (!D)
+    return AR_Available;
+
   // If we are within an Objective-C method, we should consult
   // both the availability of the method as well as the
   // enclosing class.  If the class is (say) deprecated,
index 8837bbdb2bc44ba6d2d776b4f76b08f2630a31d1..c17451eaaaf191ca9734ae5dd7a432a1cc20d542 100644 (file)
@@ -3783,6 +3783,10 @@ static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
     IFace = CatDecl->getClassInterface();
   else
     IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
+
+  if (!IFace)
+    return;
+
   IFace->setHasDesignatedInitializers();
   D->addAttr(::new (S.Context)
                   ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context,
@@ -5059,7 +5063,8 @@ static bool isDeclDeprecated(Decl *D) {
       return true;
     // A category implicitly has the availability of the interface.
     if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
-      return CatD->getClassInterface()->isDeprecated();
+      if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface())
+        return Interface->isDeprecated();
   } while ((D = cast_or_null<Decl>(D->getDeclContext())));
   return false;
 }
@@ -5070,7 +5075,8 @@ static bool isDeclUnavailable(Decl *D) {
       return true;
     // A category implicitly has the availability of the interface.
     if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
-      return CatD->getClassInterface()->isUnavailable();
+      if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface())
+        return Interface->isUnavailable();
   } while ((D = cast_or_null<Decl>(D->getDeclContext())));
   return false;
 }
index fba7a2d23ffd7bfb09633c91deac338bb26e8751..74779bc28c4823d00e474b849518cbecfeca7a2a 100644 (file)
@@ -76,8 +76,8 @@ bool Sema::CanUseDecl(NamedDecl *D) {
 static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) {
   // Warn if this is used but marked unused.
   if (D->hasAttr<UnusedAttr>()) {
-    const Decl *DC = cast<Decl>(S.getCurObjCLexicalContext());
-    if (!DC->hasAttr<UnusedAttr>())
+    const Decl *DC = cast_or_null<Decl>(S.getCurObjCLexicalContext());
+    if (DC && !DC->hasAttr<UnusedAttr>())
       S.Diag(Loc, diag::warn_used_but_marked_unused) << D->getDeclName();
   }
 }
index 13ba68db58e63990b93ac11993621c78589dfd35..14d33d3760518c7dd1f96f537099d6ef18848fad 100644 (file)
@@ -284,3 +284,14 @@ void f(id a) {
 void g(id a) {
   [a anotherPartiallyUnavailableMethod]; // no warning, `a` could be an InterfaceWithImplementation.
 }
+
+typedef struct {} S1 __attribute__((unavailable)); // expected-note2{{marked unavailable here}}
+typedef struct {} S2 __attribute__((deprecated)); // expected-note2{{marked deprecated here}}
+@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}}
+- (void)method1:(S1) x; // expected-error{{is unavailable}}
+- (void)method2:(S2) x; // expected-warning{{is deprecated}}
+@end
+@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
+- (void)method1:(S1) x; // expected-error{{is unavailable}}
+- (void)method2:(S2) x; // expected-warning{{is deprecated}}
+@end
index 535065769404ecdf36ef20ed01cff3ceaad10fe9..a8673e1b01912f3a49f402383e60d63069de96d4 100644 (file)
@@ -410,3 +410,11 @@ __attribute__((objc_root_class))
   return [super init];
 }
 @end
+
+@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}}
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
+@end
+
+@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
+- (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}}
+@end