Skip to content

Commit 3cb480b

Browse files
authored
[C++20] Fix crash with invalid concept requirement (#138877)
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
1 parent f9783c5 commit 3cb480b

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,8 @@ Bug Fixes to C++ Support
660660
- Fixed a crash when forming an invalid function type in a dependent context. (#GH138657) (#GH115725) (#GH68852)
661661
- No longer crashes when instantiating invalid variable template specialization
662662
whose type depends on itself. (#GH51347), (#GH55872)
663+
- Improved parser recovery of invalid requirement expressions. In turn, this
664+
fixes crashes from follow-on processing of the invalid requirement. (#GH138820)
663665

664666
Bug Fixes to AST Handling
665667
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Parse/ParseExprCXX.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3706,8 +3706,10 @@ ExprResult Parser::ParseRequiresExpression() {
37063706
SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
37073707
break;
37083708
}
3709+
// If there's an error consuming the closing bracket, consumeClose()
3710+
// will handle skipping to the nearest recovery point for us.
37093711
if (ExprBraces.consumeClose())
3710-
ExprBraces.skipToEnd();
3712+
break;
37113713

37123714
concepts::Requirement *Req = nullptr;
37133715
SourceLocation NoexceptLoc;

clang/test/SemaCXX/concept-crash-on-diagnostic.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,15 @@ concept is_foo_concept = __is_same(foo::bar, T);
4848
// expected-error@-1 {{'bar' is a private member of 'GH131530::foo'}}
4949

5050
}
51+
52+
namespace GH138820 {
53+
int a;
54+
template<typename T>
55+
concept atomicish = requires() {
56+
{ // expected-note {{to match this '{'}}
57+
a
58+
... // expected-error {{expected '}'}}
59+
};
60+
};
61+
atomicish<int> f(); // expected-error {{expected 'auto' or 'decltype(auto)' after concept name}}
62+
} // namespace GH138820

0 commit comments

Comments
 (0)