When resolving default template arguments, it should be done in the declaration context

of the template what we are going to instantiate.

Fixes various crashes of rdar://11242625 & http://llvm.org/PR11421.

llvm-svn: 155576
This commit is contained in:
Argyrios Kyrtzidis 2012-04-25 18:39:17 +00:00
parent 1ad04d95bc
commit 6fe744cc38
2 changed files with 35 additions and 0 deletions

View File

@ -2512,6 +2512,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext());
ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs,
Param->getDefaultArgumentLoc(),
Param->getDeclName());
@ -2560,6 +2561,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext());
return SemaRef.SubstExpr(Param->getDefaultArgument(), AllTemplateArgs);
}
@ -2607,6 +2609,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext());
// Substitute into the nested-name-specifier first,
QualifierLoc = Param->getDefaultArgument().getTemplateQualifierLoc();
if (QualifierLoc) {

View File

@ -292,3 +292,35 @@ namespace PR10187 {
template void f<S>(); // expected-note {{here}}
}
}
namespace rdar11242625 {
template <typename T>
struct Main {
struct default_names {
typedef int id;
};
template <typename T2 = typename default_names::id>
struct TS {
T2 q;
};
};
struct Sub : public Main<int> {
TS<> ff;
};
int arr[sizeof(Sub)];
}
namespace PR11421 {
template < unsigned > struct X {
static const unsigned dimension = 3;
template<unsigned dim=dimension>
struct Y: Y<dim> { }; // expected-error {{incomplete type}} expected-note {{is not complete until the closing}}
};
typedef X<3> X3;
X3::Y<>::iterator it; // expected-note {{requested here}}
}