For the archives, here's said patch: https://reviews.llvm.org/D56816
(Thanks!) On Wed, Jan 16, 2019 at 5:26 PM Alex L <arpha...@gmail.com> wrote: > Hi, > > We are planning to fix this issue by not checking if the method is > defined. I will post a patch this week. > > Cheers, > Alex > > On Fri, 11 Jan 2019 at 10:26, Alex L <arpha...@gmail.com> wrote: > >> Thanks, we might have similar cases in our code base as well. We'll see >> if we can fix that too. >> >> On Fri, 11 Jan 2019 at 06:13, Nico Weber <tha...@chromium.org> wrote: >> >>> Here's some user feedback on this new feature. >>> >>> It looks like the warning is only suppressed if `init` has a definition >>> in the @interface block. In the 4 cases where we saw this warning fire >>> after r349841, it still fires after this change because in all 4 cases a >>> class marked init as unavailable in the @interface but didn't add a >>> definition of it in the classes @implementation (instead relying on calling >>> the superclass's (NSObject) init). >>> >>> It's pretty easy to just add >>> >>> - (instancetype)init { return [super init]; } >>> >>> to these 4 classes, but: >>> a) it doesn't Just Work >>> b) the diagnostic doesn't make it clear that adding a definition of init >>> will suppress the warning. >>> >>> Up to you to decide what (if anything) to do with this feedback :-) >>> >>> (https://bugs.chromium.org/p/chromium/issues/detail?id=917351#c17 has a >>> full reduced code snippet.) >>> >>> On Wed, Jan 9, 2019 at 5:35 PM Alex Lorenz via cfe-commits < >>> cfe-commits@lists.llvm.org> wrote: >>> >>>> Author: arphaman >>>> Date: Wed Jan 9 14:31:37 2019 >>>> New Revision: 350768 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=350768&view=rev >>>> Log: >>>> [ObjC] Allow the use of implemented unavailable methods from within >>>> the @implementation context >>>> >>>> In Objective-C, it's common for some frameworks to mark some methods >>>> like init >>>> as unavailable in the @interface to prohibit their usage. However, these >>>> frameworks then often implemented said method and refer to it in >>>> another method >>>> that acts as a factory for that object. The recent change to how >>>> messages to >>>> self are type checked in clang (r349841) introduced a regression which >>>> started >>>> to prohibit this pattern with an X is unavailable error. This commit >>>> addresses >>>> the aforementioned regression. >>>> >>>> rdar://47134898 >>>> >>>> Differential Revision: https://reviews.llvm.org/D56469 >>>> >>>> Added: >>>> cfe/trunk/test/SemaObjC/call-unavailable-init-in-self.m >>>> Modified: >>>> cfe/trunk/lib/Sema/SemaDeclAttr.cpp >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=350768&r1=350767&r2=350768&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Jan 9 14:31:37 2019 >>>> @@ -7269,9 +7269,10 @@ ShouldDiagnoseAvailabilityOfDecl(Sema &S >>>> /// 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) { >>>> +static bool >>>> +ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K, >>>> + VersionTuple DeclVersion, Decl >>>> *Ctx, >>>> + const NamedDecl *OffendingDecl) { >>>> assert(K != AR_Available && "Expected an unavailable declaration >>>> here!"); >>>> >>>> // Checks if we should emit the availability diagnostic in the >>>> context of C. >>>> @@ -7280,9 +7281,22 @@ static bool ShouldDiagnoseAvailabilityIn >>>> if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, >>>> C)) >>>> if (AA->getIntroduced() >= DeclVersion) >>>> return true; >>>> - } else if (K == AR_Deprecated) >>>> + } else if (K == AR_Deprecated) { >>>> if (C->isDeprecated()) >>>> return true; >>>> + } else if (K == AR_Unavailable) { >>>> + // It is perfectly fine to refer to an 'unavailable' Objective-C >>>> method >>>> + // when it's actually defined and is referenced from within the >>>> + // @implementation itself. In this context, we interpret >>>> unavailable as a >>>> + // form of access control. >>>> + if (const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) { >>>> + if (const auto *Impl = dyn_cast<ObjCImplDecl>(C)) { >>>> + if (MD->getClassInterface() == Impl->getClassInterface() && >>>> + MD->isDefined()) >>>> + return true; >>>> + } >>>> + } >>>> + } >>>> >>>> if (C->isUnavailable()) >>>> return true; >>>> @@ -7471,7 +7485,8 @@ static void DoEmitAvailabilityWarning(Se >>>> if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, >>>> OffendingDecl)) >>>> DeclVersion = AA->getIntroduced(); >>>> >>>> - if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx)) >>>> + if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx, >>>> + OffendingDecl)) >>>> return; >>>> >>>> SourceLocation Loc = Locs.front(); >>>> @@ -7955,7 +7970,8 @@ void DiagnoseUnguardedAvailability::Diag >>>> >>>> // If the context of this function is less available than D, we >>>> should not >>>> // emit a diagnostic. >>>> - if (!ShouldDiagnoseAvailabilityInContext(SemaRef, Result, >>>> Introduced, Ctx)) >>>> + if (!ShouldDiagnoseAvailabilityInContext(SemaRef, Result, >>>> Introduced, Ctx, >>>> + OffendingDecl)) >>>> return; >>>> >>>> // We would like to emit the diagnostic even if >>>> -Wunguarded-availability is >>>> >>>> Added: cfe/trunk/test/SemaObjC/call-unavailable-init-in-self.m >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/call-unavailable-init-in-self.m?rev=350768&view=auto >>>> >>>> ============================================================================== >>>> --- cfe/trunk/test/SemaObjC/call-unavailable-init-in-self.m (added) >>>> +++ cfe/trunk/test/SemaObjC/call-unavailable-init-in-self.m Wed Jan 9 >>>> 14:31:37 2019 >>>> @@ -0,0 +1,68 @@ >>>> +// RUN: %clang_cc1 -x objective-c -verify -fobjc-arc %s >>>> + >>>> +@interface NSObject >>>> + >>>> ++ (instancetype)new; >>>> ++ (instancetype)alloc; >>>> + >>>> +@end >>>> + >>>> +@interface Sub: NSObject >>>> + >>>> +- (instancetype)init __attribute__((unavailable)); // expected-note 4 >>>> {{'init' has been explicitly marked unavailable here}} >>>> + >>>> +- (void)notImplemented __attribute__((unavailable)); // expected-note >>>> {{'notImplemented' has been explicitly marked unavailable here}} >>>> + >>>> +@end >>>> + >>>> +@implementation Sub >>>> + >>>> ++ (Sub *)create { >>>> + return [[self alloc] init]; >>>> +} >>>> + >>>> ++ (Sub *)create2 { >>>> + return [self new]; >>>> +} >>>> + >>>> ++ (Sub *)create3 { >>>> + return [Sub new]; >>>> +} >>>> + >>>> +- (instancetype) init { >>>> + return self; >>>> +} >>>> + >>>> +- (void)reportUseOfUnimplemented { >>>> + [self notImplemented]; // expected-error {{'notImplemented' is >>>> unavailable}} >>>> +} >>>> + >>>> +@end >>>> + >>>> +@interface SubClassContext: Sub >>>> +@end >>>> + >>>> +@implementation SubClassContext >>>> + >>>> +- (void)subClassContext { >>>> + (void)[[Sub alloc] init]; // expected-error {{'init' is unavailable}} >>>> + (void)[Sub new]; // expected-error {{'new' is unavailable}} >>>> +} >>>> + >>>> +@end >>>> + >>>> +void unrelatedContext() { >>>> + (void)[[Sub alloc] init]; // expected-error {{'init' is unavailable}} >>>> + (void)[Sub new]; // expected-error {{'new' is unavailable}} >>>> +} >>>> + >>>> +@interface X @end >>>> + >>>> +@interface X (Foo) >>>> +-(void)meth __attribute__((unavailable)); >>>> +@end >>>> + >>>> +@implementation X (Foo) >>>> +-(void)meth {} >>>> +-(void)call_it { [self meth]; } >>>> +@end >>>> >>>> >>>> _______________________________________________ >>>> cfe-commits mailing list >>>> cfe-commits@lists.llvm.org >>>> 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