aaron.ballman created this revision.
aaron.ballman added reviewers: rsmith, erichkeane, rjmccall.
aaron.ballman requested review of this revision.
Herald added a project: clang.

The parsing code for a typename requirement currently asserts when given 
something which is not a valid type-requirement 
(http://eel.is/c++draft/expr.prim.req.type#nt:type-requirement). This removes 
the assertion to continue on to the proper diagnostic.

This resolves PR53057.

Note that in that PR, it is using `_BitInt(N)` as a dependent type name. This 
patch does not attempt to support that as it is not clear that is a valid type 
requirement (it does not match the grammar production for one). The workaround 
in the PR, however, is definitely valid and works as expected.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D117560

Files:
  clang/lib/Parse/ParseExprCXX.cpp
  clang/test/Parser/cxx2a-concepts-requires-expr.cpp


Index: clang/test/Parser/cxx2a-concepts-requires-expr.cpp
===================================================================
--- clang/test/Parser/cxx2a-concepts-requires-expr.cpp
+++ clang/test/Parser/cxx2a-concepts-requires-expr.cpp
@@ -144,3 +144,18 @@
 
 bool r41 = requires { requires (); };
 // expected-error@-1 {{expected expression}}
+
+bool r42 = requires { typename long; }; // expected-error {{expected a 
qualified name after 'typename'}}
+
+template <int N>
+requires requires {
+ typename _BitInt(N); // expected-error {{expected a qualified name after 
'typename'}}
+} using r43 = void;
+
+template <int N>
+using BitInt = _BitInt(N);
+
+template <int N>
+requires requires {
+ typename BitInt<N>; // ok
+} using r44 = void;
Index: clang/lib/Parse/ParseExprCXX.cpp
===================================================================
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -3589,7 +3589,7 @@
 
           // We need to consume the typename to allow 'requires { typename a; 
}'
           SourceLocation TypenameKWLoc = ConsumeToken();
-          if (TryAnnotateCXXScopeToken()) {
+          if (TryAnnotateOptionalCXXScopeToken()) {
             TPA.Commit();
             SkipUntil(tok::semi, tok::r_brace, 
SkipUntilFlags::StopBeforeMatch);
             break;


Index: clang/test/Parser/cxx2a-concepts-requires-expr.cpp
===================================================================
--- clang/test/Parser/cxx2a-concepts-requires-expr.cpp
+++ clang/test/Parser/cxx2a-concepts-requires-expr.cpp
@@ -144,3 +144,18 @@
 
 bool r41 = requires { requires (); };
 // expected-error@-1 {{expected expression}}
+
+bool r42 = requires { typename long; }; // expected-error {{expected a qualified name after 'typename'}}
+
+template <int N>
+requires requires {
+ typename _BitInt(N); // expected-error {{expected a qualified name after 'typename'}}
+} using r43 = void;
+
+template <int N>
+using BitInt = _BitInt(N);
+
+template <int N>
+requires requires {
+ typename BitInt<N>; // ok
+} using r44 = void;
Index: clang/lib/Parse/ParseExprCXX.cpp
===================================================================
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -3589,7 +3589,7 @@
 
           // We need to consume the typename to allow 'requires { typename a; }'
           SourceLocation TypenameKWLoc = ConsumeToken();
-          if (TryAnnotateCXXScopeToken()) {
+          if (TryAnnotateOptionalCXXScopeToken()) {
             TPA.Commit();
             SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
             break;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D117560: [C++20][Con... Aaron Ballman via Phabricator via cfe-commits

Reply via email to