Skip to content
Snippets Groups Projects
Commit c4db521c authored by Carlos Galvez's avatar Carlos Galvez
Browse files

[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
parent 22225cc5
No related branches found
No related tags found
No related merge requests found
Showing
with 62 additions and 27 deletions
......@@ -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);
......
// 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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment