diff options
author | Douglas Gregor <dgregor@apple.com> | 2015-09-30 21:27:42 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2015-09-30 21:27:42 +0000 |
commit | d2a713e41bd362125ba80a3eecc7e05876e06adb (patch) | |
tree | 17c9fe147727c3d80269947aa6dd383e9f2da0b7 /clang/lib/Sema/SemaDecl.cpp | |
parent | b1ff6e4260dfe4cce64a2ebb425360f706aeb42b (diff) | |
download | bcm5719-llvm-d2a713e41bd362125ba80a3eecc7e05876e06adb.tar.gz bcm5719-llvm-d2a713e41bd362125ba80a3eecc7e05876e06adb.zip |
Don't inherit availability information when implementing a protocol requirement.
When an Objective-C method implements a protocol requirement, do not
inherit any availability information from the protocol
requirement. Rather, check that the implementation is not less
available than the protocol requirement, as we do when overriding a
method that has availability. Fixes rdar://problem/22734745.
llvm-svn: 248949
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 571c9baa048..a359ef49311 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2175,14 +2175,15 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { } static bool mergeDeclAttribute(Sema &S, NamedDecl *D, - const InheritableAttr *Attr, bool Override) { + const InheritableAttr *Attr, + Sema::AvailabilityMergeKind AMK) { InheritableAttr *NewAttr = nullptr; unsigned AttrSpellingListIndex = Attr->getSpellingListIndex(); if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr)) NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(), AA->getIntroduced(), AA->getDeprecated(), AA->getObsoleted(), AA->getUnavailable(), - AA->getMessage(), Override, + AA->getMessage(), AMK, AttrSpellingListIndex); else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr)) NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), @@ -2219,7 +2220,11 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, // AlignedAttrs are handled separately, because we need to handle all // such attributes on a declaration at the same time. NewAttr = nullptr; - else if (isa<DeprecatedAttr>(Attr) && Override) + else if (isa<DeprecatedAttr>(Attr) && + (AMK == Sema::AMK_Override || + AMK == Sema::AMK_ProtocolImplementation)) + NewAttr = nullptr; + else if (isa<UnavailableAttr>(Attr) && AMK == Sema::AMK_ProtocolImplementation) NewAttr = nullptr; else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr)) NewAttr = cast<InheritableAttr>(Attr->clone(S.Context)); @@ -2366,8 +2371,8 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, if (!foundAny) New->setAttrs(AttrVec()); for (auto *I : Old->specific_attrs<InheritableAttr>()) { - bool Override = false; // Ignore deprecated/unavailable/availability attributes if requested. + AvailabilityMergeKind LocalAMK = AMK_None; if (isa<DeprecatedAttr>(I) || isa<UnavailableAttr>(I) || isa<AvailabilityAttr>(I)) { @@ -2376,10 +2381,9 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, continue; case AMK_Redeclaration: - break; - case AMK_Override: - Override = true; + case AMK_ProtocolImplementation: + LocalAMK = AMK; break; } } @@ -2388,7 +2392,7 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, if (isa<UsedAttr>(I)) continue; - if (mergeDeclAttribute(*this, New, I, Override)) + if (mergeDeclAttribute(*this, New, I, LocalAMK)) foundAny = true; } @@ -3156,8 +3160,11 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, // Merge the attributes, including deprecated/unavailable AvailabilityMergeKind MergeKind = - isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration - : AMK_Override; + isa<ObjCProtocolDecl>(oldMethod->getDeclContext()) + ? AMK_ProtocolImplementation + : isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration + : AMK_Override; + mergeDeclAttributes(newMethod, oldMethod, MergeKind); // Merge attributes from the parameters. |