aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-09-26 14:30:28 +0000
committerDouglas Gregor <dgregor@apple.com>2011-09-26 14:30:28 +0000
commit480b53cfff18c40d10fcb09b0185a9b75dfd491e (patch)
tree88d1b4d0387c079893c591b84eeb984a5aac629c
parente6d1dff47d17154e99a98c499ee399df70a4bcf1 (diff)
Diagnose attempts to use 'using typename' with a non-identifier name,
from Stepan Dyatkovskiy. Fixes PR10925. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140528 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td3
-rw-r--r--lib/Parse/ParseDeclCXX.cpp9
-rw-r--r--test/SemaTemplate/typename-specifier.cpp13
3 files changed, 25 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 0f3b998c65..3d577e9319 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -225,6 +225,9 @@ def err_typename_invalid_storageclass : Error<
"type name does not allow storage class to be specified">;
def err_typename_invalid_functionspec : Error<
"type name does not allow function specifier to be specified">;
+def err_typename_identifiers_only : Error<
+ "typename is allowed for identifiers only">;
+
def err_invalid_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier">;
def err_invalid_vector_decl_spec_combination : Error<
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 21cf3a1e1c..88e93a05b7 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -545,6 +545,15 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
return 0;
}
+ // "typename" keyword is allowed for identifiers only,
+ // because it may be a type definition.
+ if (IsTypeName && Name.getKind() != UnqualifiedId::IK_Identifier) {
+ Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only)
+ << FixItHint::CreateRemoval(SourceRange(TypenameLoc));
+ // Proceed parsing, but reset the IsTypeName flag.
+ IsTypeName = false;
+ }
+
if (IsAliasDecl) {
TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
MultiTemplateParamsArg TemplateParamsArg(Actions,
diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp
index 7898a20d6e..9eb4f33de0 100644
--- a/test/SemaTemplate/typename-specifier.cpp
+++ b/test/SemaTemplate/typename-specifier.cpp
@@ -102,3 +102,16 @@ struct H {
};
G<H> struct_G;
+
+namespace PR10925 {
+ template< int mydim, typename Traits >
+ class BasicGeometry
+ {
+ typedef int some_type_t;
+ };
+
+ template<class ctype, int mydim, int coorddim>
+ class MockGeometry : BasicGeometry<mydim, int>{
+ using typename BasicGeometry<mydim, int>::operator[]; // expected-error {{typename is allowed for identifiers only}}
+ };
+}