From: Erik Pilkington Date: Tue, 7 Aug 2018 22:59:02 +0000 (+0000) Subject: [Sema] Ensure an auto non-type template parameter is dependent X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e7a60053bd055e4869550052ea1756c7d87b5ca9;p=clang [Sema] Ensure an auto non-type template parameter is dependent The dependent auto was getting stripped away while rebuilding the template parameter type, so substitute it in. rdar://41852459 Differential revision: https://reviews.llvm.org/D50088 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@339198 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index fa002de3f5..f31f0d4957 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -974,7 +974,7 @@ NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename, QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc) { if (TSI->getType()->isUndeducedType()) { - // C++1z [temp.dep.expr]p3: + // C++17 [temp.dep.expr]p3: // An id-expression is type-dependent if it contains // - an identifier associated by name lookup with a non-type // template-parameter declared with a type that contains a @@ -9866,6 +9866,15 @@ bool Sema::RebuildTemplateParamsInCurrentInstantiation( if (!NewTSI) return true; + if (NewTSI->getType()->isUndeducedType()) { + // C++17 [temp.dep.expr]p3: + // An id-expression is type-dependent if it contains + // - an identifier associated by name lookup with a non-type + // template-parameter declared with a type that contains a + // placeholder type (7.1.7.4), + NewTSI = SubstAutoTypeSourceInfo(NewTSI, Context.DependentTy); + } + if (NewTSI != NTTP->getTypeSourceInfo()) { NTTP->setTypeSourceInfo(NewTSI); NTTP->setType(NewTSI->getType()); diff --git a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp index 1a84d545c6..b887c7f47d 100644 --- a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -335,3 +335,46 @@ namespace Nested { void g(int, int); using Int = A::B<&g>::param2; } + +namespace rdar41852459 { +template struct G {}; + +template struct S { + template void f() { + G x; + } + template void f2() { + G x; + } + template void f3() { + G x; + } +}; + +template struct I {}; + +template struct K { + template void f() { + I x; + } + template void f2() { + I x; + } + template void f3() { + I x; + } +}; + +template struct L {}; +template struct M { + template void f() { + L x; + } + template void f() { + L x; + } + template void f() { + L x; + } +}; +}