Skip to content

[C23] Do not diagnose binary literals as an extension #81658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 14, 2024

Conversation

AaronBallman
Copy link
Collaborator

@AaronBallman AaronBallman commented Feb 13, 2024

We previously would diagnose them as a GNU extension in C mode, but they are now a feature of C23. The -Wgnu-binary-literal warning group no longer controls any diagnostics as this is no longer a GNU extension. The warning group is retained as a noop to help avoid "unknown warning" diagnostics.

This also adds the companion compatibility warning which existed for C++ but not for C.

Fixes #72017

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 llvm#72017
@AaronBallman AaronBallman added clang Clang issues not falling into any other category c23 clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer labels Feb 13, 2024
@llvmbot
Copy link
Member

llvmbot commented Feb 13, 2024

@llvm/pr-subscribers-clang

Author: Aaron Ballman (AaronBallman)

Changes

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 #72017


Full diff: https://github.com/llvm/llvm-project/pull/81658.diff

6 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+6)
  • (modified) clang/include/clang/Basic/DiagnosticGroups.td (+2-5)
  • (modified) clang/include/clang/Basic/DiagnosticLexKinds.td (+4-1)
  • (modified) clang/lib/Lex/LiteralSupport.cpp (+11-5)
  • (added) clang/test/C/C2x/n2549.c (+14)
  • (modified) clang/test/Lexer/gnu-flags.c (+3-11)
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@+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

@llvmbot llvmbot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Feb 13, 2024
Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could consider keeping the warning group, not actually guarding any warning, so we don't warn on -Wno-gnu-binary-literal.

Otherwise looks fine.

Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

This helps avoid "unknown warning group" diagnostics even though it
doesn't actually control a diagnostic.
@AaronBallman
Copy link
Collaborator Author

We could consider keeping the warning group, not actually guarding any warning, so we don't warn on -Wno-gnu-binary-literal.

That's a good idea, I've done that and updated the release notes accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c23 clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[clang] Binary literals are flagged as a GNU extension even when compiling in C23 mode
4 participants