]> granicus.if.org Git - clang/commitdiff
[Sema] Ensure an auto non-type template parameter is dependent
authorErik Pilkington <erik.pilkington@gmail.com>
Tue, 7 Aug 2018 22:59:02 +0000 (22:59 +0000)
committerErik Pilkington <erik.pilkington@gmail.com>
Tue, 7 Aug 2018 22:59:02 +0000 (22:59 +0000)
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

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

index fa002de3f5f1199d470aae92b5282a772385894d..f31f0d4957ad3997b8ab3f9a6239cb8e9edf10a0 100644 (file)
@@ -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());
index 1a84d545c647448487cbb0094e0ca162b4d6dd83..b887c7f47d3cf636d8e3d1bce0281203de287513 100644 (file)
@@ -335,3 +335,46 @@ namespace Nested {
   void g(int, int);
   using Int = A<int>::B<&g>::param2;
 }
+
+namespace rdar41852459 {
+template <auto V> struct G {};
+
+template <class T> struct S {
+  template <auto V> void f() {
+    G<V> x;
+  }
+  template <auto *PV> void f2() {
+    G<PV> x;
+  }
+  template <decltype(auto) V> void f3() {
+    G<V> x;
+  }
+};
+
+template <auto *PV> struct I {};
+
+template <class T> struct K {
+  template <auto *PV> void f() {
+    I<PV> x;
+  }
+  template <auto V> void f2() {
+    I<V> x;
+  }
+  template <decltype(auto) V> void f3() {
+    I<V> x;
+  }
+};
+
+template <decltype(auto)> struct L {};
+template <class T> struct M {
+  template <auto *PV> void f() {
+    L<PV> x;
+  }
+  template <auto V> void f() {
+    L<V> x;
+  }
+  template <decltype(auto) V> void f() {
+    L<V> x;
+  }
+};
+}