https://github.com/naveen-seth updated https://github.com/llvm/llvm-project/pull/141695
>From 8556e25c43fff5525501113f38dc0f3b48203f5c Mon Sep 17 00:00:00 2001 From: Naveen Seth Hanig <naveen.ha...@outlook.com> Date: Wed, 28 May 2025 02:26:54 +0200 Subject: [PATCH 1/3] [C2y] Correctly handle FP-suffixes on prefixed octals (#141230) Fixes #141230. Currently, prefixed octal literals used with floating-point suffixes are not rejected, causing Clang to crash. This adds proper handling to reject invalid literals such as `0o0.1` or `0.0e1`. No release note because this is fixing an issue with a new change. --- clang/lib/Lex/LiteralSupport.cpp | 20 ++++++++++++++++---- clang/test/C/C2y/n3353.c | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 75ad977d64b24..3b941fc4c48b8 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1420,7 +1420,7 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { } // Parse a potential octal literal prefix. - bool SawOctalPrefix = false, IsSingleZero = false; + bool IsSingleZero = false; if ((c1 == 'O' || c1 == 'o') && (s[1] >= '0' && s[1] <= '7')) { unsigned DiagId; if (LangOpts.C2y) @@ -1432,14 +1432,26 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { Diags.Report(TokLoc, DiagId); ++s; DigitsBegin = s; - SawOctalPrefix = true; + radix = 8; + s = SkipOctalDigits(s); + if (s == ThisTokEnd) { + // Done + } else if ((isHexDigit(*s) && *s != 'e' && *s != 'E' && *s != '.') && + !isValidUDSuffix(LangOpts, StringRef(s, ThisTokEnd - s))) { + Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, + LangOpts), + diag::err_invalid_digit) + << StringRef(s, 1) << 1; + hadError = true; + } + // Other suffixes will be diagnosed by the caller. + return; } auto _ = llvm::make_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 && !SawOctalPrefix && !hadError && - !IsSingleZero) + if (radix == 8 && LangOpts.C2y && !hadError && !IsSingleZero) 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 a616228f1bad0..d7d8b03501260 100644 --- a/clang/test/C/C2y/n3353.c +++ b/clang/test/C/C2y/n3353.c @@ -92,6 +92,28 @@ int o2 = 0xG; /* expected-error {{invalid suffix 'xG' on integer constant}} c2y-warning {{octal literals without a '0o' prefix are deprecated}} */ +// Show that floating-point suffixes on octal literals are rejected. +auto f1 = 0o0.; /* expected-error {{invalid suffix '.' on integer constant}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + ext-warning {{octal integer literals are a C2y extension}} + cpp-warning {{octal integer literals are a Clang extension}} + */ +auto f2 = 0o0.1; /* expected-error {{invalid suffix '.1' on integer constant}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + ext-warning {{octal integer literals are a C2y extension}} + cpp-warning {{octal integer literals are a Clang extension}} + */ +auto f3 = 0o0e1; /* expected-error {{invalid suffix 'e1' on integer constant}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + ext-warning {{octal integer literals are a C2y extension}} + cpp-warning {{octal integer literals are a Clang extension}} + */ +auto f4 = 0o0E1; /* expected-error {{invalid suffix 'E1' on integer constant}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + ext-warning {{octal integer literals are a C2y extension}} + cpp-warning {{octal integer literals are a Clang extension}} + */ + // Ensure digit separators work as expected. constexpr int p = 0o0'1'2'3'4'5'6'7; /* compat-warning {{octal integer literals are incompatible with standards before C2y}} ext-warning {{octal integer literals are a C2y extension}} >From eb486831f317f46fa19d09f5380751dff2210ee5 Mon Sep 17 00:00:00 2001 From: Naveen Seth Hanig <naveen.ha...@outlook.com> Date: Wed, 4 Jun 2025 18:09:08 +0200 Subject: [PATCH 2/3] Extract source location to variable --- clang/lib/Lex/LiteralSupport.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 3b941fc4c48b8..ad387e1c54bc5 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1438,10 +1438,8 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { // Done } else if ((isHexDigit(*s) && *s != 'e' && *s != 'E' && *s != '.') && !isValidUDSuffix(LangOpts, StringRef(s, ThisTokEnd - s))) { - Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, - LangOpts), - diag::err_invalid_digit) - << StringRef(s, 1) << 1; + auto InvalidDigitLoc = Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, LangOpts); + Diags.Report(InvalidDigitLoc, diag::err_invalid_digit) << StringRef(s, 1) << 1; hadError = true; } // Other suffixes will be diagnosed by the caller. >From b50be5df815f66912fb614742f6eaa1a9ffbe76f Mon Sep 17 00:00:00 2001 From: Naveen Seth Hanig <naveen.ha...@outlook.com> Date: Wed, 4 Jun 2025 18:10:06 +0200 Subject: [PATCH 3/3] Add tests for valid FPs with leading 0's --- clang/test/C/C2y/n3353.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/clang/test/C/C2y/n3353.c b/clang/test/C/C2y/n3353.c index d7d8b03501260..cd61cbf039067 100644 --- a/clang/test/C/C2y/n3353.c +++ b/clang/test/C/C2y/n3353.c @@ -114,6 +114,15 @@ auto f4 = 0o0E1; /* expected-error {{invalid suffix 'E1' on integer constant}} cpp-warning {{octal integer literals are a Clang extension}} */ +// Show that valid floating-point literals with a leading 0 do not produce octal-related warnings. +auto f5 = 0.; +auto f7 = 00.; +auto f8 = 01.; +auto f9 = 0e1; +auto f10 = 0E1; +auto f11 = 00e1; +auto f12 = 00E1; + // Ensure digit separators work as expected. constexpr int p = 0o0'1'2'3'4'5'6'7; /* compat-warning {{octal integer literals are incompatible with standards before C2y}} ext-warning {{octal integer literals are a C2y extension}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits