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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

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. :-)

@@ -1432,14 +1432,26 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
Diags.Report(TokLoc, DiagId);
++s;
DigitsBegin = s;
SawOctalPrefix = true;
radix = 8;
Copy link
Collaborator

Choose a reason for hiding this comment

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

There's code below which also unconditionally sets radix to 8; we should remove that and update the comments. We also seem to skip the octal digits twice (I think it's a noop to do it a second time, but it's still a code smell).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think the octal digits are skipped twice here, because the function now always returns before exiting the if-block we are currently in.

// Other suffixes will be diagnosed by the caller.
return;

This separates parsing for octals with a literal prefix from those starting with 0, so that the logic for potentially parsing a floating-point only applies to the latter (otherwise, we get this crash).
Let me know if I am missing something here!

For the radix assignment, this could be shared between both cases if we move it above the current if statement.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, you're right, I missed the unconditional return!

@naveen-seth naveen-seth requested a review from AaronBallman May 28, 2025 13:20
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.
4 participants