Skip to content

[feature availability] Don't disallow annotating ObjC interfaces and protocols with features when there are unannotated forward declarations of them #11000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: swift/release/6.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3658,11 +3658,27 @@ void Sema::copyFeatureAvailability(Decl *Dst, Decl *Src) {
}
}

static bool isForwardDeclaration(Decl *Prev, Decl *D) {
if (Prev->getCanonicalDecl() != D->getCanonicalDecl())
return false;
if (auto *ID = dyn_cast<ObjCInterfaceDecl>(Prev))
return !ID->getPreviousDecl();
if (auto *PD = dyn_cast<ObjCProtocolDecl>(Prev))
return !PD->getPreviousDecl();
return false;
}

void Sema::copyFeatureAvailabilityCheck(Decl *Dst, NamedDecl *Src,
bool Redeclaration) {
if (Dst->isInvalidDecl())
return;

// Don't check whether a new feature is being added if Src is a
// forward declaration of classes and protocols as they cannnot be
// annotated with attributes.
if (isForwardDeclaration(Src, Dst))
return;

llvm::SmallDenseMap<StringRef, DomainAvailabilityAttr *> DstToAttr;

for (auto *AA : Dst->specific_attrs<DomainAvailabilityAttr>())
Expand Down
4 changes: 4 additions & 0 deletions clang/test/SemaObjC/feature-availability.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ -(struct S1)m2 __attribute__((availability(domain:feature1, AVAIL)));
-(struct S1)m3 __attribute__((availability(domain:feature1, UNAVAIL))); // expected-error {{use of 'S1' requires feature 'feature1' to be available}}
@end

@class Base0;

__attribute__((availability(domain:feature1, AVAIL))) // expected-note 2 {{is incompatible with __attribute__((availability(domain:feature1, 0)))}}
@interface Base0 {
struct S0 ivar0; // expected-error {{use of 'S0' requires feature 'feature1' to be unavailable}}
Expand Down Expand Up @@ -134,6 +136,8 @@ @interface Derived2(Cat1)
@implementation Derived2(Cat1)
@end

@protocol P1;

__attribute__((availability(domain:feature1, UNAVAIL)))
@protocol P1
@end
Expand Down