]> granicus.if.org Git - clang/commitdiff
-Wunguarded-availability should support if (@available) checks in top-level
authorAlex Lorenz <arphaman@gmail.com>
Wed, 26 Apr 2017 14:20:02 +0000 (14:20 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Wed, 26 Apr 2017 14:20:02 +0000 (14:20 +0000)
blocks and lambdas

Prior to this commit Clang emitted the old "partial availability" warning for
expressions that referred to declarations that were not yet introduced in
blocks and lambdas that were not in a function/method. This commit ensures that
top-level blocks and lambdas use the new unguarded availability checks.

rdar://31835952

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

lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExpr.cpp
test/SemaObjC/unguarded-availability.m

index 027b3fe0e782802894cf830dc4a503fbbf0ef21f..17c6975ca5e9524d4d4d695c9db5d7c7f470972e 100644 (file)
@@ -7220,6 +7220,8 @@ void Sema::DiagnoseUnguardedAvailabilityViolations(Decl *D) {
     Body = FD->getBody();
   } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D))
     Body = MD->getBody();
+  else if (auto *BD = dyn_cast<BlockDecl>(D))
+    Body = BD->getBody();
 
   assert(Body && "Need a body here!");
 
index 5a56f709377753378d183f8997cc6a488fabd904..00480f821fc6d334e13ee9653c043bcb497da63f 100644 (file)
@@ -171,9 +171,14 @@ DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc,
   if (AvailabilityResult Result =
           S.ShouldDiagnoseAvailabilityOfDecl(D, &Message)) {
 
-    if (Result == AR_NotYetIntroduced && S.getCurFunctionOrMethodDecl()) {
-      S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
-      return;
+    if (Result == AR_NotYetIntroduced) {
+      if (S.getCurFunctionOrMethodDecl()) {
+        S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
+        return;
+      } else if (S.getCurBlock() || S.getCurLambda()) {
+        S.getCurFunction()->HasPotentialAvailabilityViolations = true;
+        return;
+      }
     }
 
     const ObjCPropertyDecl *ObjCPDecl = nullptr;
@@ -12498,6 +12503,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
 
   BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
 
+  if (Body && getCurFunction()->HasPotentialAvailabilityViolations)
+    DiagnoseUnguardedAvailabilityViolations(BSI->TheDecl);
+
   // Try to apply the named return value optimization. We have to check again
   // if we can do this, though, because blocks keep return statements around
   // to deduce an implicit return type.
index 4369a0e329d29b49a2eac56c574a4c2574c13166..ae921f4a27b3e3b3bd76a88b4af61e8986cbe1e6 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx-10.9 -Wunguarded-availability -fblocks -fsyntax-only -verify %s
-// RUN: %clang_cc1 -xobjective-c++ -DOBJCPP -triple x86_64-apple-macosx-10.9 -Wunguarded-availability -fblocks -fsyntax-only -verify %s
+// RUN: %clang_cc1 -xobjective-c++ -std=c++11 -DOBJCPP -triple x86_64-apple-macosx-10.9 -Wunguarded-availability -fblocks -fsyntax-only -verify %s
 
 #define AVAILABLE_10_0  __attribute__((availability(macos, introduced = 10.0)))
 #define AVAILABLE_10_11 __attribute__((availability(macos, introduced = 10.11)))
@@ -8,9 +8,9 @@
 int func_10_11() AVAILABLE_10_11; // expected-note 4 {{'func_10_11' has been explicitly marked partial here}}
 
 #ifdef OBJCPP
-// expected-note@+2 {{marked partial here}}
+// expected-note@+2 {{marked partial here}}
 #endif
-int func_10_12() AVAILABLE_10_12; // expected-note 5 {{'func_10_12' has been explicitly marked partial here}}
+int func_10_12() AVAILABLE_10_12; // expected-note 6 {{'func_10_12' has been explicitly marked partial here}}
 
 int func_10_0() AVAILABLE_10_0;
 
@@ -129,6 +129,12 @@ void test_params(int_10_12 x); // expected-warning {{'int_10_12' is partial: int
 
 void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn
 
+void (^topLevelBlockDecl)() = ^ {
+  func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  if (@available(macos 10.12, *))
+    func_10_12();
+};
+
 #ifdef OBJCPP
 
 int f(char) AVAILABLE_10_12;
@@ -176,4 +182,10 @@ int instantiate_availability() {
     with_availability_attr<int_10_12>(); // expected-warning{{'with_availability_attr<int>' is only available on macOS 10.11 or newer}} expected-warning{{'int_10_12' is only available on macOS 10.12 or newer}} expected-note 2 {{enclose}}
 }
 
+auto topLevelLambda = [] () {
+  func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  if (@available(macos 10.12, *))
+    func_10_12();
+};
+
 #endif