When re-checking an already-substituted template argument, don't lose
authorRichard Smith <richard@metafoo.co.uk>
Tue, 3 Nov 2020 22:02:56 +0000 (14:02 -0800)
committerRichard Smith <richard@metafoo.co.uk>
Tue, 3 Nov 2020 22:09:54 +0000 (14:09 -0800)
the reference-ness of the parameter's type.

clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp

index d01189b..03670e2 100644 (file)
@@ -1593,7 +1593,7 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(
   ExprResult SubstReplacement = TransformExpr(E->getReplacement());
   if (SubstReplacement.isInvalid())
     return true;
-  QualType SubstType = TransformType(E->getType());
+  QualType SubstType = TransformType(E->getParameterType(getSema().Context));
   if (SubstType.isNull())
     return true;
   // The type may have been previously dependent and not now, which means we
index 460b6de..522835f 100644 (file)
@@ -65,3 +65,15 @@ namespace PR42513 {
 
   void use() { f<X1>(); }
 }
+
+namespace ReferenceToConstexpr {
+  struct A { const char *str = "hello"; };
+  constexpr A a;
+  template<const A &r, typename T> struct B {
+    static_assert(__builtin_strcmp(r.str, "hello") == 0, "");
+  };
+  template<const A &r> struct C {
+    template<typename T> void f(B<r, T>, T) {}
+  };
+  void f(C<a> ca) { ca.f({}, 0); }
+}