Yes. I filed rdar://problem/28812809 <rdar://problem/28812809> to report that problem in the SDK. I also filed rdar://problem/28825862 <rdar://problem/28825862> to remind us to restore the more strict checking after we release a version of the tvOS SDK with a fix.
Thanks, Erik! > On Oct 18, 2016, at 9:46 AM, Erik Pilkington <erik.pilking...@gmail.com> > wrote: > > > On second thought, I think the header *is* ill-formed here. If we allowed > this behaviour, this would provide a way to circumvent an availability > diagnostic. For example, now the following compiles cleanly, where we really > should emit a diagnostic somewhere! > > typedef int unavail_int __attribute__((availability(tvos, unavailable))); > > __attribute__((availability(tvos, unavailable))) > @interface A > extern unavail_int foo; > @end > > int main() { (void)foo; } > > I’m not so sure about the politics of this, but could you file a radar or > something to get the header fixed (i.e, make the variable __TVOS_PROHIBITED)? > I’ll make a new patch that makes this a special case for now. > > Sorry for the flip-flop! > Erik > >> On Oct 18, 2016, at 11:47 AM, Erik Pilkington <erik.pilking...@gmail.com >> <mailto:erik.pilking...@gmail.com>> wrote: >> >> Hi Bob, >> I think the code in the header is fine here, so I reverted in r284486. >> Here’s a reduced version: >> >> typedef int unavail_int __attribute__((availability(tvos, unavailable))); >> >> __attribute__((availability(tvos, unavailable))) >> @interface A >> extern unavail_int foo; >> @end >> >> The problem is that ‘foo’ is actually at file context, not in the context of >> the interface, because we temporarily switched contexts to parse it. This >> means we can’t just look at DeclContexts in the DelayedDiagnostic case, >> which is what I was doing here. I’ll try to get a fix out for this soon! >> >> Thanks for pointing this out! >> Erik >> >>> On Oct 18, 2016, at 1:37 AM, Bob Wilson <bob.wil...@apple.com >>> <mailto:bob.wil...@apple.com>> wrote: >>> >>> Hi Erik, >>> >>> This change does not work with one of the headers from the AVFoundation >>> framework in tvOS 10.0. We can try to get a fix into the tvOS SDK, but it >>> will probably be a while before we could release an SDK with that change. >>> In the meantime, this is kind of disruptive. Can you find a way to keep the >>> previous behavior, at least until we have a chance to fix that header? >>> >>> The header in question is >>> System/Library/Frameworks/AVFoundation.framework/Headers/AVCaptureDevice.h >>> in the AppleTVSimulator.sdk directory from Xcode 8.0. The problematic >>> declaration is this one: >>> >>> AVF_EXPORT const AVCaptureWhiteBalanceGains >>> AVCaptureWhiteBalanceGainsCurrent NS_AVAILABLE_IOS(8_0); >>> >>> The problem is that the type is declared like this: >>> >>> typedef struct { >>> float redGain; >>> float greenGain; >>> float blueGain; >>> } AVCaptureWhiteBalanceGains NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED; >>> >>> The variable is missing the __TVOS_PROHIBITED attribute. You can reproduce >>> this easily: >>> >>> $ cat t.m >>> #import <AVFoundation/AVFoundation.h> >>> $ clang -c -arch x86_64 -mtvos-simulator-version-min=10.0 -isysroot >>> /Applications/Xcode-8.0.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk >>> t.m >>> /Applications/Xcode-8.0.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk/System/Library/Frameworks/AVFoundation.framework/Headers/AVCaptureDevice.h:1184:14: >>> error: >>> 'AVCaptureWhiteBalanceGains' is unavailable: not available on tvOS >>> extern const AVCaptureWhiteBalanceGains AVCaptureWhiteBalanceGainsCurren... >>> ^ >>> /Applications/Xcode-8.0.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk/System/Library/Frameworks/AVFoundation.framework/Headers/AVCaptureDevice.h:1081:3: >>> note: >>> 'AVCaptureWhiteBalanceGains' has been explicitly marked unavailable >>> here >>> } AVCaptureWhiteBalanceGains __attribute__((availability(ios,introduced=... >>> ^ >>> 1 error generated. >>> >>> Maybe we can carve out an exception based on the fact that this is just an >>> extern declaration of the variable — it’s not actually being used here. It >>> is also defined within the @interface for an Objective-C class, in case >>> that helps at all. >>> >>>> On Oct 14, 2016, at 12:08 PM, Erik Pilkington via cfe-commits >>>> <cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>> wrote: >>>> >>>> Author: epilk >>>> Date: Fri Oct 14 14:08:01 2016 >>>> New Revision: 284265 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=284265&view=rev >>>> <http://llvm.org/viewvc/llvm-project?rev=284265&view=rev> >>>> Log: >>>> [Sema] Refactor context checking for availability diagnostics >>>> >>>> This commit combines a couple of redundant functions that do availability >>>> attribute context checking into a more correct/simpler one. >>>> >>>> Differential revision: https://reviews.llvm.org/D25283 >>>> <https://reviews.llvm.org/D25283> >>>> >>>> Modified: >>>> cfe/trunk/include/clang/Sema/Sema.h >>>> cfe/trunk/lib/Sema/SemaDecl.cpp >>>> cfe/trunk/lib/Sema/SemaDeclAttr.cpp >>>> cfe/trunk/lib/Sema/SemaExpr.cpp >>>> cfe/trunk/test/SemaObjC/class-unavail-warning.m >>>> >>>> Modified: cfe/trunk/include/clang/Sema/Sema.h >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=284265&r1=284264&r2=284265&view=diff >>>> >>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=284265&r1=284264&r2=284265&view=diff> >>>> ============================================================================== >>>> --- cfe/trunk/include/clang/Sema/Sema.h (original) >>>> +++ cfe/trunk/include/clang/Sema/Sema.h Fri Oct 14 14:08:01 2016 >>>> @@ -9889,23 +9889,16 @@ public: >>>> return OriginalLexicalContext ? OriginalLexicalContext : CurContext; >>>> } >>>> >>>> - AvailabilityResult getCurContextAvailability() const; >>>> - >>>> - /// \brief Get the verison that this context implies. >>>> - /// For instance, a method in an interface that is annotated with an >>>> - /// availability attribuite effectively has the availability of the >>>> interface. >>>> - VersionTuple getVersionForDecl(const Decl *Ctx) const; >>>> - >>>> /// \brief The diagnostic we should emit for \c D, or \c AR_Available. >>>> /// >>>> /// \param D The declaration to check. Note that this may be altered to >>>> point >>>> /// to another declaration that \c D gets it's availability from. i.e., we >>>> /// walk the list of typedefs to find an availability attribute. >>>> /// >>>> - /// \param ContextVersion The version to compare availability against. >>>> - AvailabilityResult >>>> - ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D, VersionTuple >>>> ContextVersion, >>>> - std::string *Message); >>>> + /// \param Message If non-null, this will be populated with the message >>>> from >>>> + /// the availability attribute that is selected. >>>> + AvailabilityResult ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D, >>>> + std::string >>>> *Message); >>>> >>>> const DeclContext *getCurObjCLexicalContext() const { >>>> const DeclContext *DC = getCurLexicalContext(); >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=284265&r1=284264&r2=284265&view=diff >>>> >>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=284265&r1=284264&r2=284265&view=diff> >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct 14 14:08:01 2016 >>>> @@ -15615,29 +15615,3 @@ void Sema::ActOnPragmaWeakAlias(Identifi >>>> Decl *Sema::getObjCDeclContext() const { >>>> return (dyn_cast_or_null<ObjCContainerDecl>(CurContext)); >>>> } >>>> - >>>> -AvailabilityResult Sema::getCurContextAvailability() const { >>>> - 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, >>>> - // the entire method is considered deprecated from the >>>> - // purpose of checking if the current context is deprecated. >>>> - if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { >>>> - AvailabilityResult R = MD->getAvailability(); >>>> - if (R != AR_Available) >>>> - return R; >>>> - D = MD->getClassInterface(); >>>> - } >>>> - // If we are within an Objective-c @implementation, it >>>> - // gets the same availability context as the @interface. >>>> - else if (const ObjCImplementationDecl *ID = >>>> - dyn_cast<ObjCImplementationDecl>(D)) { >>>> - D = ID->getClassInterface(); >>>> - } >>>> - // Recover from user error. >>>> - return D ? D->getAvailability() : AR_Available; >>>> -} >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=284265&r1=284264&r2=284265&view=diff >>>> >>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=284265&r1=284264&r2=284265&view=diff> >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Oct 14 14:08:01 2016 >>>> @@ -6317,30 +6317,6 @@ static void handleDelayedForbiddenType(S >>>> diag.Triggered = true; >>>> } >>>> >>>> -static bool isDeclDeprecated(Decl *D) { >>>> - do { >>>> - if (D->isDeprecated()) >>>> - return true; >>>> - // A category implicitly has the availability of the interface. >>>> - if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) >>>> - if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface()) >>>> - return Interface->isDeprecated(); >>>> - } while ((D = cast_or_null<Decl>(D->getDeclContext()))); >>>> - return false; >>>> -} >>>> - >>>> -static bool isDeclUnavailable(Decl *D) { >>>> - do { >>>> - if (D->isUnavailable()) >>>> - return true; >>>> - // A category implicitly has the availability of the interface. >>>> - if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) >>>> - if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface()) >>>> - return Interface->isUnavailable(); >>>> - } while ((D = cast_or_null<Decl>(D->getDeclContext()))); >>>> - return false; >>>> -} >>>> - >>>> static const AvailabilityAttr *getAttrForPlatform(ASTContext &Context, >>>> const Decl *D) { >>>> // Check each AvailabilityAttr to find the one for this platform. >>>> @@ -6369,6 +6345,49 @@ static const AvailabilityAttr *getAttrFo >>>> return nullptr; >>>> } >>>> >>>> +/// \brief whether we should emit a diagnostic for \c K and \c >>>> DeclVersion in >>>> +/// the context of \c Ctx. For example, we should emit an unavailable >>>> diagnostic >>>> +/// in a deprecated context, but not the other way around. >>>> +static bool ShouldDiagnoseAvailabilityInContext(Sema &S, >>>> AvailabilityResult K, >>>> + VersionTuple DeclVersion, >>>> + Decl *Ctx) { >>>> + assert(K != AR_Available && "Expected an unavailable declaration >>>> here!"); >>>> + >>>> + // Checks if we should emit the availability diagnostic in the context >>>> of C. >>>> + auto CheckContext = [&](const Decl *C) { >>>> + if (K == AR_NotYetIntroduced) { >>>> + if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, C)) >>>> + if (AA->getIntroduced() >= DeclVersion) >>>> + return true; >>>> + } else if (K == AR_Deprecated) >>>> + if (C->isDeprecated()) >>>> + return true; >>>> + >>>> + if (C->isUnavailable()) >>>> + return true; >>>> + return false; >>>> + }; >>>> + >>>> + do { >>>> + if (CheckContext(Ctx)) >>>> + return false; >>>> + >>>> + // An implementation implicitly has the availability of the interface. >>>> + if (auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) { >>>> + if (const ObjCInterfaceDecl *Interface = >>>> CatOrImpl->getClassInterface()) >>>> + if (CheckContext(Interface)) >>>> + return false; >>>> + } >>>> + // A category implicitly has the availability of the interface. >>>> + else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(Ctx)) >>>> + if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface()) >>>> + if (CheckContext(Interface)) >>>> + return false; >>>> + } while ((Ctx = cast_or_null<Decl>(Ctx->getDeclContext()))); >>>> + >>>> + return true; >>>> +} >>>> + >>>> static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, >>>> Decl *Ctx, const NamedDecl *D, >>>> StringRef Message, SourceLocation Loc, >>>> @@ -6385,11 +6404,15 @@ static void DoEmitAvailabilityWarning(Se >>>> // Matches diag::note_availability_specified_here. >>>> unsigned available_here_select_kind; >>>> >>>> - // Don't warn if our current context is deprecated or unavailable. >>>> + VersionTuple DeclVersion; >>>> + if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, D)) >>>> + DeclVersion = AA->getIntroduced(); >>>> + >>>> + if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx)) >>>> + return; >>>> + >>>> switch (K) { >>>> case AR_Deprecated: >>>> - if (isDeclDeprecated(Ctx) || isDeclUnavailable(Ctx)) >>>> - return; >>>> diag = !ObjCPropertyAccess ? diag::warn_deprecated >>>> : diag::warn_property_method_deprecated; >>>> diag_message = diag::warn_deprecated_message; >>>> @@ -6399,8 +6422,6 @@ static void DoEmitAvailabilityWarning(Se >>>> break; >>>> >>>> case AR_Unavailable: >>>> - if (isDeclUnavailable(Ctx)) >>>> - return; >>>> diag = !ObjCPropertyAccess ? diag::err_unavailable >>>> : diag::err_property_method_unavailable; >>>> diag_message = diag::err_unavailable_message; >>>> @@ -6615,29 +6636,6 @@ void Sema::EmitAvailabilityWarning(Avail >>>> ObjCProperty, ObjCPropertyAccess); >>>> } >>>> >>>> -VersionTuple Sema::getVersionForDecl(const Decl *D) const { >>>> - assert(D && "Expected a declaration here!"); >>>> - >>>> - VersionTuple DeclVersion; >>>> - if (const auto *AA = getAttrForPlatform(getASTContext(), D)) >>>> - DeclVersion = AA->getIntroduced(); >>>> - >>>> - const ObjCInterfaceDecl *Interface = nullptr; >>>> - >>>> - if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) >>>> - Interface = MD->getClassInterface(); >>>> - else if (const auto *ID = dyn_cast<ObjCImplementationDecl>(D)) >>>> - Interface = ID->getClassInterface(); >>>> - >>>> - if (Interface) { >>>> - if (const auto *AA = getAttrForPlatform(getASTContext(), Interface)) >>>> - if (AA->getIntroduced() > DeclVersion) >>>> - DeclVersion = AA->getIntroduced(); >>>> - } >>>> - >>>> - return std::max(DeclVersion, >>>> Context.getTargetInfo().getPlatformMinVersion()); >>>> -} >>>> - >>>> namespace { >>>> >>>> /// \brief This class implements -Wunguarded-availability. >>>> @@ -6651,6 +6649,7 @@ class DiagnoseUnguardedAvailability >>>> typedef RecursiveASTVisitor<DiagnoseUnguardedAvailability> Base; >>>> >>>> Sema &SemaRef; >>>> + Decl *Ctx; >>>> >>>> /// Stack of potentially nested 'if (@available(...))'s. >>>> SmallVector<VersionTuple, 8> AvailabilityStack; >>>> @@ -6658,9 +6657,10 @@ class DiagnoseUnguardedAvailability >>>> void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range); >>>> >>>> public: >>>> - DiagnoseUnguardedAvailability(Sema &SemaRef, VersionTuple BaseVersion) >>>> - : SemaRef(SemaRef) { >>>> - AvailabilityStack.push_back(BaseVersion); >>>> + DiagnoseUnguardedAvailability(Sema &SemaRef, Decl *Ctx) >>>> + : SemaRef(SemaRef), Ctx(Ctx) { >>>> + AvailabilityStack.push_back( >>>> + SemaRef.Context.getTargetInfo().getPlatformMinVersion()); >>>> } >>>> >>>> void IssueDiagnostics(Stmt *S) { TraverseStmt(S); } >>>> @@ -6693,8 +6693,8 @@ void DiagnoseUnguardedAvailability::Diag >>>> NamedDecl *D, SourceRange Range) { >>>> >>>> VersionTuple ContextVersion = AvailabilityStack.back(); >>>> - if (AvailabilityResult Result = >>>> SemaRef.ShouldDiagnoseAvailabilityOfDecl( >>>> - D, ContextVersion, nullptr)) { >>>> + if (AvailabilityResult Result = >>>> + SemaRef.ShouldDiagnoseAvailabilityOfDecl(D, nullptr)) { >>>> // All other diagnostic kinds have already been handled in >>>> // DiagnoseAvailabilityOfDecl. >>>> if (Result != AR_NotYetIntroduced) >>>> @@ -6703,6 +6703,14 @@ void DiagnoseUnguardedAvailability::Diag >>>> const AvailabilityAttr *AA = >>>> getAttrForPlatform(SemaRef.getASTContext(), D); >>>> VersionTuple Introduced = AA->getIntroduced(); >>>> >>>> + if (ContextVersion >= Introduced) >>>> + return; >>>> + >>>> + // If the context of this function is less available than D, we >>>> should not >>>> + // emit a diagnostic. >>>> + if (!ShouldDiagnoseAvailabilityInContext(SemaRef, Result, Introduced, >>>> Ctx)) >>>> + return; >>>> + >>>> SemaRef.Diag(Range.getBegin(), diag::warn_unguarded_availability) >>>> << Range << D >>>> << AvailabilityAttr::getPrettyPlatformName( >>>> @@ -6777,6 +6785,5 @@ void Sema::DiagnoseUnguardedAvailability >>>> >>>> assert(Body && "Need a body here!"); >>>> >>>> - VersionTuple BaseVersion = getVersionForDecl(D); >>>> - DiagnoseUnguardedAvailability(*this, >>>> BaseVersion).IssueDiagnostics(Body); >>>> + DiagnoseUnguardedAvailability(*this, D).IssueDiagnostics(Body); >>>> } >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=284265&r1=284264&r2=284265&view=diff >>>> >>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=284265&r1=284264&r2=284265&view=diff> >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Oct 14 14:08:01 2016 >>>> @@ -103,9 +103,9 @@ static bool HasRedeclarationWithoutAvail >>>> return false; >>>> } >>>> >>>> -AvailabilityResult Sema::ShouldDiagnoseAvailabilityOfDecl( >>>> - NamedDecl *&D, VersionTuple ContextVersion, std::string *Message) { >>>> - AvailabilityResult Result = D->getAvailability(Message, ContextVersion); >>>> +AvailabilityResult >>>> +Sema::ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D, std::string >>>> *Message) { >>>> + AvailabilityResult Result = D->getAvailability(Message); >>>> >>>> // For typedefs, if the typedef declaration appears available look >>>> // to the underlying type to see if it is more restrictive. >>>> @@ -113,7 +113,7 @@ AvailabilityResult Sema::ShouldDiagnoseA >>>> if (Result == AR_Available) { >>>> if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) { >>>> D = TT->getDecl(); >>>> - Result = D->getAvailability(Message, ContextVersion); >>>> + Result = D->getAvailability(Message); >>>> continue; >>>> } >>>> } >>>> @@ -124,7 +124,7 @@ AvailabilityResult Sema::ShouldDiagnoseA >>>> if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) { >>>> if (IDecl->getDefinition()) { >>>> D = IDecl->getDefinition(); >>>> - Result = D->getAvailability(Message, ContextVersion); >>>> + Result = D->getAvailability(Message); >>>> } >>>> } >>>> >>>> @@ -132,18 +132,10 @@ AvailabilityResult Sema::ShouldDiagnoseA >>>> if (Result == AR_Available) { >>>> const DeclContext *DC = ECD->getDeclContext(); >>>> if (const EnumDecl *TheEnumDecl = dyn_cast<EnumDecl>(DC)) >>>> - Result = TheEnumDecl->getAvailability(Message, ContextVersion); >>>> + Result = TheEnumDecl->getAvailability(Message); >>>> } >>>> >>>> - switch (Result) { >>>> - case AR_Available: >>>> - return Result; >>>> - >>>> - case AR_Unavailable: >>>> - case AR_Deprecated: >>>> - return getCurContextAvailability() != Result ? Result : AR_Available; >>>> - >>>> - case AR_NotYetIntroduced: { >>>> + if (Result == AR_NotYetIntroduced) { >>>> // Don't do this for enums, they can't be redeclared. >>>> if (isa<EnumConstantDecl>(D) || isa<EnumDecl>(D)) >>>> return AR_Available; >>>> @@ -166,23 +158,18 @@ AvailabilityResult Sema::ShouldDiagnoseA >>>> >>>> return Warn ? AR_NotYetIntroduced : AR_Available; >>>> } >>>> - } >>>> - llvm_unreachable("Unknown availability result!"); >>>> + >>>> + return Result; >>>> } >>>> >>>> static void >>>> DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc, >>>> const ObjCInterfaceDecl *UnknownObjCClass, >>>> bool ObjCPropertyAccess) { >>>> - VersionTuple ContextVersion; >>>> - if (const DeclContext *DC = S.getCurObjCLexicalContext()) >>>> - ContextVersion = S.getVersionForDecl(cast<Decl>(DC)); >>>> - >>>> std::string Message; >>>> - // See if this declaration is unavailable, deprecated, or partial in the >>>> - // current context. >>>> + // See if this declaration is unavailable, deprecated, or partial. >>>> if (AvailabilityResult Result = >>>> - S.ShouldDiagnoseAvailabilityOfDecl(D, ContextVersion, >>>> &Message)) { >>>> + S.ShouldDiagnoseAvailabilityOfDecl(D, &Message)) { >>>> >>>> if (Result == AR_NotYetIntroduced && S.getCurFunctionOrMethodDecl()) { >>>> S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true; >>>> @@ -192,8 +179,7 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name >>>> const ObjCPropertyDecl *ObjCPDecl = nullptr; >>>> if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { >>>> if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) { >>>> - AvailabilityResult PDeclResult = >>>> - PD->getAvailability(nullptr, ContextVersion); >>>> + AvailabilityResult PDeclResult = PD->getAvailability(nullptr); >>>> if (PDeclResult == Result) >>>> ObjCPDecl = PD; >>>> } >>>> >>>> Modified: cfe/trunk/test/SemaObjC/class-unavail-warning.m >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/class-unavail-warning.m?rev=284265&r1=284264&r2=284265&view=diff >>>> >>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/class-unavail-warning.m?rev=284265&r1=284264&r2=284265&view=diff> >>>> ============================================================================== >>>> --- cfe/trunk/test/SemaObjC/class-unavail-warning.m (original) >>>> +++ cfe/trunk/test/SemaObjC/class-unavail-warning.m Fri Oct 14 14:08:01 >>>> 2016 >>>> @@ -1,4 +1,4 @@ >>>> -// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -verify >>>> %s >>>> +// RUN: %clang_cc1 -fsyntax-only -fblocks -triple x86_64-apple-darwin10 >>>> -verify %s >>>> // rdar://9092208 <rdar://9092208> >>>> >>>> __attribute__((unavailable("not available"))) >>>> @@ -98,3 +98,19 @@ UNAVAILABLE >>>> @end >>>> @interface UnavailSub(cat)<SomeProto> // no error >>>> @end >>>> + >>>> +int unavail_global UNAVAILABLE; >>>> + >>>> +UNAVAILABLE __attribute__((objc_root_class)) >>>> +@interface TestAttrContext >>>> +-meth; >>>> +@end >>>> + >>>> +@implementation TestAttrContext >>>> +-meth { >>>> + unavail_global = 2; // no warn >>>> + (void) ^{ >>>> + unavail_global = 4; // no warn >>>> + }; >>>> +} >>>> +@end >>>> >>>> >>>> _______________________________________________ >>>> cfe-commits mailing list >>>> cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org> >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>> <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits> >>> >> >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits