Skip to content

[C2y] Handle FP-suffixes on prefixed octals (#141230) #141695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions clang/lib/Lex/LiteralSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have tests showing 00. , 01. 0E1 etc do not produce extension warnings?

Diags.Report(TokLoc, diag::warn_unprefixed_octal_deprecated);
});

Expand Down
31 changes: 31 additions & 0 deletions clang/test/C/C2y/n3353.c
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
Loading