[clang] 0233a13 - [Clang][Lex] Fix parsing of nested requirement to prevent flowing off the end of token stream (#73691)

via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 29 21:03:36 PST 2023


Author: Shafik Yaghmour
Date: 2023-11-29T21:03:32-08:00
New Revision: 0233a1306b240850cbf9f4783a20c36f967d9697

URL: https://github.com/llvm/llvm-project/commit/0233a1306b240850cbf9f4783a20c36f967d9697
DIFF: https://github.com/llvm/llvm-project/commit/0233a1306b240850cbf9f4783a20c36f967d9697.diff

LOG: [Clang][Lex] Fix parsing of nested requirement to prevent flowing off the end of token stream (#73691)

Currently when parsing a nested requirement we attempt to balance parens
if we have a parameter list. This will fail in some cases of ill-formed
code and keep going until we fall off the token stream and crash. This
fixes the hand parsing by using SkipUntil which will properly flag if we
don't find the expected tokens.

Fixes: https://github.com/llvm/llvm-project/issues/73112

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseExprCXX.cpp
    clang/test/Parser/cxx2a-concepts-requires-expr.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2ee946af32bf197..8d2b60dd75acfee 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -790,6 +790,9 @@ Bug Fixes to C++ Support
   completes (except deduction guides). Fixes:
   (`#59827 <https://github.com/llvm/llvm-project/issues/59827>`_)
 
+- Fix crash when parsing nested requirement. Fixes:
+  (`#73112 <https://github.com/llvm/llvm-project/issues/73112>`_)
+
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 - Fixed an import failure of recursive friend class template.

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 79db094e098f8e6..8b86db1bb8fc5d5 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -3635,10 +3635,12 @@ ExprResult Parser::ParseRequiresExpression() {
               auto Res = TryParseParameterDeclarationClause();
               if (Res != TPResult::False) {
                 // Skip to the closing parenthesis
-                // FIXME: Don't traverse these tokens twice (here and in
-                //  TryParseParameterDeclarationClause).
                 unsigned Depth = 1;
                 while (Depth != 0) {
+                  bool FoundParen = SkipUntil(tok::l_paren, tok::r_paren,
+                                              SkipUntilFlags::StopBeforeMatch);
+                  if (!FoundParen)
+                    break;
                   if (Tok.is(tok::l_paren))
                     Depth++;
                   else if (Tok.is(tok::r_paren))

diff  --git a/clang/test/Parser/cxx2a-concepts-requires-expr.cpp b/clang/test/Parser/cxx2a-concepts-requires-expr.cpp
index a18a54c7fad0690..971591afb08dba2 100644
--- a/clang/test/Parser/cxx2a-concepts-requires-expr.cpp
+++ b/clang/test/Parser/cxx2a-concepts-requires-expr.cpp
@@ -160,3 +160,11 @@ template <int N>
 requires requires {
  typename BitInt<N>; // ok
 } using r44 = void;
+
+namespace GH73112 {
+void f() {
+    requires { requires(int; } // expected-error {{expected ')'}} \
+                               // expected-error {{expected expression}} \
+                               // expected-note {{to match this '('}}
+}
+}


        


More information about the cfe-commits mailing list