Skip to content

Commit e4e6bcb

Browse files
committed
[domain availability] Stop copying attributes from an ObjCMethodDecl to
another Stop copying domain availability attributes between ObjCMethodDecls, except when moving them from a method declaration to its implementation. rdar://160157241
1 parent 844d502 commit e4e6bcb

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3293,7 +3293,7 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
32933293
Diag(Old->getLocation(), diag::note_previous_declaration);
32943294
}
32953295

3296-
if (auto *ND = dyn_cast<NamedDecl>(Old))
3296+
if (auto *ND = dyn_cast<NamedDecl>(Old); ND && !isa<ObjCMethodDecl>(ND))
32973297
copyFeatureAvailabilityCheck(New, ND, true);
32983298

32993299
if (!Old->hasAttrs())
@@ -3328,6 +3328,9 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
33283328
if (isa<UsedAttr>(I) || isa<RetainAttr>(I))
33293329
continue;
33303330

3331+
if (isa<ObjCMethodDecl>(Old) && isa<DomainAvailabilityAttr>(I))
3332+
continue;
3333+
33313334
if (isa<InferredNoReturnAttr>(I)) {
33323335
if (auto *FD = dyn_cast<FunctionDecl>(New)) {
33333336
if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)

clang/lib/Sema/SemaDeclObjC.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,24 @@ HasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param) {
364364
return !T.getLocalQualifiers().hasObjCLifetime();
365365
}
366366

367+
/// Helper function to copy domain availability attributes on methods in the
368+
/// class interfaces or categories to methods in the implementations.
369+
static void copyDomainAvailabilityAttr(ObjCMethodDecl *MD, Sema &SemaRef) {
370+
ObjCContainerDecl *CD = nullptr;
371+
372+
if (ObjCCategoryDecl *CatD = MD->getCategory())
373+
CD = CatD;
374+
else if (ObjCInterfaceDecl *ID = MD->getClassInterface())
375+
CD = ID;
376+
377+
if (!CD)
378+
return;
379+
380+
if (ObjCMethodDecl *IDecl =
381+
CD->getMethod(MD->getSelector(), MD->isInstanceMethod()))
382+
SemaRef.copyFeatureAvailabilityCheck(MD, IDecl, true);
383+
}
384+
367385
/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
368386
/// and user declared, in the method definition's AST.
369387
void SemaObjC::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
@@ -379,6 +397,8 @@ void SemaObjC::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
379397
if (!MDecl)
380398
return;
381399

400+
copyDomainAvailabilityAttr(MDecl, SemaRef);
401+
382402
QualType ResultType = MDecl->getReturnType();
383403
if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
384404
!MDecl->isInvalidDecl() &&

clang/test/CodeGenObjC/feature-availability.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ +(void)unavailable_cm1 __attribute__((availability(domain:feature2, AVAIL)));
202202
@implementation C3
203203
-(void)p1_m1 {
204204
}
205-
-(void)unavailable_p2_m2 {
205+
-(void)unavailable_p2_m2 __attribute__((availability(domain:feature2, AVAIL))) {
206206
unavailable_func1();
207207
}
208208
+(void)cm0 {

clang/test/SemaObjC/feature-availability.m

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,30 @@ @interface Base6 <P1, P2>
176176
@end
177177

178178
void foo(id<P1>); // expected-error {{use of 'P1' requires feature 'feature1' to be unavailable}}
179+
180+
@interface Base8
181+
@property (copy) id x;
182+
@end
183+
184+
__attribute__((availability(domain:feature1, AVAIL)))
185+
@interface Derived8 : Base8
186+
@property (copy) id x;
187+
@end
188+
189+
@interface Base9
190+
-(void)m4 __attribute__((availability(domain:feature1, AVAIL)));
191+
@end
192+
193+
@interface Derived9 : Base9
194+
-(void)m4;
195+
@end
196+
197+
@implementation Derived9 : Base9
198+
-(void)m4 {
199+
// Check that this method doesn't inherit the domain availablity attribute
200+
// from the base class method.
201+
func1(); // expected-error {{use of 'func1' requires feature 'feature1' to be available}}
202+
203+
[super m4]; // expected-error {{use of 'm4' requires feature 'feature1' to be available}}
204+
}
205+
@end

0 commit comments

Comments
 (0)