https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102033

--- Comment #3 from qingzhe huang <nickhuang99 at hotmail dot com> ---
I can give tons of similar cases with even more complicated template levels
combined with using/typedefs/default arguments. i.e.

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){}

The fix are all can be done similarly at point to calculating function
parameter "cv-qualifier" value by passing its result into call
*cp_build_qualified_type* at  decl.c:grokparms.

for example:

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3414cbdc876..473c7b7d75c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -14493,7 +14493,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;
+         /* Top-level qualifiers are reserved for array type. PR101402 */
+         if (TREE_CODE (type) == TYPENAME_TYPE)
+         {
+            tree resolved_type = resolve_typename_type(type, false);
+            if (resolved_type && TREE_CODE(resolved_type) == ARRAY_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);



However, original *resolve_typename_type* function is not working well to cover
all cases. I only fixed one "non-recursive" case with 

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 020a4bf2f6d..1944bf4a6ea 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -27989,7 +27989,12 @@ resolve_typename_type (tree type, bool only_current_p)

   /* If we failed to resolve it, return the original typename.  */
   if (!result)
-    return type;
+  {
+         if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR
+                         && TREE_CODE (decl) == TEMPLATE_DECL)
+                 return TREE_TYPE(decl);
+         return type;
+  }

   /* If lookup found a typename type, resolve that too.  */
   if (TREE_CODE (result) == TYPENAME_TYPE && !TYPENAME_IS_RESOLVING_P
(result))



And then I give up because it requires almost a new *resolve_typename_type*
function to cover all possible cases. And I have no GCC write access and the
code is extremely difficult to maintain.

Reply via email to