aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse
diff options
context:
space:
mode:
authorErick Velez <erickvelez7@gmail.com>2024-05-31 11:02:21 -0700
committerGitHub <noreply@github.com>2024-05-31 11:02:21 -0700
commitf46d1463b835560d90ad3ac02b63c771e4ebe566 (patch)
tree7c290ca563ba79d5b33dd6e981071d8f0c1ead67 /clang/lib/Parse
parent458a31562aee703c15224dd9fcde19f67834a8f9 (diff)
downloadllvm-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.cpp23
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;
}