forked from OSchip/llvm-project
[clang] Introduce support for disabling warnings in system macros
Often we run into situations where we want to ignore warnings from system headers, but Clang will still give warnings about the contents of a macro defined in a system header used in user-code. Introduce a ShowInSystemMacro option to be able to specify which warnings we do want to keep raising warnings for. The current behavior is kept in this patch (i.e. warnings from system macros are enabled by default). The decision as to whether this should be an opt-in or opt-out feature can be made in a separate patch. To put the feature to test, replace duplicated code for Wshadow and Wold-style-cast with the SuppressInSystemMacro tag. Also disable the warning for C++20 designators, fixing #52944. Differential Revision: https://reviews.llvm.org/D116833
This commit is contained in:
parent
22225cc5e6
commit
c4db521cea
|
@ -45,7 +45,7 @@ namespace {
|
|||
const char *getDiagnosticCode(unsigned ID) {
|
||||
switch (ID) {
|
||||
#define DIAG(ENUM, CLASS, DEFAULT_MAPPING, DESC, GROPU, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
case clang::diag::ENUM: \
|
||||
return #ENUM;
|
||||
#include "clang/Basic/DiagnosticASTKinds.inc"
|
||||
|
|
|
@ -84,6 +84,7 @@ class Diagnostic<string text, DiagClass DC, Severity defaultmapping> {
|
|||
bit AccessControl = 0;
|
||||
bit WarningNoWerror = 0;
|
||||
bit ShowInSystemHeader = 0;
|
||||
bit ShowInSystemMacro = 1;
|
||||
bit Deferrable = 0;
|
||||
Severity DefaultSeverity = defaultmapping;
|
||||
DiagGroup Group;
|
||||
|
@ -108,6 +109,14 @@ class SuppressInSystemHeader {
|
|||
bit ShowInSystemHeader = 0;
|
||||
}
|
||||
|
||||
class ShowInSystemMacro {
|
||||
bit ShowInSystemMacro = 1;
|
||||
}
|
||||
|
||||
class SuppressInSystemMacro {
|
||||
bit ShowInSystemMacro = 0;
|
||||
}
|
||||
|
||||
class Deferrable {
|
||||
bit Deferrable = 1;
|
||||
}
|
||||
|
@ -159,4 +168,3 @@ include "DiagnosticParseKinds.td"
|
|||
include "DiagnosticRefactoringKinds.td"
|
||||
include "DiagnosticSemaKinds.td"
|
||||
include "DiagnosticSerializationKinds.td"
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define ASTSTART
|
||||
#include "clang/Basic/DiagnosticASTKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define ANALYSISSTART
|
||||
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define COMMENTSTART
|
||||
#include "clang/Basic/DiagnosticCommentKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define CROSSTUSTART
|
||||
#include "clang/Basic/DiagnosticCrossTUKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define DRIVERSTART
|
||||
#include "clang/Basic/DiagnosticDriverKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define FRONTENDSTART
|
||||
#include "clang/Basic/DiagnosticFrontendKinds.inc"
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace clang {
|
|||
// Get typedefs for common diagnostics.
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, CATEGORY, \
|
||||
NOWERROR, SHOWINSYSHEADER, DEFFERABLE) \
|
||||
NOWERROR, SHOWINSYSHEADER, SHOWINSYSMACRO, DEFFERABLE) \
|
||||
ENUM,
|
||||
#define COMMONSTART
|
||||
#include "clang/Basic/DiagnosticCommonKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define LEXSTART
|
||||
#include "clang/Basic/DiagnosticLexKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define PARSESTART
|
||||
#include "clang/Basic/DiagnosticParseKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define REFACTORINGSTART
|
||||
#include "clang/Basic/DiagnosticRefactoringKinds.inc"
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define SEMASTART
|
||||
#include "clang/Basic/DiagnosticSemaKinds.inc"
|
||||
|
|
|
@ -197,7 +197,8 @@ def ext_flexible_array_init : Extension<
|
|||
|
||||
// C++20 designated initializers
|
||||
def ext_cxx_designated_init : Extension<
|
||||
"designated initializers are a C++20 extension">, InGroup<CXX20Designator>;
|
||||
"designated initializers are a C++20 extension">, InGroup<CXX20Designator>,
|
||||
SuppressInSystemMacro;
|
||||
def warn_cxx17_compat_designated_init : Warning<
|
||||
"designated initializers are incompatible with C++ standards before C++20">,
|
||||
InGroup<CXXPre20CompatPedantic>, DefaultIgnore;
|
||||
|
@ -449,7 +450,7 @@ def warn_decl_shadow :
|
|||
"typedef in %2|"
|
||||
"type alias in %2|"
|
||||
"structured binding}1">,
|
||||
InGroup<Shadow>, DefaultIgnore;
|
||||
InGroup<Shadow>, DefaultIgnore, SuppressInSystemMacro;
|
||||
def warn_decl_shadow_uncaptured_local :
|
||||
Warning<warn_decl_shadow.Text>,
|
||||
InGroup<ShadowUncapturedLocal>, DefaultIgnore;
|
||||
|
@ -3941,7 +3942,8 @@ def warn_cast_align : Warning<
|
|||
"cast from %0 to %1 increases required alignment from %2 to %3">,
|
||||
InGroup<CastAlign>, DefaultIgnore;
|
||||
def warn_old_style_cast : Warning<
|
||||
"use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore;
|
||||
"use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore,
|
||||
SuppressInSystemMacro;
|
||||
|
||||
// Separate between casts to void* and non-void* pointers.
|
||||
// Some APIs use (abuse) void* for something like a user context,
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace clang {
|
|||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
ENUM,
|
||||
#define SERIALIZATIONSTART
|
||||
#include "clang/Basic/DiagnosticSerializationKinds.inc"
|
||||
|
|
|
@ -33,7 +33,7 @@ struct StaticDiagInfoRec;
|
|||
// platforms. See "How To Write Shared Libraries" by Ulrich Drepper.
|
||||
struct StaticDiagInfoDescriptionStringTable {
|
||||
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
char ENUM##_desc[sizeof(DESC)];
|
||||
// clang-format off
|
||||
#include "clang/Basic/DiagnosticCommonKinds.inc"
|
||||
|
@ -54,7 +54,7 @@ struct StaticDiagInfoDescriptionStringTable {
|
|||
|
||||
const StaticDiagInfoDescriptionStringTable StaticDiagInfoDescriptions = {
|
||||
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
DESC,
|
||||
// clang-format off
|
||||
#include "clang/Basic/DiagnosticCommonKinds.inc"
|
||||
|
@ -79,7 +79,7 @@ extern const StaticDiagInfoRec StaticDiagInfo[];
|
|||
// StaticDiagInfoRec would have extra padding on 64-bit platforms.
|
||||
const uint32_t StaticDiagInfoDescriptionOffsets[] = {
|
||||
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
offsetof(StaticDiagInfoDescriptionStringTable, ENUM##_desc),
|
||||
// clang-format off
|
||||
#include "clang/Basic/DiagnosticCommonKinds.inc"
|
||||
|
@ -115,6 +115,7 @@ struct StaticDiagInfoRec {
|
|||
uint8_t Category : 6;
|
||||
uint8_t WarnNoWerror : 1;
|
||||
uint8_t WarnShowInSystemHeader : 1;
|
||||
uint8_t WarnShowInSystemMacro : 1;
|
||||
|
||||
uint16_t OptionGroupIndex : 15;
|
||||
uint16_t Deferrable : 1;
|
||||
|
@ -170,7 +171,7 @@ VALIDATE_DIAG_SIZE(REFACTORING)
|
|||
const StaticDiagInfoRec StaticDiagInfo[] = {
|
||||
// clang-format off
|
||||
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
|
||||
{ \
|
||||
diag::ENUM, \
|
||||
DEFAULT_SEVERITY, \
|
||||
|
@ -179,6 +180,7 @@ const StaticDiagInfoRec StaticDiagInfo[] = {
|
|||
CATEGORY, \
|
||||
NOWERROR, \
|
||||
SHOWINSYSHEADER, \
|
||||
SHOWINSYSMACRO, \
|
||||
GROUP, \
|
||||
DEFERRABLE, \
|
||||
STR_SIZE(DESC, uint16_t)},
|
||||
|
@ -586,6 +588,13 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
|
|||
Diag.getSourceManager().getExpansionLoc(Loc)))
|
||||
return diag::Severity::Ignored;
|
||||
|
||||
// We also ignore warnings due to system macros
|
||||
bool ShowInSystemMacro =
|
||||
!GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemMacro;
|
||||
if (State->SuppressSystemWarnings && !ShowInSystemMacro && Loc.isValid() &&
|
||||
Diag.getSourceManager().isInSystemMacro(Loc))
|
||||
return diag::Severity::Ignored;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -7798,8 +7798,6 @@ void Sema::CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl,
|
|||
DeclarationName Name = R.getLookupName();
|
||||
|
||||
// Emit warning and note.
|
||||
if (getSourceManager().isInSystemMacro(R.getNameLoc()))
|
||||
return;
|
||||
ShadowedDeclKind Kind = computeShadowedDeclKind(ShadowedDecl, OldDC);
|
||||
Diag(R.getNameLoc(), WarningDiag) << Name << Kind << OldDC;
|
||||
if (!CaptureLoc.isInvalid())
|
||||
|
|
|
@ -7727,8 +7727,7 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
|
|||
CastExpr = Result.get();
|
||||
}
|
||||
|
||||
if (getLangOpts().CPlusPlus && !castType->isVoidType() &&
|
||||
!getSourceManager().isInSystemMacro(LParenLoc))
|
||||
if (getLangOpts().CPlusPlus && !castType->isVoidType())
|
||||
Diag(LParenLoc, diag::warn_old_style_cast) << CastExpr->getSourceRange();
|
||||
|
||||
CheckTollFreeBridgeCast(castType, CastExpr);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast %s
|
||||
// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast -Wc++20-designator %s
|
||||
|
||||
// Test that macro expansions from system headers don't trigger 'syntactic'
|
||||
// warnings that are not actionable.
|
||||
|
@ -12,6 +12,11 @@
|
|||
|
||||
#define OLD_STYLE_CAST(a) ((int) (a))
|
||||
|
||||
struct Foo {
|
||||
int x;
|
||||
};
|
||||
#define DESIGNATED_INITIALIZERS (Foo{.x = 123})
|
||||
|
||||
#else
|
||||
|
||||
#define IS_SYSHEADER
|
||||
|
@ -28,8 +33,13 @@ void PR16093() {
|
|||
}
|
||||
|
||||
void PR18147() {
|
||||
// no -Wold_style_cast in system macro expansion
|
||||
// no -Wold-style-cast in system macro expansion
|
||||
int i = OLD_STYLE_CAST(0);
|
||||
}
|
||||
|
||||
void PR52944() {
|
||||
// no -Wc++20-designator in system macro expansion
|
||||
auto i = DESIGNATED_INITIALIZERS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -76,6 +76,7 @@ class Diagnostic<string text, DiagClass DC, Severity defaultmapping> {
|
|||
bit AccessControl = 0;
|
||||
bit WarningNoWerror = 0;
|
||||
bit ShowInSystemHeader = 0;
|
||||
bit ShowInSystemMacro = 1;
|
||||
bit Deferrable = 0;
|
||||
Severity DefaultSeverity = defaultmapping;
|
||||
DiagGroup Group;
|
||||
|
@ -100,6 +101,14 @@ class SuppressInSystemHeader {
|
|||
bit ShowInSystemHeader = 0;
|
||||
}
|
||||
|
||||
class ShowInSystemMacro {
|
||||
bit ShowInSystemMacro = 1;
|
||||
}
|
||||
|
||||
class SuppressInSystemMacro {
|
||||
bit ShowInSystemMacro = 0;
|
||||
}
|
||||
|
||||
class Deferrable {
|
||||
bit Deferrable = 1;
|
||||
}
|
||||
|
|
|
@ -5,23 +5,23 @@ include "DiagnosticBase.inc"
|
|||
// Test usage of Deferrable and NonDeferrable in diagnostics.
|
||||
|
||||
def test_default : Error<"This error is non-deferrable by default">;
|
||||
// CHECK-DAG: DIAG(test_default, {{.*}}SFINAE_SubstitutionFailure, false, true, false, 0)
|
||||
// CHECK-DAG: DIAG(test_default, {{.*}}SFINAE_SubstitutionFailure, false, true, true, false, 0)
|
||||
|
||||
def test_deferrable : Error<"This error is deferrable">, Deferrable;
|
||||
// CHECK-DAG: DIAG(test_deferrable, {{.*}} SFINAE_SubstitutionFailure, false, true, true, 0)
|
||||
// CHECK-DAG: DIAG(test_deferrable, {{.*}} SFINAE_SubstitutionFailure, false, true, true, true, 0)
|
||||
|
||||
def test_non_deferrable : Error<"This error is non-deferrable">, NonDeferrable;
|
||||
// CHECK-DAG: DIAG(test_non_deferrable, {{.*}} SFINAE_SubstitutionFailure, false, true, false, 0)
|
||||
// CHECK-DAG: DIAG(test_non_deferrable, {{.*}} SFINAE_SubstitutionFailure, false, true, true, false, 0)
|
||||
|
||||
let Deferrable = 1 in {
|
||||
|
||||
def test_let : Error<"This error is deferrable by let">;
|
||||
// CHECK-DAG: DIAG(test_let, {{.*}} SFINAE_SubstitutionFailure, false, true, true, 0)
|
||||
// CHECK-DAG: DIAG(test_let, {{.*}} SFINAE_SubstitutionFailure, false, true, true, true, 0)
|
||||
|
||||
// Make sure TextSubstitution is allowed in the let Deferrable block.
|
||||
def textsub : TextSubstitution<"%select{text1|text2}0">;
|
||||
|
||||
def test_let2 : Error<"This error is deferrable by let %sub{textsub}0">;
|
||||
// CHECK-DAG: DIAG(test_let2, {{.*}} SFINAE_SubstitutionFailure, false, true, true, 0)
|
||||
// CHECK-DAG: DIAG(test_let2, {{.*}} SFINAE_SubstitutionFailure, false, true, true, true, 0)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,9 +27,9 @@ llvm::ArrayRef<DiagnosticRecord> diagtool::getBuiltinDiagnosticsByName() {
|
|||
// FIXME: Is it worth having two tables, especially when this one can get
|
||||
// out of sync easily?
|
||||
static const DiagnosticRecord BuiltinDiagnosticsByID[] = {
|
||||
#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \
|
||||
SFINAE,NOWERROR,SHOWINSYSHEADER,DEFER,CATEGORY) \
|
||||
{ #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) },
|
||||
#define DIAG(ENUM, CLASS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFER, CATEGORY) \
|
||||
{#ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t)},
|
||||
#include "clang/Basic/DiagnosticCommonKinds.inc"
|
||||
#include "clang/Basic/DiagnosticCrossTUKinds.inc"
|
||||
#include "clang/Basic/DiagnosticDriverKinds.inc"
|
||||
|
|
|
@ -1311,6 +1311,11 @@ void clang::EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS,
|
|||
else
|
||||
OS << ", false";
|
||||
|
||||
if (R.getValueAsBit("ShowInSystemMacro"))
|
||||
OS << ", true";
|
||||
else
|
||||
OS << ", false";
|
||||
|
||||
if (R.getValueAsBit("Deferrable"))
|
||||
OS << ", true";
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue