[clang] f482b96 - [C2y] Handle FP-suffixes on prefixed octals (#141230) (#141695)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 6 00:47:37 PDT 2025
Author: Naveen Seth Hanig
Date: 2025-06-06T09:47:34+02:00
New Revision: f482b9677eb8e6f1b12ec74225dfe0d3c78ec854
URL: https://github.com/llvm/llvm-project/commit/f482b9677eb8e6f1b12ec74225dfe0d3c78ec854
DIFF: https://github.com/llvm/llvm-project/commit/f482b9677eb8e6f1b12ec74225dfe0d3c78ec854.diff
LOG: [C2y] Handle FP-suffixes on prefixed octals (#141230) (#141695)
Fixes https://github.com/llvm/llvm-project/issues/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.
Added:
Modified:
clang/lib/Lex/LiteralSupport.cpp
clang/test/C/C2y/n3353.c
Removed:
################################################################################
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index 75ad977d64b24..a62508e3e27bf 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))) {
+ 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.
+ 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..cd61cbf039067 100644
--- a/clang/test/C/C2y/n3353.c
+++ b/clang/test/C/C2y/n3353.c
@@ -92,6 +92,37 @@ 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}}
+ */
+
+// 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}}
More information about the cfe-commits
mailing list