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
