summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-10 00:12:48 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-10 00:12:48 +0000
commite61ef62cc2a796c27d0d7d12cd171589f14ed225 (patch)
tree6bbd4691c055c7d28d2eb0ce476992f473dbda9f
parent7b40b5a24397bf996b28e9d99c014dd17a47802b (diff)
downloadbcm5719-llvm-e61ef62cc2a796c27d0d7d12cd171589f14ed225.tar.gz
bcm5719-llvm-e61ef62cc2a796c27d0d7d12cd171589f14ed225.zip
When re-entering a template scope, we may be entering a class template
partial specialization rather than a subclass of TemplateDecl. Fixes a crash in libstdc++ 4.2's <map>. llvm-svn: 81407
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp14
-rw-r--r--clang/test/SemaTemplate/nested-template.cpp10
2 files changed, 21 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8fd3a701163..b3cef85d679 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1858,11 +1858,19 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
}
void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) {
- TemplateDecl *Template = TemplateD.getAs<TemplateDecl>();
- if (!Template)
+ Decl *D = TemplateD.getAs<Decl>();
+ if (!D)
+ return;
+
+ TemplateParameterList *Params = 0;
+ if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
+ Params = Template->getTemplateParameters();
+ else if (ClassTemplatePartialSpecializationDecl *PartialSpec
+ = dyn_cast<ClassTemplatePartialSpecializationDecl>(D))
+ Params = PartialSpec->getTemplateParameters();
+ else
return;
- TemplateParameterList *Params = Template->getTemplateParameters();
for (TemplateParameterList::iterator Param = Params->begin(),
ParamEnd = Params->end();
Param != ParamEnd; ++Param) {
diff --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp
index 896eb723984..5ee2c995400 100644
--- a/clang/test/SemaTemplate/nested-template.cpp
+++ b/clang/test/SemaTemplate/nested-template.cpp
@@ -91,3 +91,13 @@ Y Outer<X>::Inner1<Y>::ReallyInner::value3 = Y();
template<typename X>
template<typename Y>
Y Outer<X>::Inner1<Y*>::ReallyInner::value4; // expected-error{{Outer<X>::Inner1<Y *>::ReallyInner::}}
+
+
+template<typename T>
+struct X0 { };
+
+template<typename T>
+struct X0<T*> {
+ template<typename U>
+ void f(U u = T()) { }
+};
OpenPOWER on IntegriCloud