]> granicus.if.org Git - clang/commitdiff
Diagnose class template (partial) specializations that occur in the
authorDouglas Gregor <dgregor@apple.com>
Thu, 20 Oct 2011 16:41:18 +0000 (16:41 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 20 Oct 2011 16:41:18 +0000 (16:41 +0000)
*wrong* class scope. This is one of the problems behind
<rdar://problem/9676205>.

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

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/class-template-spec.cpp

index 00cc9b53b6d0f7067d701ad7e21c7ec2e3afa038..8bfcde609201e773437c9ac0cfe42dda795a3b39 100644 (file)
@@ -4565,12 +4565,21 @@ static bool CheckTemplateSpecializationScope(Sema &S,
     }
   }
 
+  if (S.CurContext->isRecord() &&
+      !S.CurContext->Equals(Specialized->getDeclContext())) {
+    // Make sure that we're specializing in the right record context.
+    // Otherwise, things can go horribly wrong.
+    S.Diag(Loc, diag::err_template_spec_decl_class_scope)
+      << Specialized;
+    return true;
+  }
+  
   // C++ [temp.class.spec]p6:
   //   A class template partial specialization may be declared or redeclared
   //   in any namespace scope in which its definition may be defined (14.5.1
   //   and 14.5.2).
   bool ComplainedAboutScope = false;
-  DeclContext *SpecializedContext
+  DeclContext *SpecializedContext 
     = Specialized->getDeclContext()->getEnclosingNamespaceContext();
   DeclContext *DC = S.CurContext->getEnclosingNamespaceContext();
   if ((!PrevDecl ||
index 07a5e2982c7f502ea963e98e369c29557525c631..8213a7263590d6ad44aa3d129876018dff56bb6c 100644 (file)
@@ -109,3 +109,13 @@ Foo<int> x;
 // Template template parameters
 template<template<class T> class Wibble>
 class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}
+
+namespace rdar9676205 {
+  template<typename T>
+  struct X {
+    template<typename U>
+    struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}}
+    };
+  };
+
+}