<div dir="ltr">Hi Erik,<div><br></div><div>with this change clangs warns on this program:</div><div><br></div><div><div>$ cat <a href="http://test.mm">test.mm</a></div><div>#import <Cocoa/Cocoa.h></div><div>@interface AXPlatformNodeCocoa : NSObject<br></div><div>@end</div><div>@implementation AXPlatformNodeCocoa<br></div><div>- (NSArray*)accessibilityAttributeNames {</div><div>  NSArray* const kTextfieldAttributes = @[</div><div>    NSAccessibilityPlaceholderValueAttribute,</div><div>  ];</div><div>  return kTextfieldAttributes;</div><div>}</div><div>@end</div><div><br></div><div>$ bin/clang -c <a href="http://test.mm">test.mm</a> -isysroot $(xcrun -show-sdk-path) -Wpartial-availability -mmacosx-version-min=10.7</div><div>test.mm:9:5: warning: 'NSAccessibilityPlaceholderValueAttribute' is partial: introduced in macOS 10.6 [-Wpartial-availability]</div><div>    NSAccessibilityPlaceholderValueAttribute,</div><div>    ^</div><div>/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSAccessibilityConstants.h:85:31: note: </div><div>      'NSAccessibilityPlaceholderValueAttribute' has been explicitly marked partial here</div></div><div><br></div><div>Given that I'm building with -mmacosx-version-min=10.7 it seems strange to warn about something introduced in 10.6. This is probably not doing what it should?</div><div><br></div><div>Thanks,</div><div>Nico</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 29, 2016 at 1:37 PM, Erik Pilkington via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: epilk<br>
Date: Fri Jul 29 12:37:38 2016<br>
New Revision: 277175<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=277175&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=277175&view=rev</a><br>
Log:<br>
Reapply r277058: "[ObjC] Consider availability of context when emitting availability warnings"<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/DeclBase.h<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/AST/DeclBase.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/test/SemaObjC/attr-availability.m<br>
<br>
Modified: cfe/trunk/include/clang/AST/DeclBase.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=277175&r1=277174&r2=277175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=277175&r1=277174&r2=277175&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/DeclBase.h (original)<br>
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri Jul 29 12:37:38 2016<br>
@@ -17,6 +17,7 @@<br>
 #include "clang/AST/AttrIterator.h"<br>
 #include "clang/AST/DeclarationName.h"<br>
 #include "clang/Basic/Specifiers.h"<br>
+#include "clang/Basic/VersionTuple.h"<br>
 #include "llvm/ADT/PointerUnion.h"<br>
 #include "llvm/ADT/iterator.h"<br>
 #include "llvm/ADT/iterator_range.h"<br>
@@ -603,7 +604,12 @@ public:<br>
   /// AR_Available, will be set to a (possibly empty) message<br>
   /// describing why the declaration has not been introduced, is<br>
   /// deprecated, or is unavailable.<br>
-  AvailabilityResult getAvailability(std::string *Message = nullptr) const;<br>
+  ///<br>
+  /// \param EnclosingVersion The version to compare with. If empty, assume the<br>
+  /// deployment target version.<br>
+  AvailabilityResult<br>
+  getAvailability(std::string *Message = nullptr,<br>
+                  VersionTuple EnclosingVersion = VersionTuple()) const;<br>
<br>
   /// \brief Determine whether this declaration is marked 'deprecated'.<br>
   ///<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=277175&r1=277174&r2=277175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=277175&r1=277174&r2=277175&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jul 29 12:37:38 2016<br>
@@ -9596,7 +9596,12 @@ public:<br>
   }<br>
<br>
   AvailabilityResult getCurContextAvailability() const;<br>
