[clang] [C23] Do not diagnose binary literals as an extension (PR #81658)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 13 11:56:47 PST 2024


https://github.com/AaronBallman created https://github.com/llvm/llvm-project/pull/81658

We previously would diagnose them as a GNU extension in C mode, but they are now a feature of C23. This removes the old warning group, -Wgnu-binary-literal, as it no longer makes sense and searching through public repositories shows it is a rarely used option (same for the -Wno form). It also adds the companion compatibility warning which existed for C++ but not for C.

Fixes https://github.com/llvm/llvm-project/issues/72017

>From d1e840aa381dbef967f0569b2cd2c295f53db49b Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 13 Feb 2024 14:53:11 -0500
Subject: [PATCH] [C23] Do not diagnose binary literals as an extension

We previously would diagnose them as a GNU extension in C mode, but
they are now a feature of C23. This removes the old warning group,
-Wgnu-binary-literal, as it no longer makes sense and searching through
public repositories shows it is a rarely used option (same for the -Wno
form). It also adds the companion compatibility warning which existed
for C++ but not for C.

Fixes https://github.com/llvm/llvm-project/issues/72017
---
 clang/docs/ReleaseNotes.rst                     |  6 ++++++
 clang/include/clang/Basic/DiagnosticGroups.td   |  7 ++-----
 clang/include/clang/Basic/DiagnosticLexKinds.td |  5 ++++-
 clang/lib/Lex/LiteralSupport.cpp                | 16 +++++++++++-----
 clang/test/C/C2x/n2549.c                        | 14 ++++++++++++++
 clang/test/Lexer/gnu-flags.c                    | 14 +++-----------
 6 files changed, 40 insertions(+), 22 deletions(-)
 create mode 100644 clang/test/C/C2x/n2549.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc2fb3b25e3a54..94ce2923b88c54 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -56,6 +56,10 @@ Clang Frontend Potentially Breaking Changes
   ``ArrayRef<TemplateArgument>`` reduces AST memory usage by 0.4% when compiling clang, and is
   expected to show similar improvements on other workloads.
 
+- Removed the ``-Wgnu-binary-literal`` diagnostic group. Binary literals are no
+  longer a GNU extension, they're now a C23 extension which is controlled via
+  ``-pedantic`` or ``-Wc23-extensions``.
+
 Target OS macros extension
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 A new Clang extension (see :ref:`here <target_os_detail>`) is enabled for
@@ -113,6 +117,8 @@ C Language Changes
 
 C23 Feature Support
 ^^^^^^^^^^^^^^^^^^^
+- No longer diagnose use of binary literals as an extension in C23 mode. Fixes
+ `#72017 <https://github.com/llvm/llvm-project/issues/72017>`_.
 
 Non-comprehensive list of changes in this release
 -------------------------------------------------
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 975eca0ad9b642..c783421910331c 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -44,10 +44,8 @@ def DeprecatedModuleDotMap : DiagGroup<"deprecated-module-dot-map">;
 def FrameworkHdrAtImport : DiagGroup<"atimport-in-framework-header">;
 def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">;
 def CXXPre14CompatBinaryLiteral : DiagGroup<"c++98-c++11-compat-binary-literal">;
-def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
 def BinaryLiteral : DiagGroup<"binary-literal", [CXX14BinaryLiteral,
-                                                 CXXPre14CompatBinaryLiteral,
-                                                 GNUBinaryLiteral]>;
+                                                 CXXPre14CompatBinaryLiteral]>;
 def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">;
 def SingleBitBitFieldConstantConversion :
   DiagGroup<"single-bit-bitfield-constant-conversion">;
@@ -1178,8 +1176,7 @@ def : DiagGroup<"c2x-extensions", [C23]>;
 
 // A warning group for warnings about GCC extensions.
 def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
-                            GNUAutoType,
-                            GNUBinaryLiteral, GNUCaseRange,
+                            GNUAutoType, GNUCaseRange,
                             GNUComplexInteger, GNUCompoundLiteralInitializer,
                             GNUConditionalOmittedOperand, GNUDesignator,
                             GNUEmptyStruct,
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 75ca2fa16d3485..1354543612b9fb 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -246,7 +246,10 @@ def warn_cxx17_hex_literal : Warning<
   "C++ standards before C++17">,
   InGroup<CXXPre17CompatPedantic>, DefaultIgnore;
 def ext_binary_literal : Extension<
