https://github.com/mattst88 created 
https://github.com/llvm/llvm-project/pull/217815

GCC accepts the `wb`/`uwb` `_BitInt` suffixes before C23 without a warning, and
pedwarns about them under `-Wpedantic` ("ISO C does not support literal 'wb'
suffixes before C23") — in both `-std=c11` and `-std=gnu11`. Clang instead emits
`ext_c23_bitint_suffix`, an `ExtWarn` in the default-on `-Wc23-extensions`
group, so a literal such as `0uwb` is an error under `-Werror`.

That breaks code built in a GNU C mode with `-Werror`. glibc is one: it builds
with `-std=gnu11` (`Makeconfig`), and `stdlib/tst-stdbit-builtins.c` writes
`0uwb` directly.

In a GNU C mode before C23 the suffix is available as an extension, the same way
it is in C++, so this diagnoses it with a new `ext_bitint_suffix_in_gnu_mode`
rather than as a use of a C23 feature. This follows the existing
`ext_vla_cxx_in_gnu_mode`, which downgrades the C++ VLA `ExtWarn` to a silent
`Extension` in GNU mode and reuses the non-GNU variant's summary and diagnostic
group. Both the preprocessor expression evaluator and the Sema literal handler
need the same arm.

Resulting behaviour, which matches the shape GCC has:

| | before | after |
|---|---|---|
| `-std=gnu11` | warns (`-Wc23-extensions`) | silent |
| `-std=gnu11 -pedantic` | warns | warns (`-Wbit-int-extension`) |
| `-std=c11` | warns | warns (unchanged) |

**Tradeoff worth calling out for review:** a GNU C mode now reports the suffix
under `-Wbit-int-extension` instead of `-Wc23-extensions`, so `-std=gnu11
-Wc23-extensions` no longer flags it. Strict ISO modes are untouched. I think
that's the right split — it's what the VLA precedent does — but it is a
deliberate behaviour change and I'd rather it be discussed than discovered.

`clang/test/Lexer/bitint-constants-compat.c` gains two RUN lines covering a GNU
mode with and without `-Wbit-int-extension`. `clang/test/AST/ByteCode/complex.c`
has no `-std`, so it is gnu17 and its two expected warnings go away.

Full `check-clang` passes.


>From 7d86d1a67bfdfbb46775d201bf94be39f25e0cab Mon Sep 17 00:00:00 2001
From: Matt Turner <[email protected]>
Date: Fri, 10 Jul 2026 03:14:47 -0400
Subject: [PATCH] [clang] Diagnose the _BitInt suffix as an extension in GNU C
 modes

GCC accepts the wb/uwb _BitInt suffixes before C23 without a warning and
pedwarns about them under -Wpedantic ("ISO C does not support literal 'wb'
suffixes before C23"), in both -std=c11 and -std=gnu11.  Clang instead emitted
ext_c23_bitint_suffix, which is an ExtWarn in the default-on -Wc23-extensions
group, so a literal such as 0uwb was an error under -Werror.  That breaks code
built in a GNU C mode with -Werror, glibc's stdlib/tst-stdbit-builtins.c for
one: glibc builds with -std=gnu11 and the test writes 0uwb directly.

In a GNU C mode before C23 the suffix is available as an extension, the same
way it is in C++, so diagnose it with a new ext_bitint_suffix_in_gnu_mode
rather than as a use of a C23 feature.  This follows ext_vla_cxx_in_gnu_mode,
which downgrades the C++ VLA ExtWarn to a silent Extension the same way and
shares the non-GNU variant's summary and diagnostic group.  Both the
preprocessor expression evaluator and the Sema literal handler need the same
arm.

The tradeoff is deliberate: a GNU C mode now reports the suffix under
-Wbit-int-extension instead of -Wc23-extensions, so -std=gnu11
-Wc23-extensions no longer flags it.  Strict ISO modes such as -std=c11 are
untouched and still warn by default, and -std=gnu11 -pedantic still warns,
which is the shape GCC has.

Assisted-by: Claude Code
---
 clang/docs/ReleaseNotes.md                         |  7 +++++++
 clang/include/clang/Basic/DiagnosticCommonKinds.td |  2 ++
 clang/lib/Lex/PPExpressions.cpp                    | 12 +++++++-----
 clang/lib/Sema/SemaExpr.cpp                        |  1 +
 clang/test/AST/ByteCode/complex.c                  |  4 +++-
 clang/test/Lexer/bitint-constants-compat.c         | 11 +++++++++++
 6 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 8c9467ca7b742..28caa1937acff 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -238,6 +238,13 @@ features cannot lower the translation-unit ABI level;
 
 - More consistent rendering of Unicode characters in diagnostic messages.
 
+- The `wb` and `uwb` `_BitInt` literal suffixes are now diagnosed in GNU C 
modes
+  before C23 as a Clang extension, under `-Wbit-int-extension` (so silent 
unless
+  `-pedantic` or that flag is given), rather than under the default-on
+  `-Wc23-extensions`. This matches GCC, which accepts the suffixes in 
`-std=gnu11`
+  and only pedwarns about them. Strict ISO modes such as `-std=c11` still warn 
by
+  default.
+
 - Fixed bug in `-Wdocumentation` so that it correctly handles explicit
   function template instantiations (#64087).
 
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index 192fdf9299eb4..10343e2c340a0 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -240,6 +240,8 @@ def ext_cxx_bitint_suffix : Extension<
 def ext_c23_bitint_suffix : ExtWarn<
   "'_BitInt' suffix for literals is a C23 extension">,
   InGroup<C23>;
+def ext_bitint_suffix_in_gnu_mode : Extension<ext_cxx_bitint_suffix.Summary>,
+  InGroup<BitIntExtension>;
 def warn_c23_compat_bitint_suffix : Warning<
   "'_BitInt' suffix for literals is incompatible with C standards before C23">,
   InGroup<CPre23Compat>, DefaultIgnore;
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index 1040b83e8745d..4d47c1b6e9707 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -335,13 +335,15 @@ static bool EvaluateValue(PPValue &Result, Token 
&PeekTok, DefinedTracker &DT,
                                  : diag::ext_cxx23_size_t_suffix
                            : diag::err_cxx23_size_t_suffix);
 
-    // 'wb/uwb' literals are a C23 feature.
+    // 'wb/uwb' literals are a C23 feature, and an extension before C23 in a
+    // GNU C mode, the way they are in C++.
     // '__wb/__uwb' are a C++ extension.
     if (Literal.isBitInt)
-      PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
-                       : PP.getLangOpts().C23
-                           ? diag::warn_c23_compat_bitint_suffix
-                           : diag::ext_c23_bitint_suffix);
+      PP.Diag(PeekTok,
+              PP.getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
+              : PP.getLangOpts().C23     ? diag::warn_c23_compat_bitint_suffix
+              : PP.getLangOpts().GNUMode ? diag::ext_bitint_suffix_in_gnu_mode
+                                         : diag::ext_c23_bitint_suffix);
 
     // Parse the integer literal into Result.
     if (Literal.GetIntegerValue(Result.Val)) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index da76bbf3c35f0..a7fa009fd744c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4073,6 +4073,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, 
Scope *UDLScope) {
       PP.Diag(Tok.getLocation(),
               getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix
               : getLangOpts().C23     ? diag::warn_c23_compat_bitint_suffix
+              : getLangOpts().GNUMode ? diag::ext_bitint_suffix_in_gnu_mode
                                       : diag::ext_c23_bitint_suffix);
 
     // Get the value in the widest-possible width. What is "widest" depends on
diff --git a/clang/test/AST/ByteCode/complex.c 
b/clang/test/AST/ByteCode/complex.c
index 12c51f95ff7c6..c30d1d3f1f93f 100644
--- a/clang/test/AST/ByteCode/complex.c
+++ b/clang/test/AST/ByteCode/complex.c
@@ -29,4 +29,6 @@ void testComplexFloat(_Atomic(_Complex float) *fp) {
   *fp = f;
 }
 
-void ZeroNeedsAlloc() { 9999999999999999999wb / 1wbi; } // both-warning 
2{{'_BitInt' suffix for literals is a C23 extension}}
+// The RUN lines above have no -std, so this is gnu17, where the suffix is an
+// extension Clang accepts silently.
+void ZeroNeedsAlloc() { 9999999999999999999wb / 1wbi; }
diff --git a/clang/test/Lexer/bitint-constants-compat.c 
b/clang/test/Lexer/bitint-constants-compat.c
index d8bff94ef88ca..ef7d1e22a1d0c 100644
--- a/clang/test/Lexer/bitint-constants-compat.c
+++ b/clang/test/Lexer/bitint-constants-compat.c
@@ -1,23 +1,34 @@
 // RUN: %clang_cc1 -std=c17 -fsyntax-only -verify=ext -Wno-unused %s
 // RUN: %clang_cc1 -std=c2x -fsyntax-only -verify=compat -Wpre-c2x-compat 
-Wno-unused %s
 // RUN: %clang_cc1 -fsyntax-only -verify=cpp -Wbit-int-extension -Wno-unused 
-x c++ %s
+//
+// gnu proves the extension warning fires in a GNU C mode, gnuquiet that it is
+// silent without -Wbit-int-extension.
+// RUN: %clang_cc1 -std=gnu17 -fsyntax-only -verify=gnu -Wbit-int-extension 
-Wno-unused %s
+// RUN: %clang_cc1 -std=gnu17 -fsyntax-only -verify=gnuquiet -Wno-unused %s
 
 #if 18446744073709551615uwb // ext-warning {{'_BitInt' suffix for literals is 
a C23 extension}} \
                                compat-warning {{'_BitInt' suffix for literals 
is incompatible with C standards before C23}} \
+                               gnu-warning {{'_BitInt' suffix for literals is 
a Clang extension}} \
                                cpp-error {{invalid suffix 'uwb' on integer 
constant}}
 #endif
 
 #if 18446744073709551615__uwb // ext-error {{invalid suffix '__uwb' on integer 
constant}} \
                                compat-error {{invalid suffix '__uwb' on 
integer constant}} \
+                               gnu-error {{invalid suffix '__uwb' on integer 
constant}} \
+                               gnuquiet-error {{invalid suffix '__uwb' on 
integer constant}} \
                                cpp-warning {{'_BitInt' suffix for literals is 
a Clang extension}}
 #endif
 
 void func(void) {
   18446744073709551615wb; // ext-warning {{'_BitInt' suffix for literals is a 
C23 extension}} \
                              compat-warning {{'_BitInt' suffix for literals is 
incompatible with C standards before C23}} \
+                             gnu-warning {{'_BitInt' suffix for literals is a 
Clang extension}} \
                              cpp-error {{invalid suffix 'wb' on integer 
constant}}
 
   18446744073709551615__wb; // ext-error {{invalid suffix '__wb' on integer 
constant}} \
                              compat-error {{invalid suffix '__wb' on integer 
constant}} \
+                             gnu-error {{invalid suffix '__wb' on integer 
constant}} \
+                             gnuquiet-error {{invalid suffix '__wb' on integer 
constant}} \
                              cpp-warning {{'_BitInt' suffix for literals is a 
Clang extension}}
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to