diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e0c603aaab6..940c43ce707 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -14384,7 +14384,16 @@ grokparms (tree parmlist, tree *parms)
 
           /* Top-level qualifiers on the parameters are
              ignored for function types.  */
-         type = cp_build_qualified_type (type, 0);
+
+         int type_quals = 0;
+         /* Inside template declaration, typename and decltype indicating
+            dependent name and cv-qualifier are preserved until
+            template instantiation.
+            PR101402/PR102033/PR102034/PR102039/PR102044 */
+         if (processing_template_decl
+               && (TREE_CODE (type) == TYPENAME_TYPE || TREE_CODE (type) == DECLTYPE_TYPE))
+                 type_quals = CP_TYPE_CONST_P(type);
+         type = cp_build_qualified_type (type, type_quals);
           if (TREE_CODE (type) == METHOD_TYPE)
             {
               error ("parameter %qD invalidly declared method type", decl);
diff --git a/gcc/testsuite/g++.dg/parse/pr101402.C b/gcc/testsuite/g++.dg/parse/pr101402.C
new file mode 100644
index 00000000000..58d9c4f8542
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr101402.C
@@ -0,0 +1,5 @@
+template<class T> struct A {
+     typedef T arr[3];
+};
+template<class T> void f(const typename A<T>::arr) { } // #1
+template void f<int>(const A<int>::arr);
diff --git a/gcc/testsuite/g++.dg/parse/pr102033.C b/gcc/testsuite/g++.dg/parse/pr102033.C
new file mode 100644
index 00000000000..0d5cc17620f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr102033.C
@@ -0,0 +1,34 @@
+/* {dg-do compile } */
+/* {dg-options "-std=c++11" } */
+
+namespace test1
+{
+template<class TA>
+struct A{
+        template<class TB>
+        using Type=TB[3];
+};
+template<class TA, class TB>
+void f(const typename A<TA>::template Type<TB>){}
+template <>
+void f<int, char>(const typename A<int>::template Type<char>){}
+}
+namespace test2
+{
+template<class TA>
+struct A{
+        template<class TB>
+        struct B{
+                using TB_Alias=TB;
+                template<class TC=TB_Alias>
+                struct C{
+                        typedef TC Arr3[3];
+                };
+        };
+};
+template<class TA, class TB>
+void f(const typename A<TA>::template B<TB>::template C<>::Arr3){}
+template <>
+void f<int, char>(const typename A<int>::template B<char>::template C<>::Arr3){}
+}
+
diff --git a/gcc/testsuite/g++.dg/parse/pr102034.C b/gcc/testsuite/g++.dg/parse/pr102034.C
new file mode 100644
index 00000000000..37fdce52912
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr102034.C
@@ -0,0 +1,13 @@
+/*{dg-do compile} */
+template<class TA>
+struct A{
+        template<class TB>
+        struct B{
+        typedef TB Arr3[3];
+        };
+};
+template<class TA, class TB>
+void f(const typename A<TA>::template B<TB>::Arr3){}
+template <>
+void f<int, char>(const typename A<int>::B<char>::Arr3){}
+
diff --git a/gcc/testsuite/g++.dg/parse/pr102039.C b/gcc/testsuite/g++.dg/parse/pr102039.C
new file mode 100644
index 00000000000..25d3e77fd74
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr102039.C
@@ -0,0 +1,24 @@
+namespace test1
+{
+struct A{
+        typedef int Arr3[3];
+};
+
+template<class T>
+void f(const typename T::Arr3){}
+
+template<>
+void f<A>(const int[3]){}
+}
+
+namespace test2
+{
+struct A{
+        typedef int Arr3[3];
+};
+template<class T>
+void f(const typename T::Arr3){}
+template<>
+void f<A>(const int*){}
+}
+
diff --git a/gcc/testsuite/g++.dg/parse/pr102044.C b/gcc/testsuite/g++.dg/parse/pr102044.C
new file mode 100644
index 00000000000..bef6a920b47
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr102044.C
@@ -0,0 +1,32 @@
+/* {dg-do compile } */
+/* {dg-options "-std=c++11" } */
+namespace test1
+{
+template<unsigned int N, class T>
+void f(const T[N]){}
+
+template<unsigned int N, class T>
+using fPtr=decltype(f<N,T>)*;
+
+template<unsigned int N, class T>
+fPtr<N,T> af[N]={&f<N,T>};
+
+template<unsigned int N, class T>
+void g(const decltype(af<N,T>)){}
+
+template<>
+void g<1,int>(const fPtr<1,int>[1]){}
+}
+
+namespace test2
+{
+template <class T>
+struct A{
+T arr3[3];
+};
+template <class T>
+void f(const decltype(A<T>::arr3)){}
+template <>
+void f<int>(const int[3]){}
+}
+
