r310874 - [Sema] Improve some -Wunguarded-availability diagnostics
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 14 12:49:12 PDT 2017
Author: epilk
Date: Mon Aug 14 12:49:12 2017
New Revision: 310874
URL: http://llvm.org/viewvc/llvm-project?rev=310874&view=rev
Log:
[Sema] Improve some -Wunguarded-availability diagnostics
rdar://33543523
Differential revision: https://reviews.llvm.org/D36200
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDeclAttr.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=310874&r1=310873&r2=310874&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Aug 14 12:49:12 2017
@@ -2896,25 +2896,11 @@ def warn_unguarded_availability :
def warn_unguarded_availability_new :
Warning<warn_unguarded_availability.Text>,
InGroup<UnguardedAvailabilityNew>;
-def warn_partial_availability : Warning<"%0 is only available conditionally">,
- InGroup<UnguardedAvailability>, DefaultIgnore;
-def warn_partial_availability_new : Warning<warn_partial_availability.Text>,
- InGroup<UnguardedAvailabilityNew>;
-def note_partial_availability_silence : Note<
- "annotate %select{%1|anonymous %1}0 with an availability attribute to silence">;
+def note_decl_unguarded_availability_silence : Note<
+ "annotate %select{%1|anonymous %1}0 with an availability attribute to silence this warning">;
def note_unguarded_available_silence : Note<
"enclose %0 in %select{an @available|a __builtin_available}1 check to silence"
" this warning">;
-def warn_partial_message : Warning<"%0 is partial: %1">,
- InGroup<UnguardedAvailability>, DefaultIgnore;
-def warn_partial_message_new : Warning<warn_partial_message.Text>,
- InGroup<UnguardedAvailabilityNew>;
-def warn_partial_fwdclass_message : Warning<
- "%0 may be partial because the receiver type is unknown">,
- InGroup<UnguardedAvailability>, DefaultIgnore;
-def warn_partial_fwdclass_message_new :
- Warning<warn_partial_fwdclass_message.Text>,
- InGroup<UnguardedAvailabilityNew>;
def warn_at_available_unchecked_use : Warning<
"%select{@available|__builtin_available}0 does not guard availability here; "
"use if (%select{@available|__builtin_available}0) instead">,
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=310874&r1=310873&r2=310874&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Aug 14 12:49:12 2017
@@ -7128,7 +7128,83 @@ static void DoEmitAvailabilityWarning(Se
if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx))
return;
+ // The declaration can have multiple availability attributes, we are looking
+ // at one of them.
+ const AvailabilityAttr *A = getAttrForPlatform(S.Context, OffendingDecl);
+ if (A && A->isInherited()) {
+ 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.
+ NoteLocation = Redecl->getLocation();
+ break;
+ }
+ }
+ }
+
switch (K) {
+ case AR_NotYetIntroduced: {
+ // We would like to emit the diagnostic even if -Wunguarded-availability is
+ // 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(), OffendingDecl);
+ VersionTuple Introduced = AA->getIntroduced();
+
+ bool UseNewWarning = shouldDiagnoseAvailabilityByDefault(
+ S.Context, S.Context.getTargetInfo().getPlatformMinVersion(),
+ Introduced);
+ unsigned Warning = UseNewWarning ? diag::warn_unguarded_availability_new
+ : diag::warn_unguarded_availability;
+
+ S.Diag(Loc, Warning)
+ << OffendingDecl
+ << AvailabilityAttr::getPrettyPlatformName(
+ S.getASTContext().getTargetInfo().getPlatformName())
+ << Introduced.getAsString();
+
+ S.Diag(OffendingDecl->getLocation(), diag::note_availability_specified_here)
+ << OffendingDecl << /* partial */ 3;
+
+ if (const auto *Enclosing = findEnclosingDeclToAnnotate(Ctx)) {
+ if (auto *TD = dyn_cast<TagDecl>(Enclosing))
+ if (TD->getDeclName().isEmpty()) {
+ S.Diag(TD->getLocation(),
+ diag::note_decl_unguarded_availability_silence)
+ << /*Anonymous*/ 1 << TD->getKindName();
+ return;
+ }
+ auto FixitNoteDiag =
+ S.Diag(Enclosing->getLocation(),
+ diag::note_decl_unguarded_availability_silence)
+ << /*Named*/ 0 << Enclosing;
+ // Don't offer a fixit for declarations with availability attributes.
+ if (Enclosing->hasAttr<AvailabilityAttr>())
+ return;
+ if (!S.getPreprocessor().isMacroDefined("API_AVAILABLE"))
+ return;
+ Optional<AttributeInsertion> Insertion = createAttributeInsertion(
+ Enclosing, S.getSourceManager(), S.getLangOpts());
+ if (!Insertion)
+ return;
+ std::string PlatformName =
+ AvailabilityAttr::getPlatformNameSourceSpelling(
+ S.getASTContext().getTargetInfo().getPlatformName())
+ .lower();
+ std::string Introduced =
+ OffendingDecl->getVersionIntroduced().getAsString();
+ FixitNoteDiag << FixItHint::CreateInsertion(
+ Insertion->Loc,
+ (llvm::Twine(Insertion->Prefix) + "API_AVAILABLE(" + PlatformName +
+ "(" + Introduced + "))" + Insertion->Suffix)
+ .str());
+ }
+ return;
+ }
case AR_Deprecated:
diag = !ObjCPropertyAccess ? diag::warn_deprecated
: diag::warn_property_method_deprecated;
@@ -7193,28 +7269,6 @@ static void DoEmitAvailabilityWarning(Se
}
break;
- case AR_NotYetIntroduced: {
- // We would like to emit the diagnostic even if -Wunguarded-availability is
- // 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(), OffendingDecl);
- VersionTuple Introduced = AA->getIntroduced();
- bool NewWarning = shouldDiagnoseAvailabilityByDefault(
- S.Context, S.Context.getTargetInfo().getPlatformMinVersion(),
- Introduced);
- diag = NewWarning ? diag::warn_partial_availability_new
- : diag::warn_partial_availability;
- diag_message = NewWarning ? diag::warn_partial_message_new
- : diag::warn_partial_message;
- diag_fwdclass_message = NewWarning ? diag::warn_partial_fwdclass_message_new
- : diag::warn_partial_fwdclass_message;
- property_note_select = /* partial */ 2;
- available_here_select_kind = /* partial */ 3;
- break;
- }
-
case AR_Available:
llvm_unreachable("Warning for availability of available declaration?");
}
@@ -7253,59 +7307,8 @@ static void DoEmitAvailabilityWarning(Se
S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
}
- // The declaration can have multiple availability attributes, we are looking
- // at one of them.
- const AvailabilityAttr *A = getAttrForPlatform(S.Context, OffendingDecl);
- if (A && A->isInherited()) {
- 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) << OffendingDecl
- << available_here_select_kind;
- break;
- }
- }
- }
- else
- S.Diag(NoteLocation, diag_available_here)
- << OffendingDecl << available_here_select_kind;
-
- if (K == AR_NotYetIntroduced)
- 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;
- }
- auto FixitNoteDiag = S.Diag(Enclosing->getLocation(),
- diag::note_partial_availability_silence)
- << /*Named*/ 0 << Enclosing;
- // Don't offer a fixit for declarations with availability attributes.
- if (Enclosing->hasAttr<AvailabilityAttr>())
- return;
- if (!S.getPreprocessor().isMacroDefined("API_AVAILABLE"))
- return;
- Optional<AttributeInsertion> Insertion = createAttributeInsertion(
- Enclosing, S.getSourceManager(), S.getLangOpts());
- if (!Insertion)
- return;
- std::string PlatformName =
- AvailabilityAttr::getPlatformNameSourceSpelling(
- S.getASTContext().getTargetInfo().getPlatformName())
- .lower();
- std::string Introduced =
- OffendingDecl->getVersionIntroduced().getAsString();
- FixitNoteDiag << FixItHint::CreateInsertion(
- Insertion->Loc,
- (llvm::Twine(Insertion->Prefix) + "API_AVAILABLE(" + PlatformName +
- "(" + Introduced + "))" + Insertion->Suffix)
- .str());
- }
+ S.Diag(NoteLocation, diag_available_here)
+ << OffendingDecl << available_here_select_kind;
}
static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD,
Modified: cfe/trunk/test/SemaObjC/attr-availability.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-availability.m?rev=310874&r1=310873&r2=310874&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-availability.m (original)
+++ cfe/trunk/test/SemaObjC/attr-availability.m Mon Aug 14 12:49:12 2017
@@ -196,7 +196,7 @@ __attribute__((availability(macosx, intr
@end
#if defined(WARN_PARTIAL)
-// expected-warning at +2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note at +2 {{annotate 'partialinter1' with an availability attribute to silence}}
+// expected-warning at +2 {{'PartialI2' is only available on macOS 10.8 or newer}} expected-note at +2 {{annotate 'partialinter1' with an availability attribute to silence}}
#endif
void partialinter1(PartialI2* p) {
}
@@ -204,7 +204,7 @@ void partialinter1(PartialI2* p) {
@class PartialI2;
#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}}
+// expected-warning at +2 {{'PartialI2' is only available on macOS 10.8 or newer}} 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=310874&r1=310873&r2=310874&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/unguarded-availability-new.m (original)
+++ cfe/trunk/test/SemaObjC/unguarded-availability-new.m Mon Aug 14 12:49:12 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 {{annotate 'x' with an availability attribute to silence}}
+ // expected-warning at -3 {{'new_int' is only available on macOS 10.14 or newer}} expected-note at -3 {{annotate 'x' with an availability attribute to silence this warning}}
#endif
#ifdef IOS
- // expected-warning at -6 {{'new_int' is partial: introduced in iOS 12}} expected-note at -6 {{annotate 'x' with an availability attribute to silence}}
+ // expected-warning at -6 {{'new_int' is only available on iOS 12 or newer}} expected-note at -6 {{annotate 'x' with an availability attribute to silence this warning}}
#endif
#ifdef TVOS
- // expected-warning at -9 {{'new_int' is partial: introduced in tvOS 13}} expected-note at -9 {{annotate 'x' with an availability attribute to silence}}
+ // expected-warning at -9 {{'new_int' is only available on tvOS 13 or newer}} expected-note at -9 {{annotate 'x' with an availability attribute to silence this warning}}
#endif
#ifdef WATCHOS
- // expected-warning at -12 {{'new_int' is partial: introduced in watchOS 5}} expected-note at -12 {{annotate 'x' with an availability attribute to silence}}
+ // expected-warning at -12 {{'new_int' is only available on watchOS 5}} expected-note at -12 {{annotate 'x' with an availability attribute to silence this warning}}
#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=310874&r1=310873&r2=310874&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/unguarded-availability.m (original)
+++ cfe/trunk/test/SemaObjC/unguarded-availability.m Mon Aug 14 12:49:12 2017
@@ -74,7 +74,7 @@ void use_typedef() {
__attribute__((objc_root_class))
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}}
+ int_10_12 bar; // expected-warning {{'int_10_12' is only available on macOS 10.12 or newer}}
}
- (void)method1;
- (void)method2;
@@ -127,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{{annotate 'test_params' with an availability attribute to silence}}
+void test_params(int_10_12 x); // expected-warning {{'int_10_12' is only available on macOS 10.12 or newer}} expected-note{{annotate 'test_params' with an availability attribute to silence this warning}}
void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn
@@ -238,29 +238,29 @@ void functionInFunction() {
#endif
struct InStruct { // expected-note{{annotate 'InStruct' with an availability attribute to silence}}
- new_int mem; // expected-warning{{'new_int' is partial}}
+ new_int mem; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}}
- struct { new_int mem; } anon; // expected-warning{{'new_int' is partial}} expected-note{{annotate anonymous struct with an availability attribute}}
+ struct { new_int mem; } anon; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}} expected-note{{annotate anonymous struct with an availability attribute to silence}}
};
#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}}
+ SomeValue = SomeConstexprValue // expected-warning{{'SomeConstexprValue' is only available on macOS 10.12 or newer}}
} SomeEnum;
#endif
@interface InInterface
--(new_int)meth; // expected-warning{{'new_int' is partial}} expected-note{{annotate 'meth' with an availability attribute}}
+-(new_int)meth; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}} expected-note{{annotate 'meth' with an availability attribute}}
@end
@interface Proper // expected-note{{annotate 'Proper' with an availability attribute}}
- at property (class) new_int x; // expected-warning{{'new_int' is partial}}
+ at property (class) new_int x; // expected-warning{{'new_int' is only available}}
@end
void with_local_struct() {
struct local { // expected-note{{annotate 'local' with an availability attribute}}
- new_int x; // expected-warning{{'new_int' is partial}}
+ new_int x; // expected-warning{{'new_int' is only available}}
};
}
@@ -273,7 +273,7 @@ AVAILABLE_10_12
@protocol ProtocolWithNewProtocolRequirement <NewProtocol> // expected-note {{annotate 'ProtocolWithNewProtocolRequirement' with an availability attribute to silence}}
- at property(copy) id<NewProtocol> prop; // expected-warning {{'NewProtocol' is partial: introduced in macOS 10.12}}
+ at property(copy) id<NewProtocol> prop; // expected-warning {{'NewProtocol' is only available on macOS 10.12 or newer}}
@end
More information about the cfe-commits
mailing list