[llvm-branch-commits] [clang] [clang] Adjust -pedantic-errors -WX/-Wno-error=X interaction (#184756) (PR #188422)
Fangrui Song via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Mar 25 00:16:16 PDT 2026
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/188422
While -Wno-long-long suppresses -pedantic-errors diagnostics in both GCC and Clang, GCC -Wno-error=long-long emits warnings while Clang still emits errors.
```
% echo 'long long x = 0;' | gcc -std=c89 -pedantic-errors -Wno-error=long-long -x c -fsyntax-only -
<stdin>:1:6: warning: ISO C90 does not support 'long long' [-Wlong-long]
% echo 'long long x = 0;' | clang -std=c89 -pedantic-errors -Wno-error=long-long -x c -fsyntax-only -
<stdin>:1:1: error: 'long long' is an extension when C99 mode is not enabled [-Werror,-Wlong-long]
1 | long long x = 0;
| ^
1 error generated.
```
The order of -pedantic-errors and -Wno-error=long-long does not matter.
Two fixes to how extension diagnostics interact with -pedantic-errors in getDiagnosticSeverity():
1. -Wno-error=X now downgrades -pedantic-errors diagnostics to warnings. setDiagnosticGroupWarningAsError() sets HasNoWarningAsError but not IsUser, so the ExtBehavior upgrade would re-promote to error. When HasNoWarningAsError is set, cap the ExtBehavior upgrade at Warning.
2. -Wfoo no longer prevents -pedantic-errors from upgrading to error. Previously, -Wfoo set IsUser which blocked the ExtBehavior upgrade entirely. Now only -Wno-foo (IsUser + Ignored) blocks the upgrade, matching GCC behavior.
```
% echo 'long long x = 0;' | myclang -std=c89 -pedantic-errors -Wno-error=long-long -x c -fsyntax-only -
<stdin>:1:1: warning: 'long long' is an extension when C99 mode is not enabled [-Wlong-long]
1 | long long x = 0;
| ^
1 warning generated.
```
Fixes https://github.com/llvm/llvm-project/issues/184250
>From 8385d86298c0fd43eeb2bc2817d894cb793f3c15 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 9 Mar 2026 19:35:17 -0700
Subject: [PATCH] [clang] Adjust -pedantic-errors -WX/-Wno-error=X interaction
(#184756)
While -Wno-long-long suppresses -pedantic-errors diagnostics in both GCC
and Clang, GCC -Wno-error=long-long emits warnings while Clang still
emits errors.
```
% echo 'long long x = 0;' | gcc -std=c89 -pedantic-errors -Wno-error=long-long -x c -fsyntax-only -
<stdin>:1:6: warning: ISO C90 does not support 'long long' [-Wlong-long]
% echo 'long long x = 0;' | clang -std=c89 -pedantic-errors -Wno-error=long-long -x c -fsyntax-only -
<stdin>:1:1: error: 'long long' is an extension when C99 mode is not enabled [-Werror,-Wlong-long]
1 | long long x = 0;
| ^
1 error generated.
```
The order of -pedantic-errors and -Wno-error=long-long does not matter.
Two fixes to how extension diagnostics interact with -pedantic-errors
in getDiagnosticSeverity():
1. -Wno-error=X now downgrades -pedantic-errors diagnostics to warnings.
setDiagnosticGroupWarningAsError() sets HasNoWarningAsError but not
IsUser, so the ExtBehavior upgrade would re-promote to error. When
HasNoWarningAsError is set, cap the ExtBehavior upgrade at Warning.
2. -Wfoo no longer prevents -pedantic-errors from upgrading to error.
Previously, -Wfoo set IsUser which blocked the ExtBehavior upgrade
entirely. Now only -Wno-foo (IsUser + Ignored) blocks the upgrade,
matching GCC behavior.
```
% echo 'long long x = 0;' | myclang -std=c89 -pedantic-errors -Wno-error=long-long -x c -fsyntax-only -
<stdin>:1:1: warning: 'long long' is an extension when C99 mode is not enabled [-Wlong-long]
1 | long long x = 0;
| ^
1 warning generated.
```
Fixes https://github.com/llvm/llvm-project/issues/184250
---
clang/docs/ReleaseNotes.rst | 7 +++++++
clang/lib/Basic/DiagnosticIDs.cpp | 13 ++++++++++---
clang/test/Misc/diag-mapping.c | 9 +++++++--
3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 04d3bc83072c1..6ead7d488e941 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -572,6 +572,13 @@ Bug Fixes in This Version
by diagnosing invalid comma-separated argument lists. (#GH166325)
- Clang now treats enumeration constants of fixed-underlying enums as the enumerated type. (#GH172118)
- Fixed a failed assertion in the preprocessor when ``__has_embed`` parameters are missing parentheses. (#GH175088)
+- Fixed the interaction between ``-pedantic-errors`` and ``-Wno-error=X``.
+ Previously, ``-Wno-error=X`` failed to downgrade ``-pedantic-errors``
+ diagnostics to warnings (e.g., ``-pedantic-errors -Wno-error=long-long``
+ still emitted an error for ``long long`` in C89 mode). Now ``-Wno-error=X``
+ correctly downgrades the diagnostic to a warning, matching GCC's behavior.
+ Additionally, ``-Wfoo`` no longer prevents ``-pedantic-errors`` from
+ upgrading extension diagnostics to errors. (#GH184250)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp
index 45aa901da307c..530187ea81bfc 100644
--- a/clang/lib/Basic/DiagnosticIDs.cpp
+++ b/clang/lib/Basic/DiagnosticIDs.cpp
@@ -500,9 +500,16 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
return diag::Severity::Ignored;
// For extension diagnostics that haven't been explicitly mapped, check if we
- // should upgrade the diagnostic.
- if (IsExtensionDiag && !Mapping.isUser())
- Result = std::max(Result, State->ExtBehavior);
+ // should upgrade the diagnostic. Skip if the user explicitly suppressed it
+ // (e.g. -Wno-foo).
+ if (IsExtensionDiag &&
+ !(Mapping.isUser() && Result == diag::Severity::Ignored)) {
+ if (Mapping.hasNoWarningAsError())
+ Result = std::max(Result,
+ std::min(State->ExtBehavior, diag::Severity::Warning));
+ else
+ Result = std::max(Result, State->ExtBehavior);
+ }
// At this point, ignored errors can no longer be upgraded.
if (Result == diag::Severity::Ignored)
diff --git a/clang/test/Misc/diag-mapping.c b/clang/test/Misc/diag-mapping.c
index edc137ec68fef..20b6cccb77884 100644
--- a/clang/test/Misc/diag-mapping.c
+++ b/clang/test/Misc/diag-mapping.c
@@ -18,12 +18,17 @@
// This should emit an error with -pedantic-errors.
// RUN: not %clang_cc1 %s -pedantic-errors 2>&1 | grep "error:"
-// This should emit a warning, because -Wfoo overrides -pedantic*.
-// RUN: %clang_cc1 %s -pedantic-errors -Wextra-tokens 2>&1 | grep "warning:"
+// RUN: %clang_cc1 %s -pedantic -Wno-error=extra-tokens 2>&1 | grep "warning:"
+
+// -Wfoo does not override -pedantic-errors; the diagnostic stays an error.
+// RUN: not %clang_cc1 %s -pedantic-errors -Wextra-tokens 2>&1 | grep "error:"
// This should emit nothing, because -Wno-extra-tokens overrides -pedantic*
// RUN: %clang_cc1 %s -pedantic-errors -Wno-extra-tokens 2>&1 | not grep diagnostic
+// -Wno-error=extra-tokens should downgrade -pedantic-errors to warning.
+// RUN: %clang_cc1 %s -pedantic-errors -Wno-error=extra-tokens 2>&1 | grep "warning:"
+
#ifdef foo
#endif bad // extension!
More information about the llvm-branch-commits
mailing list