diff --git a/clang/include/clang/Basic/Diagnostic.td b/clang/include/clang/Basic/Diagnostic.td --- a/clang/include/clang/Basic/Diagnostic.td +++ b/clang/include/clang/Basic/Diagnostic.td @@ -84,6 +84,7 @@ bit AccessControl = 0; bit WarningNoWerror = 0; bit ShowInSystemHeader = 0; + bit ShowInSystemMacro = 1; bit Deferrable = 0; Severity DefaultSeverity = defaultmapping; DiagGroup Group; @@ -108,6 +109,14 @@ bit ShowInSystemHeader = 0; } +class ShowInSystemMacro { + bit ShowInSystemMacro = 1; +} + +class SuppressInSystemMacro { + bit ShowInSystemMacro = 0; +} + class Deferrable { bit Deferrable = 1; } @@ -159,4 +168,3 @@ include "DiagnosticRefactoringKinds.td" include "DiagnosticSemaKinds.td" include "DiagnosticSerializationKinds.td" - diff --git a/clang/include/clang/Basic/DiagnosticAST.h b/clang/include/clang/Basic/DiagnosticAST.h --- a/clang/include/clang/Basic/DiagnosticAST.h +++ b/clang/include/clang/Basic/DiagnosticAST.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticAnalysis.h b/clang/include/clang/Basic/DiagnosticAnalysis.h --- a/clang/include/clang/Basic/DiagnosticAnalysis.h +++ b/clang/include/clang/Basic/DiagnosticAnalysis.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticComment.h b/clang/include/clang/Basic/DiagnosticComment.h --- a/clang/include/clang/Basic/DiagnosticComment.h +++ b/clang/include/clang/Basic/DiagnosticComment.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticCrossTU.h b/clang/include/clang/Basic/DiagnosticCrossTU.h --- a/clang/include/clang/Basic/DiagnosticCrossTU.h +++ b/clang/include/clang/Basic/DiagnosticCrossTU.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticDriver.h b/clang/include/clang/Basic/DiagnosticDriver.h --- a/clang/include/clang/Basic/DiagnosticDriver.h +++ b/clang/include/clang/Basic/DiagnosticDriver.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticFrontend.h b/clang/include/clang/Basic/DiagnosticFrontend.h --- a/clang/include/clang/Basic/DiagnosticFrontend.h +++ b/clang/include/clang/Basic/DiagnosticFrontend.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h --- a/clang/include/clang/Basic/DiagnosticIDs.h +++ b/clang/include/clang/Basic/DiagnosticIDs.h @@ -67,7 +67,7 @@ // 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" diff --git a/clang/include/clang/Basic/DiagnosticLex.h b/clang/include/clang/Basic/DiagnosticLex.h --- a/clang/include/clang/Basic/DiagnosticLex.h +++ b/clang/include/clang/Basic/DiagnosticLex.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticParse.h b/clang/include/clang/Basic/DiagnosticParse.h --- a/clang/include/clang/Basic/DiagnosticParse.h +++ b/clang/include/clang/Basic/DiagnosticParse.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticRefactoring.h b/clang/include/clang/Basic/DiagnosticRefactoring.h --- a/clang/include/clang/Basic/DiagnosticRefactoring.h +++ b/clang/include/clang/Basic/DiagnosticRefactoring.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticSema.h b/clang/include/clang/Basic/DiagnosticSema.h --- a/clang/include/clang/Basic/DiagnosticSema.h +++ b/clang/include/clang/Basic/DiagnosticSema.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -197,7 +197,8 @@ // C++20 designated initializers def ext_cxx_designated_init : Extension< - "designated initializers are a C++20 extension">, InGroup; + "designated initializers are a C++20 extension">, InGroup, + SuppressInSystemMacro; def warn_cxx17_compat_designated_init : Warning< "designated initializers are incompatible with C++ standards before C++20">, InGroup, DefaultIgnore; @@ -449,7 +450,7 @@ "typedef in %2|" "type alias in %2|" "structured binding}1">, - InGroup, DefaultIgnore; + InGroup, DefaultIgnore, SuppressInSystemMacro; def warn_decl_shadow_uncaptured_local : Warning, InGroup, DefaultIgnore; @@ -3944,7 +3945,8 @@ "cast from %0 to %1 increases required alignment from %2 to %3">, InGroup, DefaultIgnore; def warn_old_style_cast : Warning< - "use of old-style cast">, InGroup, DefaultIgnore; + "use of old-style cast">, InGroup, DefaultIgnore, + SuppressInSystemMacro; // Separate between casts to void* and non-void* pointers. // Some APIs use (abuse) void* for something like a user context, diff --git a/clang/include/clang/Basic/DiagnosticSerialization.h b/clang/include/clang/Basic/DiagnosticSerialization.h --- a/clang/include/clang/Basic/DiagnosticSerialization.h +++ b/clang/include/clang/Basic/DiagnosticSerialization.h @@ -15,7 +15,7 @@ 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" diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -33,7 +33,7 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ CATEGORY, \ NOWERROR, \ SHOWINSYSHEADER, \ + SHOWINSYSMACRO, \ GROUP, \ DEFERRABLE, \ STR_SIZE(DESC, uint16_t)}, @@ -586,6 +588,13 @@ 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; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7798,8 +7798,6 @@ 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()) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7727,8 +7727,7 @@ 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); diff --git a/clang/test/SemaCXX/warn-sysheader-macro.cpp b/clang/test/SemaCXX/warn-sysheader-macro.cpp --- a/clang/test/SemaCXX/warn-sysheader-macro.cpp +++ b/clang/test/SemaCXX/warn-sysheader-macro.cpp @@ -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 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 diff --git a/clang/test/TableGen/DiagnosticBase.inc b/clang/test/TableGen/DiagnosticBase.inc --- a/clang/test/TableGen/DiagnosticBase.inc +++ b/clang/test/TableGen/DiagnosticBase.inc @@ -76,6 +76,7 @@ bit AccessControl = 0; bit WarningNoWerror = 0; bit ShowInSystemHeader = 0; + bit ShowInSystemMacro = 1; bit Deferrable = 0; Severity DefaultSeverity = defaultmapping; DiagGroup Group; @@ -100,6 +101,14 @@ bit ShowInSystemHeader = 0; } +class ShowInSystemMacro { + bit ShowInSystemMacro = 1; +} + +class SuppressInSystemMacro { + bit ShowInSystemMacro = 0; +} + class Deferrable { bit Deferrable = 1; } diff --git a/clang/test/TableGen/deferred-diag.td b/clang/test/TableGen/deferred-diag.td --- a/clang/test/TableGen/deferred-diag.td +++ b/clang/test/TableGen/deferred-diag.td @@ -5,23 +5,23 @@ // 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) -} \ No newline at end of file +} diff --git a/clang/tools/diagtool/DiagnosticNames.cpp b/clang/tools/diagtool/DiagnosticNames.cpp --- a/clang/tools/diagtool/DiagnosticNames.cpp +++ b/clang/tools/diagtool/DiagnosticNames.cpp @@ -27,9 +27,9 @@ // 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" diff --git a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp --- a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -1311,6 +1311,11 @@ else OS << ", false"; + if (R.getValueAsBit("ShowInSystemMacro")) + OS << ", true"; + else + OS << ", false"; + if (R.getValueAsBit("Deferrable")) OS << ", true"; else