[llvm-branch-commits] [clang] Suppress octal literal diagnostics from system macros (#192481) (PR #192643)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Apr 17 05:15:03 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Aaron Ballman (AaronBallman)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/192643.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+6)
- (modified) clang/lib/Lex/LiteralSupport.cpp (+14-3)
- (modified) clang/test/C/C2y/n3353.c (+55-4)
``````````diff
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}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/192643
More information about the llvm-branch-commits
mailing list