-  "binary integer literals are a GNU extension">, InGroup<GNUBinaryLiteral>;
+  "binary integer literals are a C23 extension">, InGroup<C23>;
+def warn_c23_compat_binary_literal : Warning<
+  "binary integer literals are incompatible with C standards before C23">,
+  InGroup<CPre23Compat>, DefaultIgnore;
 def ext_binary_literal_cxx14 : Extension<
   "binary integer literals are a C++14 extension">, InGroup<CXX14BinaryLiteral>;
 def warn_cxx11_compat_binary_literal : Warning<
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index 0a78638f680511..571a984884029d 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -1358,11 +1358,17 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
 
   // Handle simple binary numbers 0b01010
   if ((c1 == 'b' || c1 == 'B') && (s[1] == '0' || s[1] == '1')) {
-    // 0b101010 is a C++1y / GCC extension.
-    Diags.Report(TokLoc, LangOpts.CPlusPlus14
-                             ? diag::warn_cxx11_compat_binary_literal
-                         : LangOpts.CPlusPlus ? diag::ext_binary_literal_cxx14
-                                              : diag::ext_binary_literal);
+    // 0b101010 is a C++14 and C23 extension.
+    unsigned DiagId;
+    if (LangOpts.CPlusPlus14)
+      DiagId = diag::warn_cxx11_compat_binary_literal;
+    else if (LangOpts.C23)
+      DiagId = diag::warn_c23_compat_binary_literal;
+    else if (LangOpts.CPlusPlus)
+      DiagId = diag::ext_binary_literal_cxx14;
+    else
+      DiagId = diag::ext_binary_literal;
+    Diags.Report(TokLoc, DiagId);
     ++s;
     assert(s < ThisTokEnd && "didn't maximally munch?");
     radix = 2;
diff --git a/clang/test/C/C2x/n2549.c b/clang/test/C/C2x/n2549.c
new file mode 100644
index 00000000000000..817338bcdacc39
--- /dev/null
+++ b/clang/test/C/C2x/n2549.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -std=c23 %s
+// RUN: %clang_cc1 -verify=pedantic -std=c17 -pedantic %s
+// RUN: %clang_cc1 -verify=compat -std=c23 -Wpre-c23-compat %s
+
+// expected-no-diagnostics
+
+/* WG14 N2549: Clang 9
+ * Binary literals
+ */
+
+int i = 0b01; /* pedantic-warning {{binary integer literals are a C23 extension}}
+                 compat-warning {{binary integer literals are incompatible with C standards before C23}}
+               */
+
diff --git a/clang/test/Lexer/gnu-flags.c b/clang/test/Lexer/gnu-flags.c
index 6e47547b009d52..384339fc859429 100644
--- a/clang/test/Lexer/gnu-flags.c
+++ b/clang/test/Lexer/gnu-flags.c
@@ -1,15 +1,14 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE
-// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu 
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DALL \
 // RUN:   -Wgnu-zero-variadic-macro-arguments \
-// RUN:   -Wgnu-imaginary-constant -Wgnu-binary-literal -Wgnu-zero-line-directive
+// RUN:   -Wgnu-imaginary-constant -Wgnu-zero-line-directive
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wgnu \
 // RUN:   -Wno-gnu-zero-variadic-macro-arguments \
-// RUN:   -Wno-gnu-imaginary-constant -Wno-gnu-binary-literal -Wno-gnu-zero-line-directive
+// RUN:   -Wno-gnu-imaginary-constant -Wno-gnu-zero-line-directive
 // Additional disabled tests:
 // %clang_cc1 -fsyntax-only -verify %s -DZEROARGS -Wgnu-zero-variadic-macro-arguments
 // %clang_cc1 -fsyntax-only -verify %s -DIMAGINARYCONST -Wgnu-imaginary-constant
-// %clang_cc1 -fsyntax-only -verify %s -DBINARYLITERAL -Wgnu-binary-literal
 // %clang_cc1 -fsyntax-only -verify %s -DLINE0 -Wgnu-zero-line-directive
 
 #if NONE
@@ -38,13 +37,6 @@ void foo( const char* c )
 float _Complex c = 1.if;
 
 
-#if ALL || BINARYLITERAL
-// expected-warning at +3 {{binary integer literals are a GNU extension}}
-#endif
-
-int b = 0b0101;
-
-
 // This case is handled differently because lit has a bug whereby #line 0 is reported to be on line 4294967295
 // http://llvm.org/bugs/show_bug.cgi?id=16952
 #if ALL || LINE0



More information about the cfe-commits mailing list