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