}
return iterative_hash_template_arg (TREE_TYPE (arg), val);
+ case TEMPLATE_DECL:
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
+ return iterative_hash_template_arg (TREE_TYPE (arg), val);
+ break;
+
case TARGET_EXPR:
return iterative_hash_template_arg (TARGET_EXPR_INITIAL (arg), val);
hashval_t val = iterative_hash_object (code, 0);
val = iterative_hash_object (TEMPLATE_TYPE_LEVEL (t), val);
val = iterative_hash_object (TEMPLATE_TYPE_IDX (t), val);
+ if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
+ val = iterative_hash_template_arg (CLASS_PLACEHOLDER_TEMPLATE (t), val);
if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
val = iterative_hash_template_arg (TYPE_TI_ARGS (t), val);
--comparing_specializations;
}
return false;
+ case TEMPLATE_DECL:
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (t1)
+ && DECL_TEMPLATE_TEMPLATE_PARM_P (t2))
+ return cp_tree_equal (TREE_TYPE (t1), TREE_TYPE (t2));
+ /* Fall through. */
case VAR_DECL:
case CONST_DECL:
case FIELD_DECL:
case FUNCTION_DECL:
- case TEMPLATE_DECL:
case IDENTIFIER_NODE:
case SSA_NAME:
case USING_DECL:
return false;
/* If T1 and T2 don't represent the same class template deduction,
they aren't equal. */
- if (CLASS_PLACEHOLDER_TEMPLATE (t1)
- != CLASS_PLACEHOLDER_TEMPLATE (t2))
+ if (!cp_tree_equal (CLASS_PLACEHOLDER_TEMPLATE (t1),
+ CLASS_PLACEHOLDER_TEMPLATE (t2)))
return false;
/* Constrained 'auto's are distinct from parms that don't have the same
constraints. */
--- /dev/null
+// PR c++/112737
+// { dg-do compile { target c++17 } }
+
+template<template<class> class TT>
+decltype(TT{42}) f(); // #1
+
+template<template<class> class TT>
+decltype(TT{42}) f(); // redeclaration of #1
+
+template<class T> struct A { A(T); };
+
+int main() {
+ f<A>();
+}
--- /dev/null
+// PR c++/112737
+// { dg-do compile { target c++11 } }
+
+template<template<class> class, class T>
+void g(T);
+
+template<template<class> class TT, class T>
+decltype(g<TT>(T{})) f(T); // #1
+
+template<template<class> class TT, class T>
+decltype(g<TT>(T{})) f(T); // redeclaration of #1
+
+template<class T> struct A;
+
+int main() {
+ f<A>(0);
+}