-<br>
+<br>
+  /// \brief Get the verison that this context implies.<br>
+  /// For instance, a method in an interface that is annotated with an<br>
+  /// availability attribuite effectively has the availability of the interface.<br>
+  VersionTuple getVersionForDecl(const Decl *Ctx) const;<br>
+<br>
   const DeclContext *getCurObjCLexicalContext() const {<br>
     const DeclContext *DC = getCurLexicalContext();<br>
     // A category implicitly has the attribute of the interface.<br>
<br>
Modified: cfe/trunk/lib/AST/DeclBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=277175&r1=277174&r2=277175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=277175&r1=277174&r2=277175&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/DeclBase.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Jul 29 12:37:38 2016<br>
@@ -400,11 +400,12 @@ const Attr *Decl::getDefiningAttr() cons<br>
 /// diagnostics.<br>
 static AvailabilityResult CheckAvailability(ASTContext &Context,<br>
                                             const AvailabilityAttr *A,<br>
-                                            std::string *Message) {<br>
-  VersionTuple TargetMinVersion =<br>
-    Context.getTargetInfo().getPlatformMinVersion();<br>
+                                            std::string *Message,<br>
+                                            VersionTuple EnclosingVersion) {<br>
+  if (EnclosingVersion.empty())<br>
+    EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();<br>
<br>
-  if (TargetMinVersion.empty())<br>
+  if (EnclosingVersion.empty())<br>
     return AR_Available;<br>
<br>
   // Check if this is an App Extension "platform", and if so chop off<br>
@@ -449,7 +450,7 @@ static AvailabilityResult CheckAvailabil<br>
<br>
   // Make sure that this declaration has already been introduced.<br>
   if (!A->getIntroduced().empty() &&<br>
-      TargetMinVersion < A->getIntroduced()) {<br>
+      EnclosingVersion < A->getIntroduced()) {<br>
     if (Message) {<br>
       Message->clear();<br>
       llvm::raw_string_ostream Out(*Message);<br>
@@ -463,7 +464,7 @@ static AvailabilityResult CheckAvailabil<br>
   }<br>
<br>
   // Make sure that this declaration hasn't been obsoleted.<br>
-  if (!A->getObsoleted().empty() && TargetMinVersion >= A->getObsoleted()) {<br>
+  if (!A->getObsoleted().empty() && EnclosingVersion >= A->getObsoleted()) {<br>
     if (Message) {<br>
       Message->clear();<br>
       llvm::raw_string_ostream Out(*Message);<br>
@@ -477,7 +478,7 @@ static AvailabilityResult CheckAvailabil<br>
   }<br>
<br>
   // Make sure that this declaration hasn't been deprecated.<br>
-  if (!A->getDeprecated().empty() && TargetMinVersion >= A->getDeprecated()) {<br>
+  if (!A->getDeprecated().empty() && EnclosingVersion >= A->getDeprecated()) {<br>
     if (Message) {<br>
       Message->clear();<br>
       llvm::raw_string_ostream Out(*Message);<br>
@@ -493,9 +494,10 @@ static AvailabilityResult CheckAvailabil<br>
   return AR_Available;<br>
 }<br>
<br>
-AvailabilityResult Decl::getAvailability(std::string *Message) const {<br>
+AvailabilityResult Decl::getAvailability(std::string *Message,<br>
+                                         VersionTuple EnclosingVersion) const {<br>
   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))<br>
-    return FTD->getTemplatedDecl()->getAvailability(Message);<br>
+    return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion);<br>
<br>
   AvailabilityResult Result = AR_Available;<br>
   std::string ResultMessage;<br>
@@ -520,7 +522,7 @@ AvailabilityResult Decl::getAvailability<br>
<br>
     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {<br>
       AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,<br>
-                                                Message);<br>
+                                                Message, EnclosingVersion);<br>
<br>
       if (AR == AR_Unavailable)<br>
         return AR_Unavailable;<br>
@@ -579,8 +581,8 @@ bool Decl::isWeakImported() const {<br>
       return true;<br>
<br>
     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {<br>
-      if (CheckAvailability(getASTContext(), Availability,<br>
-                            nullptr) == AR_NotYetIntroduced)<br>
+      if (CheckAvailability(getASTContext(), Availability, nullptr,<br>
+                            VersionTuple()) == AR_NotYetIntroduced)<br>
         return true;<br>
     }<br>
   }<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=277175&r1=277174&r2=277175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=277175&r1=277174&r2=277175&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Jul 29 12:37:38 2016<br>
@@ -6484,3 +6484,26 @@ void Sema::EmitAvailabilityWarning(Avail<br>
   DoEmitAvailabilityWarning(*this, AD, Ctx, D, Message, Loc, UnknownObjCClass,<br>
                             ObjCProperty, ObjCPropertyAccess);<br>
 }<br>
+<br>
+VersionTuple Sema::getVersionForDecl(const Decl *D) const {<br>
+  assert(D && "Expected a declaration here!");<br>
+<br>
+  VersionTuple DeclVersion;<br>
+  if (const auto *AA = getAttrForPlatform(getASTContext(), D))<br>
+    DeclVersion = AA->getIntroduced();<br>
+<br>
+  const ObjCInterfaceDecl *Interface = nullptr;<br>
+<br>
+  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))<br>
+    Interface = MD->getClassInterface();<br>
+  else if (const auto *ID = dyn_cast<ObjCImplementationDecl>(D))<br>
+    Interface = ID->getClassInterface();<br>
+<br>
+  if (Interface) {<br>
+    if (const auto *AA = getAttrForPlatform(getASTContext(), Interface))<br>
+      if (AA->getIntroduced() > DeclVersion)<br>
+        DeclVersion = AA->getIntroduced();<br>
+  }<br>
+<br>
+  return DeclVersion;<br>
+}<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=277175&r1=277174&r2=277175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=277175&r1=277174&r2=277175&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 29 12:37:38 2016<br>
@@ -107,9 +107,14 @@ static AvailabilityResult<br>
 DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc,<br>
                            const ObjCInterfaceDecl *UnknownObjCClass,<br>
                            bool ObjCPropertyAccess) {<br>
-  // See if this declaration is unavailable or deprecated.<br>
+  VersionTuple ContextVersion;<br>
+  if (const DeclContext *DC = S.getCurObjCLexicalContext())<br>
+    ContextVersion = S.getVersionForDecl(cast<Decl>(DC));<br>
+<br>
+  // See if this declaration is unavailable, deprecated, or partial in the<br>
+  // current context.<br>
   std::string Message;<br>
-  AvailabilityResult Result = D->getAvailability(&Message);<br>
+  AvailabilityResult Result = D->getAvailability(&Message, ContextVersion);<br>
<br>
   // For typedefs, if the typedef declaration appears available look<br>
   // to the underlying type to see if it is more restrictive.<br>
@@ -117,7 +122,7 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name<br>
     if (Result == AR_Available) {<br>
       if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {<br>
         D = TT->getDecl();<br>
-        Result = D->getAvailability(&Message);<br>
+        Result = D->getAvailability(&Message, ContextVersion);<br>
         continue;<br>
       }<br>
     }<br>
@@ -128,7 +133,7 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name<br>
   if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {<br>
     if (IDecl->getDefinition()) {<br>
       D = IDecl->getDefinition();<br>
-      Result = D->getAvailability(&Message);<br>
+      Result = D->getAvailability(&Message, ContextVersion);<br>
     }<br>
   }<br>
<br>
@@ -136,7 +141,7 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name<br>
     if (Result == AR_Available) {<br>
       const DeclContext *DC = ECD->getDeclContext();<br>
       if (const EnumDecl *TheEnumDecl = dyn_cast<EnumDecl>(DC))<br>
-        Result = TheEnumDecl->getAvailability(&Message);<br>
+        Result = TheEnumDecl->getAvailability(&Message, ContextVersion);<br>
     }<br>
<br>
   const ObjCPropertyDecl *ObjCPDecl = nullptr;<br>
@@ -144,7 +149,8 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name<br>
       Result == AR_NotYetIntroduced) {<br>
     if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {<br>
       if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {<br>
-        AvailabilityResult PDeclResult = PD->getAvailability(nullptr);<br>
+        AvailabilityResult PDeclResult =<br>
+            PD->getAvailability(nullptr, ContextVersion);<br>
         if (PDeclResult == Result)<br>
           ObjCPDecl = PD;<br>
       }<br>
@@ -198,7 +204,7 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name<br>
       break;<br>
<br>
     }<br>
-    return Result;<br>
+  return Result;<br>
 }<br>
<br>
 /// \brief Emit a note explaining that this function is deleted.<br>
<br>
Modified: cfe/trunk/test/SemaObjC/attr-availability.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-availability.m?rev=277175&r1=277174&r2=277175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-availability.m?rev=277175&r1=277174&r2=277175&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjC/attr-availability.m (original)<br>
+++ cfe/trunk/test/SemaObjC/attr-availability.m Fri Jul 29 12:37:38 2016<br>
@@ -294,3 +294,34 @@ __attribute__((objc_root_class))<br>
   [obj method]; // expected-error{{'method' is unavailable}}<br>
 }<br>
 @end<br>
+<br>
+#if defined(WARN_PARTIAL)<br>
+<br>
+int fn_10_7() __attribute__((availability(macosx, introduced=10.7))); // expected-note{{marked partial here}}<br>
+int fn_10_8() __attribute__((availability(macosx, introduced=10.8))) { // expected-note{{marked partial here}}<br>
+  return fn_10_7();<br>
+}<br>
+<br>
+__attribute__((objc_root_class))<br>
+@interface LookupAvailabilityBase<br>
+-(void) method1;<br>
+@end<br>
+<br>
+@implementation LookupAvailabilityBase<br>
+-(void)method1 { fn_10_7(); } // expected-warning{{partial}} expected-note{{explicitly redeclare}}<br>
+@end<br>
+<br>
+__attribute__((availability(macosx, introduced=10.7)))<br>
+@interface LookupAvailability : LookupAvailabilityBase<br>
+- (void)method2;<br>
+- (void)method3;<br>
+- (void)method4 __attribute__((availability(macosx, introduced=10.8)));<br>
+@end<br>
+<br>
+@implementation LookupAvailability<br>
+-(void)method2 { fn_10_7(); }<br>
+-(void)method3 { fn_10_8(); } // expected-warning{{partial}} expected-note{{explicitly redeclare}}<br>
+-(void)method4 { fn_10_8(); }<br>
+@end<br>
+<br>
+#endif<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>