https://github.com/mattst88 updated https://github.com/llvm/llvm-project/pull/217815
>From 45589de91fb540d15e2453b3a62440b66f0b994d 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 0376f18c3d93f..440d9613a3072 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -265,6 +265,13 @@ features cannot lower the translation-unit ABI level; initialization, while not diagnosing parameters passed to the selected allocation function or promise constructor. (#GH217501) +- 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 34f6ccdbc2fe6..7dfdeb7185eb0 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4080,6 +4080,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
