[clang] Suppress octal literal diagnostics from system macros (PR #192481)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 16 09:27:41 PDT 2026


https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/192481

>From 338b888f8478afc8a4e5d2c688038d88342e82f8 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Thu, 16 Apr 2026 12:04:54 -0400
Subject: [PATCH 1/3] Suppress octal literal diagnostics from system macros

We emit two kinds of diagnostics related to octal literals. One is a
compat/extension warning for use of 0o as the literal prefix and the
other is a deprecation warning for use of 0 as the literal prefix.

Clang now suppresses both of those diagnostics when the octal literal
comes from a macro expansion of a macro defined in a system header.
Those are not uses of the literal the user has any control over,
generally, so the diagnostics are not helpful in that case.

Fixes #192389
---
 clang/docs/ReleaseNotes.rst      |  6 ++++++
 clang/lib/Lex/LiteralSupport.cpp | 13 ++++++++++---
 clang/test/C/C2y/n3353.c         | 30 ++++++++++++++++++++++++++----
 3 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8d74dd8bc9699..e8edf36f39af5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -382,6 +382,12 @@ Improvements to Clang's diagnostics
   code can automatically be made portable to other host platforms that don't
   support backslashes.
 
+- No longer emitting a ``-Wpre-c2y-compat`` or extension diagnostic about use
+  of octal literals with a ``0o`` prefix, and no longer emitting a
+  ``-Wdeprecated-octal-literals`` diagnostic for use of octal literals without
+  a ``0o`` prefix, when the literal is expanded from a macro defined in a
+  system header. (#GH192389)
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index a6b895e842c80..c93e9e33786cc 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -1429,7 +1429,11 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
       DiagId = diag::ext_cpp_octal_literal;
     else
       DiagId = diag::ext_octal_literal;
-    Diags.Report(TokLoc, DiagId);
+    // If the token location is from a macro expansion where the macro was
+    // defined in a system header, suppress the diagnostic.
+    if (!SM.isInSystemMacro(TokLoc))
+      Diags.Report(TokLoc, DiagId);
+
     ++s;
     DigitsBegin = s;
     radix = 8;
@@ -1450,8 +1454,11 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
 
   llvm::scope_exit _([&] {
     // If we still have an octal value but we did not see an octal prefix,
-    // diagnose as being an obsolescent feature starting in C2y.
-    if (radix == 8 && LangOpts.C2y && !hadError && !IsSingleZero)
+    // diagnose as being an obsolescent feature starting in C2y. If the token
+    // location is from a macro expansion where the macro was defined in a
+    // system header, suppress the diagnostic.
+    if (radix == 8 && LangOpts.C2y && !hadError && !IsSingleZero &&
+        !SM.isInSystemMacro(TokLoc))
       Diags.Report(TokLoc, diag::warn_unprefixed_octal_deprecated);
   });
 
diff --git a/clang/test/C/C2y/n3353.c b/clang/test/C/C2y/n3353.c
index a2e08cf6344db..f396d4e6182bf 100644
--- a/clang/test/C/C2y/n3353.c
+++ b/clang/test/C/C2y/n3353.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -verify=expected,c2y,c -pedantic -std=c2y %s
-// RUN: %clang_cc1 -verify=expected,c2y,compat -Wpre-c2y-compat -std=c2y %s
-// RUN: %clang_cc1 -verify=expected,ext,c -pedantic -std=c23 %s
-// RUN: %clang_cc1 -verify=expected,cpp -pedantic -x c++ -Wno-c11-extensions %s
+// RUN: %clang_cc1 -verify=expected,c2y,c -pedantic -std=c2y -Wno-gnu-line-marker %s
+// RUN: %clang_cc1 -verify=expected,c2y,compat -Wpre-c2y-compat -std=c2y -Wno-gnu-line-marker %s
+// RUN: %clang_cc1 -verify=expected,ext,c -pedantic -std=c23 -Wno-gnu-line-marker %s
+// RUN: %clang_cc1 -verify=expected,cpp -pedantic -x c++ -Wno-c11-extensions -Wno-gnu-line-marker %s
 
 
 /* WG14 N3353: Clang 21
@@ -166,5 +166,27 @@ void foo() {
 }
 #endif
 
+#172 "system_header.c" 3
+#define SYS_HEADER_MACRO_1 0o02
+#define SYS_HEADER_MACRO_2 02
+#174 "n3353.c" 1
+
+#define USER_HEADER_MACRO_1 0o02
+#define USER_HEADER_MACRO_2 02
+
+void test_macro_behavior(void) {
+  // No diagnostic because these expanded from a macro defined in a system
+  // header.
+  int i = SYS_HEADER_MACRO_1;
+  int j = SYS_HEADER_MACRO_2;
+
+  // Diagnose other macro expansions though.
+  int a = USER_HEADER_MACRO_1; /* ext-warning {{octal integer literals are a C2y extension}}
+                                  cpp-warning {{octal integer literals are a Clang extension}}
+                                  compat-warning {{octal integer literals are incompatible with standards before C2y}}
+                                */
+  int b = USER_HEADER_MACRO_2; // c2y-warning {{octal literals without a '0o' prefix are deprecated}}
+}
+
 #line 0123  // expected-warning {{#line directive interprets number as decimal, not octal}}
 #line 0o123 // expected-error {{#line directive requires a simple digit sequence}}

>From a52081c90f2c4a18f1b3f01083d70dd3fe849a48 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Thu, 16 Apr 2026 12:18:08 -0400
Subject: [PATCH 2/3] Use .h as the extension for the header in the line marker

---
 clang/test/C/C2y/n3353.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/C/C2y/n3353.c b/clang/test/C/C2y/n3353.c
index f396d4e6182bf..10c8449124fe4 100644
--- a/clang/test/C/C2y/n3353.c
+++ b/clang/test/C/C2y/n3353.c
@@ -166,7 +166,7 @@ void foo() {
 }
 #endif
 
-#172 "system_header.c" 3
+#172 "system_header.h" 3
 #define SYS_HEADER_MACRO_1 0o02
 #define SYS_HEADER_MACRO_2 02
 #174 "n3353.c" 1

>From b46920d13a6748502d30337e19619d05b59a374d Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Thu, 16 Apr 2026 12:27:08 -0400
Subject: [PATCH 3/3] Add some more test cases

---
 clang/test/C/C2y/n3353.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/clang/test/C/C2y/n3353.c b/clang/test/C/C2y/n3353.c
index 10c8449124fe4..84620a2cb8425 100644
--- a/clang/test/C/C2y/n3353.c
+++ b/clang/test/C/C2y/n3353.c
@@ -166,19 +166,31 @@ void foo() {
 }
 #endif
 
+int other_func(int i, ...);
 #172 "system_header.h" 3
 #define SYS_HEADER_MACRO_1 0o02
 #define SYS_HEADER_MACRO_2 02
+#define SYS_HEADER_MACRO_FN1(...)  other_func(0o02, __VA_ARGS__)
+#define SYS_HEADER_MACRO_FN2(...)  other_func(2, __VA_ARGS__)
 #174 "n3353.c" 1
 
 #define USER_HEADER_MACRO_1 0o02
 #define USER_HEADER_MACRO_2 02
+#define USER_HEADER_MACRO_FN1(...)  other_func(0o02, __VA_ARGS__)
+#define USER_HEADER_MACRO_FN2(...)  other_func(2, __VA_ARGS__)
 
 void test_macro_behavior(void) {
   // No diagnostic because these expanded from a macro defined in a system
   // header.
   int i = SYS_HEADER_MACRO_1;
   int j = SYS_HEADER_MACRO_2;
+  int k = SYS_HEADER_MACRO_FN1(12);
+
+  // This one diagnoses because the literal is not in the system header.
+  int l = SYS_HEADER_MACRO_FN2(0o02); /* ext-warning {{octal integer literals are a C2y extension}}
+                                         cpp-warning {{octal integer literals are a Clang extension}}
+                                         compat-warning {{octal integer literals are incompatible with standards before C2y}}
+                                       */
 
   // Diagnose other macro expansions though.
   int a = USER_HEADER_MACRO_1; /* ext-warning {{octal integer literals are a C2y extension}}
@@ -186,6 +198,14 @@ void test_macro_behavior(void) {
                                   compat-warning {{octal integer literals are incompatible with standards before C2y}}
                                 */
   int b = USER_HEADER_MACRO_2; // c2y-warning {{octal literals without a '0o' prefix are deprecated}}
+  int c = USER_HEADER_MACRO_FN1(12); /* ext-warning {{octal integer literals are a C2y extension}}
+                                       cpp-warning {{octal integer literals are a Clang extension}}
+                                       compat-warning {{octal integer literals are incompatible with standards before C2y}}
+                                     */
+  int d = USER_HEADER_MACRO_FN2(0o02); /* ext-warning {{octal integer literals are a C2y extension}}
+                                          cpp-warning {{octal integer literals are a Clang extension}}
+                                          compat-warning {{octal integer literals are incompatible with standards before C2y}}
+                                        */
 }
 
 #line 0123  // expected-warning {{#line directive interprets number as decimal, not octal}}



More information about the cfe-commits mailing list