Author: Aaron Ballman
Date: 2026-04-20T07:11:39Z
New Revision: d46116b2e464e016fe793dc4c2f53562e06c0752

URL: 
https://github.com/llvm/llvm-project/commit/d46116b2e464e016fe793dc4c2f53562e06c0752
DIFF: 
https://github.com/llvm/llvm-project/commit/d46116b2e464e016fe793dc4c2f53562e06c0752.diff

LOG: Suppress octal literal diagnostics from system macros (#192481)

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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Lex/LiteralSupport.cpp
    clang/test/C/C2y/n3353.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a24d93a9de0a6..4cb709902c2df 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -513,6 +513,12 @@ Improvements to Clang's diagnostics
 - Clang now generates a fix-it for C++20 designated initializers when the 
   initializers do not match the declaration order in the structure. 
 
+- 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 c220821a0098f..3929e1dd425b1 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -1429,7 +1429,15 @@ 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.
+    // FIXME: this is actually a more general issue, for example we have a
+    // similar need for binary literals above. It would be best for this to be
+    // handled by the diagnostics engine instead of with ad hoc solutions. This
+    // same concern exists below for issuing the deprecation warning.
+    if (!SM.isInSystemMacro(TokLoc))
+      Diags.Report(TokLoc, DiagId);
+
     ++s;
     DigitsBegin = s;
     radix = 8;
@@ -1450,8 +1458,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..ad9130eeec139 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,56 @@ 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__)
+
+// Test what happens when a user macro expands to a system macro.
+#define USER_OBJECT_MACRO SYS_HEADER_MACRO_1
+#define USER_FUNCTION_MACRO() SYS_HEADER_MACRO_1
+
+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}}
+                                       */
+
+  // Neither of these diagnose because the actual octal literal tokens are
+  // defined in a system header even if there's an intervening user macro.
+  int m = USER_OBJECT_MACRO;
+  int n = USER_FUNCTION_MACRO();
+
+  // 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}}
+  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}}
 #line 0o123 // expected-error {{#line directive requires a simple digit 
sequence}}


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

Reply via email to