Skip to content

[C++20] Fix crash with invalid concept requirement #138877

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 1 commit into from
May 7, 2025

Conversation

AaronBallman
Copy link
Collaborator

We were previously recovering a bit too hard; consumeClose() would skip to a recovery point, then we would call skipToEnd() to skip to another recovery point. Needless to say, the follow-on diagnostics were not great. But also, follow-on diagnostics were crashing due to unexpected null constraint expressions.

Now we only recover once.

Fixes #138820

We were previously recovering a bit too hard; consumeClose() would skip
to a recovery point, then we would call skipToEnd() to skip to another
recovery point. Needless to say, the follow-on diagnostics were not
great. But also, follow-on diagnostics were crashing due to unexpected
null constraint expressions.

Now we only recover once.

Fixes llvm#138820
@AaronBallman AaronBallman added c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" crash-on-invalid concepts C++20 concepts labels May 7, 2025
@llvmbot llvmbot added the clang Clang issues not falling into any other category label May 7, 2025
@llvmbot
Copy link
Member

llvmbot commented May 7, 2025

@llvm/pr-subscribers-clang

Author: Aaron Ballman (AaronBallman)

Changes

We were previously recovering a bit too hard; consumeClose() would skip to a recovery point, then we would call skipToEnd() to skip to another recovery point. Needless to say, the follow-on diagnostics were not great. But also, follow-on diagnostics were crashing due to unexpected null constraint expressions.

Now we only recover once.

Fixes #138820


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

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+2)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+3-1)
  • (modified) clang/test/SemaCXX/concept-crash-on-diagnostic.cpp (+12)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 55f774f5a672e..350244e3054cf 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -660,6 +660,8 @@ Bug Fixes to C++ Support
 - Fixed a crash when forming an invalid function type in a dependent context. (#GH138657) (#GH115725) (#GH68852)
 - No longer crashes when instantiating invalid variable template specialization
   whose type depends on itself. (#GH51347), (#GH55872)
+- Improved parser recovery of invalid requirement expressions. In turn, this
+  fixes crashes from follow-on processing of the invalid requirement. (#GH138820)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 32b08a12a3bb6..546c228a30513 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -3706,8 +3706,10 @@ ExprResult Parser::ParseRequiresExpression() {
           SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
           break;
         }
+        // If there's an error consuming the closing bracket, consumeClose()
+        // will handle skipping to the nearest recovery point for us.
         if (ExprBraces.consumeClose())
-          ExprBraces.skipToEnd();
+          break;
 
         concepts::Requirement *Req = nullptr;
         SourceLocation NoexceptLoc;
diff --git a/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp b/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
index c38f8888075de..1efed72522fef 100644
--- a/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
+++ b/clang/test/SemaCXX/concept-crash-on-diagnostic.cpp
@@ -48,3 +48,15 @@ concept is_foo_concept = __is_same(foo::bar, T);
 // expected-error@-1 {{'bar' is a private member of 'GH131530::foo'}}
 
 }
+
+namespace GH138820 {
+int a;
+template<typename T>
+concept atomicish = requires() {
+  {    // expected-note {{to match this '{'}}
+    a
+   ... // expected-error {{expected '}'}}
+  };
+};
+atomicish<int> f(); // expected-error {{expected 'auto' or 'decltype(auto)' after concept name}}
+} // namespace GH138820

Copy link
Contributor

@zyn0217 zyn0217 left a comment

Choose a reason for hiding this comment

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

Thanks!

@AaronBallman AaronBallman merged commit 3cb480b into llvm:main May 7, 2025
15 of 17 checks passed
@AaronBallman AaronBallman deleted the aballman-gh138820 branch May 7, 2025 16:39
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.

Does this also fix: #138823

@AaronBallman
Copy link
Collaborator Author

Does this also fix: #138823

I don't believe so, at least from my testing on godbolt (which should have my changes, from the git hash they have with --version).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category concepts C++20 concepts crash-on-invalid
Projects
None yet
6 participants