]> granicus.if.org Git - clang/commitdiff
Diagnose attempts to use 'using typename' with a non-identifier name,
authorDouglas Gregor <dgregor@apple.com>
Mon, 26 Sep 2011 14:30:28 +0000 (14:30 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 26 Sep 2011 14:30:28 +0000 (14:30 +0000)
from Stepan Dyatkovskiy. Fixes PR10925.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140528 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseDeclCXX.cpp
test/SemaTemplate/typename-specifier.cpp

index 0f3b998c6533cb2ff4f2548f8ffea754979c6bdc..3d577e93192a7c11387ea013a2619168dd0905ec 100644 (file)
@@ -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<
index 21cf3a1e1cfd01cba26c545ca2942c9ed11c1a16..88e93a05b735ac53ecd1361fcebc4ee9bbd6ff89 100644 (file)
@@ -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,
index 7898a20d6e17eea23e3c6cf7e9f9cbfdb2d46f3e..9eb4f33de0b95feecbfec3473a4d2d936a2596c6 100644 (file)
@@ -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}}
+  };
+}