r307175 - [Sema] Don't allow -Wunguarded-availability to be silenced with redecls
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 5 10:08:56 PDT 2017
Author: epilk
Date: Wed Jul 5 10:08:56 2017
New Revision: 307175
URL: http://llvm.org/viewvc/llvm-project?rev=307175&view=rev
Log:
[Sema] Don't allow -Wunguarded-availability to be silenced with redecls
Differential revision: https://reviews.llvm.org/D33816
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/DelayedDiagnostic.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/DelayedDiagnostic.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Sema/attr-availability.c
cfe/trunk/test/Sema/attr-deprecated.c
cfe/trunk/test/Sema/attr-unavailable-message.c
cfe/trunk/test/SemaCXX/attr-deprecated.cpp
cfe/trunk/test/SemaObjC/attr-availability.m
cfe/trunk/test/SemaObjC/unguarded-availability-new.m
cfe/trunk/test/SemaObjC/unguarded-availability.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul 5 10:08:56 2017
@@ -2880,7 +2880,7 @@ def warn_partial_availability : Warning<
def warn_partial_availability_new : Warning<warn_partial_availability.Text>,
InGroup<UnguardedAvailabilityNew>;
def note_partial_availability_silence : Note<
- "explicitly redeclare %0 to silence this warning">;
+ "annotate %select{%1|anonymous %1}0 with an availability attribute to silence">;
def note_unguarded_available_silence : Note<
"enclose %0 in %select{an @available|a __builtin_available}1 check to silence"
" this warning">;
Modified: cfe/trunk/include/clang/Sema/DelayedDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DelayedDiagnostic.h?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DelayedDiagnostic.h (original)
+++ cfe/trunk/include/clang/Sema/DelayedDiagnostic.h Wed Jul 5 10:08:56 2017
@@ -124,7 +124,8 @@ public:
static DelayedDiagnostic makeAvailability(AvailabilityResult AR,
SourceLocation Loc,
- const NamedDecl *D,
+ const NamedDecl *ReferringDecl,
+ const NamedDecl *OffendingDecl,
const ObjCInterfaceDecl *UnknownObjCClass,
const ObjCPropertyDecl *ObjCProperty,
StringRef Msg,
@@ -164,9 +165,13 @@ public:
return *reinterpret_cast<const AccessedEntity*>(AccessData);
}
- const NamedDecl *getAvailabilityDecl() const {
+ const NamedDecl *getAvailabilityReferringDecl() const {
assert(Kind == Availability && "Not an availability diagnostic.");
- return AvailabilityData.Decl;
+ return AvailabilityData.ReferringDecl;
+ }
+
+ const NamedDecl *getAvailabilityOffendingDecl() const {
+ return AvailabilityData.OffendingDecl;
}
StringRef getAvailabilityMessage() const {
@@ -213,7 +218,8 @@ public:
private:
struct AD {
- const NamedDecl *Decl;
+ const NamedDecl *ReferringDecl;
+ const NamedDecl *OffendingDecl;
const ObjCInterfaceDecl *UnknownObjCClass;
const ObjCPropertyDecl *ObjCProperty;
const char *Message;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Jul 5 10:08:56 2017
@@ -3881,7 +3881,9 @@ public:
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
- void EmitAvailabilityWarning(AvailabilityResult AR, NamedDecl *D,
+ void EmitAvailabilityWarning(AvailabilityResult AR,
+ const NamedDecl *ReferringDecl,
+ const NamedDecl *OffendingDecl,
StringRef Message, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
const ObjCPropertyDecl *ObjCProperty,
@@ -10413,16 +10415,14 @@ public:
return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
}
- /// \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.
+ /// The diagnostic we should emit for \c D, and the declaration that
+ /// originated it, or \c AR_Available.
///
+ /// \param D The declaration to check.
/// \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);
+ std::pair<AvailabilityResult, const NamedDecl *>
+ ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message);
const DeclContext *getCurObjCLexicalContext() const {
const DeclContext *DC = getCurLexicalContext();
Modified: cfe/trunk/lib/Sema/DelayedDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DelayedDiagnostic.cpp?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DelayedDiagnostic.cpp (original)
+++ cfe/trunk/lib/Sema/DelayedDiagnostic.cpp Wed Jul 5 10:08:56 2017
@@ -22,7 +22,8 @@ using namespace sema;
DelayedDiagnostic
DelayedDiagnostic::makeAvailability(AvailabilityResult AR,
SourceLocation Loc,
- const NamedDecl *D,
+ const NamedDecl *ReferringDecl,
+ const NamedDecl *OffendingDecl,
const ObjCInterfaceDecl *UnknownObjCClass,
const ObjCPropertyDecl *ObjCProperty,
StringRef Msg,
@@ -31,7 +32,8 @@ DelayedDiagnostic::makeAvailability(Avai
DD.Kind = Availability;
DD.Triggered = false;
DD.Loc = Loc;
- DD.AvailabilityData.Decl = D;
+ DD.AvailabilityData.ReferringDecl = ReferringDecl;
+ DD.AvailabilityData.OffendingDecl = OffendingDecl;
DD.AvailabilityData.UnknownObjCClass = UnknownObjCClass;
DD.AvailabilityData.ObjCProperty = ObjCProperty;
char *MessageData = nullptr;
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Jul 5 10:08:56 2017
@@ -6929,8 +6929,34 @@ shouldDiagnoseAvailabilityByDefault(cons
DeclVersion >= ForceAvailabilityFromVersion;
}
+static NamedDecl *findEnclosingDeclToAnnotate(Decl *OrigCtx) {
+ for (Decl *Ctx = OrigCtx; Ctx;
+ Ctx = cast_or_null<Decl>(Ctx->getDeclContext())) {
+ if (isa<TagDecl>(Ctx) || isa<FunctionDecl>(Ctx) || isa<ObjCMethodDecl>(Ctx))
+ return cast<NamedDecl>(Ctx);
+ if (auto *CD = dyn_cast<ObjCContainerDecl>(Ctx)) {
+ if (auto *Imp = dyn_cast<ObjCImplDecl>(Ctx))
+ return Imp->getClassInterface();
+ return CD;
+ }
+ }
+
+ return dyn_cast<NamedDecl>(OrigCtx);
+}
+
+/// Actually emit an availability diagnostic for a reference to an unavailable
+/// decl.
+///
+/// \param Ctx The context that the reference occurred in
+/// \param ReferringDecl The exact declaration that was referenced.
+/// \param OffendingDecl A related decl to \c ReferringDecl that has an
+/// availability attribute corrisponding to \c K attached to it. Note that this
+/// may not be the same as ReferringDecl, i.e. if an EnumDecl is annotated and
+/// we refer to a member EnumConstantDecl, ReferringDecl is the EnumConstantDecl
+/// and OffendingDecl is the EnumDecl.
static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
- Decl *Ctx, const NamedDecl *D,
+ Decl *Ctx, const NamedDecl *ReferringDecl,
+ const NamedDecl *OffendingDecl,
StringRef Message, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
const ObjCPropertyDecl *ObjCProperty,
@@ -6938,7 +6964,7 @@ static void DoEmitAvailabilityWarning(Se
// Diagnostics for deprecated or unavailable.
unsigned diag, diag_message, diag_fwdclass_message;
unsigned diag_available_here = diag::note_availability_specified_here;
- SourceLocation NoteLocation = D->getLocation();
+ SourceLocation NoteLocation = OffendingDecl->getLocation();
// Matches 'diag::note_property_attribute' options.
unsigned property_note_select;
@@ -6947,7 +6973,7 @@ static void DoEmitAvailabilityWarning(Se
unsigned available_here_select_kind;
VersionTuple DeclVersion;
- if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, D))
+ if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, OffendingDecl))
DeclVersion = AA->getIntroduced();
if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx))
@@ -6961,7 +6987,7 @@ static void DoEmitAvailabilityWarning(Se
diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
property_note_select = /* deprecated */ 0;
available_here_select_kind = /* deprecated */ 2;
- if (const auto *attr = D->getAttr<DeprecatedAttr>())
+ if (const auto *attr = OffendingDecl->getAttr<DeprecatedAttr>())
NoteLocation = attr->getLocation();
break;
@@ -6973,13 +6999,14 @@ static void DoEmitAvailabilityWarning(Se
property_note_select = /* unavailable */ 1;
available_here_select_kind = /* unavailable */ 0;
- if (auto attr = D->getAttr<UnavailableAttr>()) {
+ if (auto attr = OffendingDecl->getAttr<UnavailableAttr>()) {
if (attr->isImplicit() && attr->getImplicitReason()) {
// Most of these failures are due to extra restrictions in ARC;
// reflect that in the primary diagnostic when applicable.
auto flagARCError = [&] {
if (S.getLangOpts().ObjCAutoRefCount &&
- S.getSourceManager().isInSystemHeader(D->getLocation()))
+ S.getSourceManager().isInSystemHeader(
+ OffendingDecl->getLocation()))
diag = diag::err_unavailable_in_arc;
};
@@ -7022,7 +7049,8 @@ static void DoEmitAvailabilityWarning(Se
// not specified for deployment targets >= to iOS 11 or equivalent or
// for declarations that were introduced in iOS 11 (macOS 10.13, ...) or
// later.
- const AvailabilityAttr *AA = getAttrForPlatform(S.getASTContext(), D);
+ const AvailabilityAttr *AA =
+ getAttrForPlatform(S.getASTContext(), OffendingDecl);
VersionTuple Introduced = AA->getIntroduced();
bool NewWarning = shouldDiagnoseAvailabilityByDefault(
S.Context, S.Context.getTargetInfo().getPlatformMinVersion(),
@@ -7045,9 +7073,9 @@ static void DoEmitAvailabilityWarning(Se
CharSourceRange UseRange;
StringRef Replacement;
if (K == AR_Deprecated) {
- if (auto attr = D->getAttr<DeprecatedAttr>())
+ if (auto attr = OffendingDecl->getAttr<DeprecatedAttr>())
Replacement = attr->getReplacement();
- if (auto attr = getAttrForPlatform(S.Context, D))
+ if (auto attr = getAttrForPlatform(S.Context, OffendingDecl))
Replacement = attr->getReplacement();
if (!Replacement.empty())
@@ -7056,21 +7084,21 @@ static void DoEmitAvailabilityWarning(Se
}
if (!Message.empty()) {
- S.Diag(Loc, diag_message) << D << Message
+ S.Diag(Loc, diag_message) << ReferringDecl << Message
<< (UseRange.isValid() ?
FixItHint::CreateReplacement(UseRange, Replacement) : FixItHint());
if (ObjCProperty)
S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
<< ObjCProperty->getDeclName() << property_note_select;
} else if (!UnknownObjCClass) {
- S.Diag(Loc, diag) << D
+ S.Diag(Loc, diag) << ReferringDecl
<< (UseRange.isValid() ?
FixItHint::CreateReplacement(UseRange, Replacement) : FixItHint());
if (ObjCProperty)
S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
<< ObjCProperty->getDeclName() << property_note_select;
} else {
- S.Diag(Loc, diag_fwdclass_message) << D
+ S.Diag(Loc, diag_fwdclass_message) << ReferringDecl
<< (UseRange.isValid() ?
FixItHint::CreateReplacement(UseRange, Replacement) : FixItHint());
S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
@@ -7078,16 +7106,16 @@ static void DoEmitAvailabilityWarning(Se
// The declaration can have multiple availability attributes, we are looking
// at one of them.
- const AvailabilityAttr *A = getAttrForPlatform(S.Context, D);
+ const AvailabilityAttr *A = getAttrForPlatform(S.Context, OffendingDecl);
if (A && A->isInherited()) {
- for (const Decl *Redecl = D->getMostRecentDecl(); Redecl;
+ for (const Decl *Redecl = OffendingDecl->getMostRecentDecl(); Redecl;
Redecl = Redecl->getPreviousDecl()) {
const AvailabilityAttr *AForRedecl = getAttrForPlatform(S.Context,
Redecl);
if (AForRedecl && !AForRedecl->isInherited()) {
// If D is a declaration with inherited attributes, the note should
// point to the declaration with actual attributes.
- S.Diag(Redecl->getLocation(), diag_available_here) << D
+ S.Diag(Redecl->getLocation(), diag_available_here) << OffendingDecl
<< available_here_select_kind;
break;
}
@@ -7095,10 +7123,19 @@ static void DoEmitAvailabilityWarning(Se
}
else
S.Diag(NoteLocation, diag_available_here)
- << D << available_here_select_kind;
+ << OffendingDecl << available_here_select_kind;
if (K == AR_NotYetIntroduced)
- S.Diag(Loc, diag::note_partial_availability_silence) << D;
+ if (const auto *Enclosing = findEnclosingDeclToAnnotate(Ctx)) {
+ if (auto *TD = dyn_cast<TagDecl>(Enclosing))
+ if (TD->getDeclName().isEmpty()) {
+ S.Diag(TD->getLocation(), diag::note_partial_availability_silence)
+ << /*Anonymous*/1 << TD->getKindName();
+ return;
+ }
+ S.Diag(Enclosing->getLocation(), diag::note_partial_availability_silence)
+ << /*Named*/0 << Enclosing;
+ }
}
static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD,
@@ -7108,9 +7145,9 @@ static void handleDelayedAvailabilityChe
DD.Triggered = true;
DoEmitAvailabilityWarning(
- S, DD.getAvailabilityResult(), Ctx, DD.getAvailabilityDecl(),
- DD.getAvailabilityMessage(), DD.Loc, DD.getUnknownObjCClass(),
- DD.getObjCProperty(), false);
+ S, DD.getAvailabilityResult(), Ctx, DD.getAvailabilityReferringDecl(),
+ DD.getAvailabilityOffendingDecl(), DD.getAvailabilityMessage(), DD.Loc,
+ DD.getUnknownObjCClass(), DD.getObjCProperty(), false);
}
void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
@@ -7169,22 +7206,25 @@ void Sema::redelayDiagnostics(DelayedDia
}
void Sema::EmitAvailabilityWarning(AvailabilityResult AR,
- NamedDecl *D, StringRef Message,
- SourceLocation Loc,
+ const NamedDecl *ReferringDecl,
+ const NamedDecl *OffendingDecl,
+ StringRef Message, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
+ const ObjCPropertyDecl *ObjCProperty,
bool ObjCPropertyAccess) {
// Delay if we're currently parsing a declaration.
if (DelayedDiagnostics.shouldDelayDiagnostics()) {
- DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(
- AR, Loc, D, UnknownObjCClass, ObjCProperty, Message,
- ObjCPropertyAccess));
+ DelayedDiagnostics.add(
+ DelayedDiagnostic::makeAvailability(
+ AR, Loc, ReferringDecl, OffendingDecl, UnknownObjCClass,
+ ObjCProperty, Message, ObjCPropertyAccess));
return;
}
Decl *Ctx = cast<Decl>(getCurLexicalContext());
- DoEmitAvailabilityWarning(*this, AR, Ctx, D, Message, Loc, UnknownObjCClass,
- ObjCProperty, ObjCPropertyAccess);
+ DoEmitAvailabilityWarning(*this, AR, Ctx, ReferringDecl, OffendingDecl,
+ Message, Loc, UnknownObjCClass, ObjCProperty,
+ ObjCPropertyAccess);
}
namespace {
@@ -7336,19 +7376,21 @@ public:
void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
NamedDecl *D, SourceRange Range) {
-
- VersionTuple ContextVersion = AvailabilityStack.back();
- if (AvailabilityResult Result =
- SemaRef.ShouldDiagnoseAvailabilityOfDecl(D, nullptr)) {
+ AvailabilityResult Result;
+ const NamedDecl *OffendingDecl;
+ std::tie(Result, OffendingDecl) =
+ SemaRef.ShouldDiagnoseAvailabilityOfDecl(D, nullptr);
+ if (Result != AR_Available) {
// All other diagnostic kinds have already been handled in
// DiagnoseAvailabilityOfDecl.
if (Result != AR_NotYetIntroduced)
return;
- const AvailabilityAttr *AA = getAttrForPlatform(SemaRef.getASTContext(), D);
+ const AvailabilityAttr *AA =
+ getAttrForPlatform(SemaRef.getASTContext(), OffendingDecl);
VersionTuple Introduced = AA->getIntroduced();
- if (ContextVersion >= Introduced)
+ if (AvailabilityStack.back() >= Introduced)
return;
// If the context of this function is less available than D, we should not
@@ -7373,8 +7415,9 @@ void DiagnoseUnguardedAvailability::Diag
SemaRef.getASTContext().getTargetInfo().getPlatformName())
<< Introduced.getAsString();
- SemaRef.Diag(D->getLocation(), diag::note_availability_specified_here)
- << D << /* partial */ 3;
+ SemaRef.Diag(OffendingDecl->getLocation(),
+ diag::note_availability_specified_here)
+ << OffendingDecl << /* partial */ 3;
auto FixitDiag =
SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence)
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Jul 5 10:08:56 2017
@@ -87,24 +87,9 @@ static void DiagnoseUnusedOfDecl(Sema &S
}
}
-static bool HasRedeclarationWithoutAvailabilityInCategory(const Decl *D) {
- const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
- if (!OMD)
- return false;
- const ObjCInterfaceDecl *OID = OMD->getClassInterface();
- if (!OID)
- return false;
-
- for (const ObjCCategoryDecl *Cat : OID->visible_categories())
- if (ObjCMethodDecl *CatMeth =
- Cat->getMethod(OMD->getSelector(), OMD->isInstanceMethod()))
- if (!CatMeth->hasAttr<AvailabilityAttr>())
- return true;
- return false;
-}
-
-AvailabilityResult
-Sema::ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D, std::string *Message) {
+std::pair<AvailabilityResult, const NamedDecl *>
+Sema::ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D,
+ std::string *Message) {
AvailabilityResult Result = D->getAvailability(Message);
// For typedefs, if the typedef declaration appears available look
@@ -121,45 +106,23 @@ Sema::ShouldDiagnoseAvailabilityOfDecl(N
}
// Forward class declarations get their attributes from their definition.
- if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
+ if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
if (IDecl->getDefinition()) {
D = IDecl->getDefinition();
Result = D->getAvailability(Message);
}
}
- if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
+ if (const auto *ECD = dyn_cast<EnumConstantDecl>(D))
if (Result == AR_Available) {
const DeclContext *DC = ECD->getDeclContext();
- if (const EnumDecl *TheEnumDecl = dyn_cast<EnumDecl>(DC))
+ if (const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) {
Result = TheEnumDecl->getAvailability(Message);
+ D = TheEnumDecl;
+ }
}
- 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;
-
- bool Warn = !D->getAttr<AvailabilityAttr>()->isInherited();
- // Objective-C method declarations in categories are not modelled as
- // redeclarations, so manually look for a redeclaration in a category
- // if necessary.
- if (Warn && HasRedeclarationWithoutAvailabilityInCategory(D))
- Warn = false;
- // In general, D will point to the most recent redeclaration. However,
- // for `@class A;` decls, this isn't true -- manually go through the
- // redecl chain in that case.
- if (Warn && isa<ObjCInterfaceDecl>(D))
- for (Decl *Redecl = D->getMostRecentDecl(); Redecl && Warn;
- Redecl = Redecl->getPreviousDecl())
- if (!Redecl->hasAttr<AvailabilityAttr>() ||
- Redecl->getAttr<AvailabilityAttr>()->isInherited())
- Warn = false;
-
- return Warn ? AR_NotYetIntroduced : AR_Available;
- }
-
- return Result;
+ return {Result, D};
}
static void
@@ -167,32 +130,34 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name
const ObjCInterfaceDecl *UnknownObjCClass,
bool ObjCPropertyAccess) {
std::string Message;
+ AvailabilityResult Result;
+ const NamedDecl* OffendingDecl;
// See if this declaration is unavailable, deprecated, or partial.
- if (AvailabilityResult Result =
- S.ShouldDiagnoseAvailabilityOfDecl(D, &Message)) {
+ std::tie(Result, OffendingDecl) = S.ShouldDiagnoseAvailabilityOfDecl(D, &Message);
+ if (Result == AR_Available)
+ return;
- if (Result == AR_NotYetIntroduced) {
- if (S.getCurFunctionOrMethodDecl()) {
- S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
- return;
- } else if (S.getCurBlock() || S.getCurLambda()) {
- S.getCurFunction()->HasPotentialAvailabilityViolations = true;
- return;
- }
+ if (Result == AR_NotYetIntroduced) {
+ if (S.getCurFunctionOrMethodDecl()) {
+ S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
+ return;
+ } else if (S.getCurBlock() || S.getCurLambda()) {
+ S.getCurFunction()->HasPotentialAvailabilityViolations = true;
+ return;
}
+ }
- const ObjCPropertyDecl *ObjCPDecl = nullptr;
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {
- AvailabilityResult PDeclResult = PD->getAvailability(nullptr);
- if (PDeclResult == Result)
- ObjCPDecl = PD;
- }
+ const ObjCPropertyDecl *ObjCPDecl = nullptr;
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+ if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {
+ AvailabilityResult PDeclResult = PD->getAvailability(nullptr);
+ if (PDeclResult == Result)
+ ObjCPDecl = PD;
}
-
- S.EmitAvailabilityWarning(Result, D, Message, Loc, UnknownObjCClass,
- ObjCPDecl, ObjCPropertyAccess);
}
+
+ S.EmitAvailabilityWarning(Result, D, OffendingDecl, Message, Loc,
+ UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess);
}
/// \brief Emit a note explaining that this function is deleted.
Modified: cfe/trunk/test/Sema/attr-availability.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-availability.c?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-availability.c (original)
+++ cfe/trunk/test/Sema/attr-availability.c Wed Jul 5 10:08:56 2017
@@ -21,6 +21,9 @@ ATSFontGetPostScriptName(int flags) __at
extern void
PartiallyAvailable() __attribute__((availability(macosx,introduced=10.8)));
+#ifdef WARN_PARTIAL
+// expected-note at +2 2 {{marked partial here}}
+#endif
enum __attribute__((availability(macosx,introduced=10.8))) PartialEnum {
kPartialEnumConstant,
};
@@ -35,11 +38,19 @@ void test_10095131() {
PartiallyAvailable();
}
+#ifdef WARN_PARTIAL
+// FIXME: This note should point to the declaration with the availability
+// attribute.
+// expected-note at +2 {{marked partial here}}
+#endif
extern void PartiallyAvailable() ;
void with_redeclaration() {
- PartiallyAvailable(); // Don't warn.
-
- // enums should never warn.
+#ifdef WARN_PARTIAL
+ // expected-warning at +4 {{'PartiallyAvailable' is only available on macOS 10.8 or newer}} expected-note at +4 {{__builtin_available}}
+ // expected-warning at +4 {{'PartialEnum' is only available on macOS 10.8 or newer}} expected-note at +4 {{__builtin_available}}
+ // expected-warning at +3 {{'kPartialEnumConstant' is only available on macOS 10.8 or newer}} expected-note at +3 {{__builtin_available}}
+#endif
+ PartiallyAvailable();
enum PartialEnum p = kPartialEnumConstant;
}
@@ -86,13 +97,13 @@ enum Original {
OriginalUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'OriginalUnavailable' has been explicitly marked unavailable here}}
};
-enum AllDeprecated {
- AllDeprecatedCase, // expected-note + {{'AllDeprecatedCase' has been explicitly marked deprecated here}}
+enum AllDeprecated { // expected-note + {{'AllDeprecated' has been explicitly marked deprecated here}}
+ AllDeprecatedCase,
AllDeprecatedUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'AllDeprecatedUnavailable' has been explicitly marked unavailable here}}
} __attribute__((availability(macosx, deprecated=10.2)));
-enum AllUnavailable {
- AllUnavailableCase, // expected-note + {{'AllUnavailableCase' has been explicitly marked unavailable here}}
+enum AllUnavailable { // expected-note + {{'AllUnavailable' has been explicitly marked unavailable here}}
+ AllUnavailableCase,
} __attribute__((availability(macosx, unavailable)));
enum User {
Modified: cfe/trunk/test/Sema/attr-deprecated.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-deprecated.c?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-deprecated.c (original)
+++ cfe/trunk/test/Sema/attr-deprecated.c Wed Jul 5 10:08:56 2017
@@ -104,9 +104,9 @@ foo_dep test17, // expected-warning {{'f
test19;
// rdar://problem/8518751
-enum __attribute__((deprecated)) Test20 { // expected-note {{'Test20' has been explicitly marked deprecated here}}
+enum __attribute__((deprecated)) Test20 { // expected-note 2 {{'Test20' has been explicitly marked deprecated here}}
test20_a __attribute__((deprecated)), // expected-note {{'test20_a' has been explicitly marked deprecated here}}
- test20_b // expected-note {{'test20_b' has been explicitly marked deprecated here}}
+ test20_b
};
void test20() {
enum Test20 f; // expected-warning {{'Test20' is deprecated}}
Modified: cfe/trunk/test/Sema/attr-unavailable-message.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-unavailable-message.c?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-unavailable-message.c (original)
+++ cfe/trunk/test/Sema/attr-unavailable-message.c Wed Jul 5 10:08:56 2017
@@ -36,13 +36,13 @@ void unavail(void) {
// rdar://10201690
enum foo {
- a = 1, // expected-note {{'a' has been explicitly marked deprecated here}}
+ a = 1,
b __attribute__((deprecated())) = 2, // expected-note {{'b' has been explicitly marked deprecated here}}
c = 3
-}__attribute__((deprecated()));
+}__attribute__((deprecated())); // expected-note {{'foo' has been explicitly marked deprecated here}}
-enum fee { // expected-note {{'fee' has been explicitly marked unavailable here}}
- r = 1, // expected-note {{'r' has been explicitly marked unavailable here}}
+enum fee { // expected-note 2 {{'fee' has been explicitly marked unavailable here}}
+ r = 1,
s = 2,
t = 3
}__attribute__((unavailable()));
Modified: cfe/trunk/test/SemaCXX/attr-deprecated.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-deprecated.cpp?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-deprecated.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-deprecated.cpp Wed Jul 5 10:08:56 2017
@@ -199,8 +199,8 @@ namespace test5 {
// rdar://problem/8518751
namespace test6 {
- enum __attribute__((deprecated)) A { // expected-note {{'A' has been explicitly marked deprecated here}}
- a0 // expected-note {{'a0' has been explicitly marked deprecated here}}
+ enum __attribute__((deprecated)) A { // expected-note 2 {{'A' has been explicitly marked deprecated here}}
+ a0
};
void testA() {
A x; // expected-warning {{'A' is deprecated}}
@@ -218,8 +218,8 @@ namespace test6 {
}
template <class T> struct C {
- enum __attribute__((deprecated)) Enum { // expected-note {{'Enum' has been explicitly marked deprecated here}}
- c0 // expected-note {{'c0' has been explicitly marked deprecated here}}
+ enum __attribute__((deprecated)) Enum { // expected-note 2 {{'Enum' has been explicitly marked deprecated here}}
+ c0
};
};
void testC() {
Modified: cfe/trunk/test/SemaObjC/attr-availability.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-availability.m?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-availability.m (original)
+++ cfe/trunk/test/SemaObjC/attr-availability.m Wed Jul 5 10:08:56 2017
@@ -13,7 +13,7 @@
@interface A <P>
- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}}
#if defined(WARN_PARTIAL)
- // expected-note at +2 {{'partialMethod' has been explicitly marked partial here}}
+ // expected-note at +2 2 {{'partialMethod' has been explicitly marked partial here}}
#endif
- (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
@@ -66,7 +66,10 @@ void f(A *a, B *b) {
@end
void f_after_redecl(A *a, B *b) {
- [a partialMethod]; // no warning
+#ifdef WARN_PARTIAL
+ // expected-warning at +2{{'partialMethod' is only available on macOS 10.8 or newer}} expected-note at +2 {{@available}}
+#endif
+ [a partialMethod];
[b partialMethod]; // no warning
[a partial_proto_method]; // no warning
[b partial_proto_method]; // no warning
@@ -133,6 +136,10 @@ id NSNibOwner, topNibObjects;
@end
@interface PartialI <PartialProt>
+#ifdef WARN_PARTIAL
+// expected-note at +3{{marked partial here}}
+// expected-note at +3{{marked partial here}}
+#endif
- (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
+ (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
@end
@@ -160,14 +167,20 @@ id NSNibOwner, topNibObjects;
@end
void partialfun(PartialI* a) {
- [a partialMethod]; // no warning
+#ifdef WARN_PARTIAL
+ // expected-warning at +2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note at +2{{@available}}
+#endif
+ [a partialMethod];
[a ipartialMethod1]; // no warning
#if defined(WARN_PARTIAL)
// expected-warning at +2 {{'ipartialMethod2' is only available on macOS 10.8 or newer}} expected-note at +2 {{enclose 'ipartialMethod2' in an @available check to silence this warning}}
#endif
[a ipartialMethod2];
[a ppartialMethod]; // no warning
- [PartialI partialMethod]; // no warning
+#ifdef WARN_PARTIAL
+ // expected-warning at +2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note at +2 {{@available}}
+#endif
+ [PartialI partialMethod];
[PartialI ipartialMethod1]; // no warning
#if defined(WARN_PARTIAL)
// expected-warning at +2 {{'ipartialMethod2' is only available on macOS 10.8 or newer}} expected-note at +2 {{enclose 'ipartialMethod2' in an @available check to silence this warning}}
@@ -177,20 +190,23 @@ void partialfun(PartialI* a) {
}
#if defined(WARN_PARTIAL)
- // expected-note at +2 {{'PartialI2' has been explicitly marked partial here}}
+ // expected-note at +2 2 {{'PartialI2' has been explicitly marked partial here}}
#endif
__attribute__((availability(macosx, introduced = 10.8))) @interface PartialI2
@end
#if defined(WARN_PARTIAL)
- // expected-warning at +2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note at +2 {{explicitly redeclare 'PartialI2' to silence this warning}}
+// expected-warning at +2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note at +2 {{annotate 'partialinter1' with an availability attribute to silence}}
#endif
void partialinter1(PartialI2* p) {
}
@class PartialI2;
-void partialinter2(PartialI2* p) { // no warning
+#ifdef WARN_PARTIAL
+// expected-warning at +2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note at +2 {{annotate 'partialinter2' with an availability attribute to silence}}
+#endif
+void partialinter2(PartialI2* p) {
}
Modified: cfe/trunk/test/SemaObjC/unguarded-availability-new.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/unguarded-availability-new.m?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/unguarded-availability-new.m (original)
+++ cfe/trunk/test/SemaObjC/unguarded-availability-new.m Wed Jul 5 10:08:56 2017
@@ -96,16 +96,16 @@ typedef int AVAILABLE_NEXT new_int;
FUNC_AVAILABLE new_int x;
#ifndef NO_WARNING
#ifdef MAC
- // expected-warning at -3 {{'new_int' is partial: introduced in macOS 10.14}} expected-note at -3 {{explicitly redeclare 'new_int' to silence this warning}}
+ // expected-warning at -3 {{'new_int' is partial: introduced in macOS 10.14}} expected-note at -3 {{annotate 'x' with an availability attribute to silence}}
#endif
#ifdef IOS
- // expected-warning at -6 {{'new_int' is partial: introduced in iOS 12}} expected-note at -6 {{explicitly redeclare 'new_int' to silence this warning}}
+ // expected-warning at -6 {{'new_int' is partial: introduced in iOS 12}} expected-note at -6 {{annotate 'x' with an availability attribute to silence}}
#endif
#ifdef TVOS
- // expected-warning at -9 {{'new_int' is partial: introduced in tvOS 13}} expected-note at -9 {{explicitly redeclare 'new_int' to silence this warning}}
+ // expected-warning at -9 {{'new_int' is partial: introduced in tvOS 13}} expected-note at -9 {{annotate 'x' with an availability attribute to silence}}
#endif
#ifdef WATCHOS
- // expected-warning at -12 {{'new_int' is partial: introduced in watchOS 5}} expected-note at -12 {{explicitly redeclare 'new_int' to silence this warning}}
+ // expected-warning at -12 {{'new_int' is partial: introduced in watchOS 5}} expected-note at -12 {{annotate 'x' with an availability attribute to silence}}
#endif
#endif
Modified: cfe/trunk/test/SemaObjC/unguarded-availability.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/unguarded-availability.m?rev=307175&r1=307174&r2=307175&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/unguarded-availability.m (original)
+++ cfe/trunk/test/SemaObjC/unguarded-availability.m Wed Jul 5 10:08:56 2017
@@ -5,6 +5,8 @@
#define AVAILABLE_10_11 __attribute__((availability(macos, introduced = 10.11)))
#define AVAILABLE_10_12 __attribute__((availability(macos, introduced = 10.12)))
+typedef int AVAILABLE_10_12 new_int; // expected-note + {{marked partial here}}
+
int func_10_11() AVAILABLE_10_11; // expected-note 4 {{'func_10_11' has been explicitly marked partial here}}
#ifdef OBJCPP
@@ -70,9 +72,9 @@ void use_typedef() {
}
__attribute__((objc_root_class))
-AVAILABLE_10_11 @interface Class_10_11 {
+AVAILABLE_10_11 @interface Class_10_11 { // expected-note{{annotate 'Class_10_11' with an availability attribute to silence}}
int_10_11 foo;
- int_10_12 bar; // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{redeclare}}
+ int_10_12 bar; // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}}
}
- (void)method1;
- (void)method2;
@@ -125,7 +127,7 @@ void test_blocks() {
};
}
-void test_params(int_10_12 x); // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{redeclare}}
+void test_params(int_10_12 x); // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{annotate 'test_params' with an availability attribute to silence}}
void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn
@@ -234,3 +236,30 @@ void functionInFunction() {
}
#endif
+
+struct InStruct { // expected-note{{annotate 'InStruct' with an availability attribute to silence}}
+ new_int mem; // expected-warning{{'new_int' is partial}}
+
+ struct { new_int mem; } anon; // expected-warning{{'new_int' is partial}} expected-note{{annotate anonymous struct with an availability attribute}}
+};
+
+#ifdef OBJCPP
+static constexpr int AVAILABLE_10_12 SomeConstexprValue = 2; // expected-note{{marked partial here}}
+typedef enum { // expected-note{{annotate anonymous enum with an availability attribute}}
+ SomeValue = SomeConstexprValue // expected-warning{{'SomeConstexprValue' is partial}}
+} SomeEnum;
+#endif
+
+ at interface InInterface
+-(new_int)meth; // expected-warning{{'new_int' is partial}} expected-note{{annotate 'meth' with an availability attribute}}
+ at end
+
+ at interface Proper // expected-note{{annotate 'Proper' with an availability attribute}}
+ at property (class) new_int x; // expected-warning{{'new_int' is partial}}
+ at end
+
+void with_local_struct() {
+ struct local { // expected-note{{annotate 'local' with an availability attribute}}
+ new_int x; // expected-warning{{'new_int' is partial}}
+ };
+}
More information about the cfe-commits
mailing list