diff options
author | Erick Velez <erickvelez7@gmail.com> | 2024-05-31 11:02:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-31 11:02:21 -0700 |
commit | f46d1463b835560d90ad3ac02b63c771e4ebe566 (patch) | |
tree | 7c290ca563ba79d5b33dd6e981071d8f0c1ead67 /clang/lib/Parse | |
parent | 458a31562aee703c15224dd9fcde19f67834a8f9 (diff) | |
download | llvm-f46d1463b835560d90ad3ac02b63c771e4ebe566.zip llvm-f46d1463b835560d90ad3ac02b63c771e4ebe566.tar.gz llvm-f46d1463b835560d90ad3ac02b63c771e4ebe566.tar.bz2 |
[clang] require template arg list after template kw (#80801)
Require a template argument list after an identifier prefixed by the
template keyword. Introduced by [CWG
96](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#96),
but the current wording of
[[temp.names]p5](https://eel.is/c++draft/temp.names#6) was introduced in
[P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html),
and became [temp.names]p6 somewhere else.
Fixes #53095
---------
Co-authored-by: Shafik Yaghmour <shafik.yaghmour@intel.com>
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index e149b1a..1558e3d 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -14,6 +14,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/PrettyStackTrace.h" +#include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TokenKinds.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Parse/ParseDiagnostic.h" @@ -3026,13 +3027,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, SS, ObjectType, ObjectHadErrors, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc, EnteringContext, Result, TemplateSpecified); - else if (TemplateSpecified && - Actions.ActOnTemplateName( - getCurScope(), SS, *TemplateKWLoc, Result, ObjectType, - EnteringContext, Template, - /*AllowInjectedClassName*/ true) == TNK_Non_template) - return true; + if (TemplateSpecified) { + TemplateNameKind TNK = + Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result, + ObjectType, EnteringContext, Template, + /*AllowInjectedClassName=*/true); + if (TNK == TNK_Non_template) + return true; + + // C++2c [tem.names]p6 + // A name prefixed by the keyword template shall be followed by a template + // argument list or refer to a class template or an alias template. + if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name || + TNK == TNK_Var_template) && + !Tok.is(tok::less)) + Diag(IdLoc, diag::missing_template_arg_list_after_template_kw); + } return false; } |