diff options
-rw-r--r-- | lib/Sema/TreeTransform.h | 23 | ||||
-rw-r--r-- | test/SemaTemplate/issue150.cpp | 26 |
2 files changed, 48 insertions, 1 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 1a5a98a23e..94aac52e5b 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -4126,7 +4126,28 @@ template<typename Derived> QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType( TypeLocBuilder &TLB, SubstTemplateTypeParmTypeLoc TL) { - return TransformTypeSpecType(TLB, TL); + const SubstTemplateTypeParmType *T = TL.getTypePtr(); + + // Substitute into the replacement type, which itself might involve something + // that needs to be transformed. This only tends to occur with default + // template arguments of template template parameters. + TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName()); + QualType Replacement = getDerived().TransformType(T->getReplacementType()); + if (Replacement.isNull()) + return QualType(); + + // Always canonicalize the replacement type. + Replacement = SemaRef.Context.getCanonicalType(Replacement); + QualType Result + = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(), + Replacement); + + // Propagate type-source information. + SubstTemplateTypeParmTypeLoc NewTL + = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); + NewTL.setNameLoc(TL.getNameLoc()); + return Result; + } template<typename Derived> diff --git a/test/SemaTemplate/issue150.cpp b/test/SemaTemplate/issue150.cpp index 0d7930723f..2cfa8c5cb1 100644 --- a/test/SemaTemplate/issue150.cpp +++ b/test/SemaTemplate/issue150.cpp @@ -69,3 +69,29 @@ namespace MultiReplacePartial { int check0[is_same<X<int, int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1]; } + +namespace PR9016 { + template<typename > struct allocator ; + template<typename > struct less ; + + template<class T, template<class> class Compare, class Default, + template<class> class Alloc> + struct interval_set { }; + + template <class X, template<class> class = less> struct interval_type_default { + typedef X type; + }; + + template <class T, + template<class _T, template<class> class Compare = less, + class = typename interval_type_default<_T,Compare>::type, + template<class> class = allocator> class IntervalSet> + struct ZZZ + { + IntervalSet<T> IntervalSetT; + }; + + void test() { + ZZZ<int, interval_set> zzz; + } +} |