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

Conversation

naveen-seth
Copy link
Contributor

@naveen-seth naveen-seth commented May 28, 2025

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.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 28, 2025
@llvmbot
Copy link
Member

llvmbot commented May 28, 2025

@llvm/pr-subscribers-clang

Author: Naveen Seth Hanig (naveen-seth)

Changes

Fixes #141230.

Prefixed octal literals crash in combination with floating-point suffixes instead of rejecting them.
This adds proper handling to reject literals such as 0o0. or 0.0e1.

No release note because this is fixing an issue with a new change.


Full diff: https://github.com/llvm/llvm-project/pull/141695.diff

2 Files Affected:

  • (modified) clang/lib/Lex/LiteralSupport.cpp (+16-4)
  • (modified) clang/test/C/C2y/n3353.c (+22)
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}}

Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

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

Can you provide the PR that brought in the change you are fixing?

Looks like this is from: 9cf46fb

@naveen-seth naveen-seth force-pushed the fix-n3353-float-suffix branch from fd40edb to 9773316 Compare May 28, 2025 00:57
@naveen-seth
Copy link
Contributor Author

Thank you for reviewing this so quickly! I was just about to tag @AaronBallman, since this PR fixes a bug that was introduced when octal prefixes were added in #131626.

Fixes llvm#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.
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

I added @cor3ntin and @tahonermann for some extra sets of eyes, seeing as how I already messed this up once before. :-)

@naveen-seth naveen-seth requested a review from AaronBallman May 28, 2025 13:20
@naveen-seth
Copy link
Contributor Author

Ping

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

LGTM!

Comment on lines 1441 to 1443
Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM,
LangOpts),
diag::err_invalid_digit)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please extract Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, LangOpts) in a variable

}

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?

@naveen-seth naveen-seth requested a review from cor3ntin June 4, 2025 16:23
Copy link

github-actions bot commented Jun 4, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@naveen-seth
Copy link
Contributor Author

Thanks for the review.
In case the changes get approved, please also merge it on my behalf since I don't have commit access yet. Thank you!

@cor3ntin cor3ntin merged commit f482b96 into llvm:main Jun 6, 2025
11 checks passed
rorth pushed a commit to rorth/llvm-project that referenced this pull request Jun 11, 2025
Fixes llvm#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.
DhruvSrivastavaX pushed a commit to DhruvSrivastavaX/lldb-for-aix that referenced this pull request Jun 12, 2025
Fixes llvm#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.
@naveen-seth naveen-seth deleted the fix-n3353-float-suffix branch June 18, 2025 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c2y clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category crash-on-invalid
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[clang] Assertion `StatusOrErr && "Invalid floating point representation"' failed.
5 participants