When converting a template argument representing &array to an expression for a
pointer typed template parameter, form &array rather than an array-to-pointer
decay on array.
llvm-svn: 293350
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6a53009..8f46ad0 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5830,8 +5830,9 @@
     if (RefExpr.isInvalid())
       return ExprError();
 
-    if (T->isFunctionType() || T->isArrayType()) {
-      // Decay functions and arrays.
+    if (!Context.hasSameUnqualifiedType(ParamType->getPointeeType(), T) &&
+        (T->isFunctionType() || T->isArrayType())) {
+      // Decay functions and arrays unless we're forming a pointer to array.
       RefExpr = DefaultFunctionArrayConversion(RefExpr.get());
       if (RefExpr.isInvalid())
         return ExprError();
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 5b72b8c..8658fb0 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -455,3 +455,11 @@
     X<int *, &m> y; f(y); // expected-error {{ambiguous}}
   }
 }
+
+namespace pointer_to_char_array {
+  typedef char T[4];
+  template<T *P> struct A { void f(); };
+  template<T *P> void A<P>::f() {}
+  T foo = "foo";
+  void g() { A<&foo>().f(); }
+}