Don't emit 'unavailable' errors inside an unavailable function. rdar://9623855.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133264 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index e3fde7c..98bfe87 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -104,18 +104,20 @@
     break;
 
   case AR_Unavailable:
-    if (Message.empty()) {
-      if (!UnknownObjCClass)
-        Diag(Loc, diag::err_unavailable) << D->getDeclName();
-      else
-        Diag(Loc, diag::warn_unavailable_fwdclass_message) 
-             << D->getDeclName();
+    if (cast<Decl>(CurContext)->getAvailability() != AR_Unavailable) {
+      if (Message.empty()) {
+        if (!UnknownObjCClass)
+          Diag(Loc, diag::err_unavailable) << D->getDeclName();
+        else
+          Diag(Loc, diag::warn_unavailable_fwdclass_message) 
+               << D->getDeclName();
+      }
+      else 
+        Diag(Loc, diag::err_unavailable_message) 
+          << D->getDeclName() << Message;
+      Diag(D->getLocation(), diag::note_unavailable_here) 
+        << isa<FunctionDecl>(D) << false;
     }
-    else 
-      Diag(Loc, diag::err_unavailable_message) 
-        << D->getDeclName() << Message;
-    Diag(D->getLocation(), diag::note_unavailable_here) 
-      << isa<FunctionDecl>(D) << false;    
     break;
   }
 
diff --git a/test/Sema/attr-unavailable-message.c b/test/Sema/attr-unavailable-message.c
index a1e047c..9f663fc 100644
--- a/test/Sema/attr-unavailable-message.c
+++ b/test/Sema/attr-unavailable-message.c
@@ -16,3 +16,13 @@
 }
 
 char test2[__has_feature(attribute_unavailable_with_message) ? 1 : -1];
+
+// rdar://9623855
+void unavail(void)  __attribute__((__unavailable__));
+void unavail(void) {
+  // No complains inside an unavailable function.
+  int ir = foo(1);
+  double dr = dfoo(1.0);
+  void (*fp)() = &bar;
+  double (*fp4)(double) = dfoo;
+}