aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-10-20 16:41:18 +0000
committerDouglas Gregor <dgregor@apple.com>2011-10-20 16:41:18 +0000
commit8e0c118cb6c22c448ce502f3e00d01630192f095 (patch)
tree7b9434cd8c545c72f4eeca8572e302fc888bff21
parentba4ee9a9b6e4cffc12bb6b395a58b89c189bb07e (diff)
Diagnose class template (partial) specializations that occur in the
*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
-rw-r--r--lib/Sema/SemaTemplate.cpp11
-rw-r--r--test/SemaTemplate/class-template-spec.cpp10
2 files changed, 20 insertions, 1 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 00cc9b53b6..8bfcde6092 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -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 ||
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index 07a5e2982c..8213a72635 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -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}}
+ };
+ };
+
+}