https://github.com/atetubou created https://github.com/llvm/llvm-project/pull/180684
…system modules When a template is instantiated from a system module, the location-specific diagnostic state (from 'Diag.GetDiagStateForLoc(Loc)') often has 'SuppressSystemWarnings' set to true because the location itself is within a system header defined by the module map. However, Clang provides mechanisms like 'AllowWarningInSystemHeaders' RAII (used for deprecated warnings in 'SemaAvailability.cpp') that temporarily override the global suppression state via 'Diag.setSuppressSystemWarnings(false)'. Previously, 'DiagnosticIDs::getDiagnosticSeverity' only checked the location-specific 'State->SuppressSystemWarnings', causing it to ignore these global overrides when the code originated from a system module. This patch updates 'getDiagnosticSeverity' to check both the location-specific 'State->SuppressSystemWarnings' and the global 'Diag.getSuppressSystemWarnings()'. This ensures that if the global state has been explicitly set to allow warnings (e.g. for deprecated templates instantiated in user code), the warning will be emitted even if the template definition resides in a system module. Fixes GH#170429 >From fdcd21fa231db92e9ec35e12d32f438cb32de195 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta <[email protected]> Date: Tue, 10 Feb 2026 14:42:13 +0900 Subject: [PATCH] [Clang][Modules] Ensure global diagnostic overrides are respected in system modules When a template is instantiated from a system module, the location-specific diagnostic state (from 'Diag.GetDiagStateForLoc(Loc)') often has 'SuppressSystemWarnings' set to true because the location itself is within a system header defined by the module map. However, Clang provides mechanisms like 'AllowWarningInSystemHeaders' RAII (used for deprecated warnings in 'SemaAvailability.cpp') that temporarily override the global suppression state via 'Diag.setSuppressSystemWarnings(false)'. Previously, 'DiagnosticIDs::getDiagnosticSeverity' only checked the location-specific 'State->SuppressSystemWarnings', causing it to ignore these global overrides when the code originated from a system module. This patch updates 'getDiagnosticSeverity' to check both the location-specific 'State->SuppressSystemWarnings' and the global 'Diag.getSuppressSystemWarnings()'. This ensures that if the global state has been explicitly set to allow warnings (e.g. for deprecated templates instantiated in user code), the warning will be emitted even if the template definition resides in a system module. Fixes GH#170429 --- clang/lib/Basic/DiagnosticIDs.cpp | 17 ++++++++++++----- clang/test/Modules/GH170429.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 clang/test/Modules/GH170429.cpp diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index a1d9d0f34d20d..a5f135083a4d5 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -549,8 +549,14 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, // If we are in a system header, we ignore it. We look at the diagnostic class // because we also want to ignore extensions and warnings in -Werror and // -pedantic-errors modes, which *map* warnings/extensions to errors. - if (State->SuppressSystemWarnings && Loc.isValid() && - SM.isInSystemHeader(SM.getExpansionLoc(Loc))) { + // + // We check both the location-specific state and the global engine state. + // In some cases (like template instantiations from system modules), the + // location-specific state might have suppression enabled, but the global + // engine state might have an override (e.g. AllowWarningInSystemHeaders) + // to show the warning. + if (State->SuppressSystemWarnings && Diag.getSuppressSystemWarnings() && + Loc.isValid() && SM.isInSystemHeader(SM.getExpansionLoc(Loc))) { bool ShowInSystemHeader = true; if (IsCustomDiag) ShowInSystemHeader = @@ -561,9 +567,10 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, if (!ShowInSystemHeader) return diag::Severity::Ignored; } - // We also ignore warnings due to system macros - if (State->SuppressSystemWarnings && Loc.isValid() && - SM.isInSystemMacro(Loc)) { + // We also ignore warnings due to system macros. As above, we respect the + // global engine suppression state to allow overrides. + if (State->SuppressSystemWarnings && Diag.getSuppressSystemWarnings() && + Loc.isValid() && SM.isInSystemMacro(Loc)) { bool ShowInSystemMacro = true; if (const StaticDiagInfoRec *Rec = GetDiagInfo(DiagID)) diff --git a/clang/test/Modules/GH170429.cpp b/clang/test/Modules/GH170429.cpp new file mode 100644 index 0000000000000..1a982b87c04e2 --- /dev/null +++ b/clang/test/Modules/GH170429.cpp @@ -0,0 +1,30 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -fmodules -fmodule-map-file=%t/module.modulemap -emit-module -o %t/A.pcm -fmodule-name=A -x c++ %t/module.modulemap +// RUN: %clang_cc1 -fmodules -fmodule-map-file=%t/module.modulemap -fmodule-file=A=%t/A.pcm -I%t %t/use.cc -verify + +//--- module.modulemap +module A [system] { + header "A.h" +} + +//--- A.h +template<typename T> +void make_unique() { + T(); +} + +//--- use.cc +#include "A.h" + +// [email protected]:* 2 {{'C' is deprecated}} + +class C { +public: + C() __attribute__((deprecated("",""))); // expected-note 2 {{'C' has been explicitly marked deprecated here}} +}; + +void bar() { + make_unique<C>(); // expected-note {{in instantiation of function template specialization 'make_unique<C>' requested here}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
