public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-8705] c++: ttp TEMPLATE_DECL equivalence [PR112737]
@ 2024-02-01 18:17 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2024-02-01 18:17 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3ba5be16a2be3eaedf2870ca1e25cfe826945948

commit r14-8705-g3ba5be16a2be3eaedf2870ca1e25cfe826945948
Author: Patrick Palka <ppalka@redhat.com>
Date:   Thu Feb 1 13:17:48 2024 -0500

    c++: ttp TEMPLATE_DECL equivalence [PR112737]
    
    Here during declaration matching we undesirably consider the two TT{42}
    CTAD expressions to be non-equivalent ultimately because for CTAD
    placeholder equivalence we compare the TEMPLATE_DECLs via pointer identity,
    and here the corresponding TEMPLATE_DECLs for TT are different since
    they're from different scopes.  On the other hand, the corresponding
    TEMPLATE_TEMPLATE_PARMs are deemed equivalent according to cp_tree_equal
    (since they have the same position and template parameters).  This turns
    out to be the root cause of some of the xtreme-header modules regressions.
    
    So this patch relaxes ttp CTAD placeholder equivalence accordingly, by
    comparing the TEMPLATE_TEMPLATE_PARM instead of the TEMPLATE_DECL.  It
    turns out this issue also affects function template-id equivalence as
    with g<TT> in the second testcase, so it makes sense to relax TEMPLATE_DECL
    equivalence more generally in cp_tree_equal.  In passing this patch
    improves ctp_hasher::hash for CTAD placeholders, so that they don't
    all get the same hash.
    
            PR c++/112737
    
    gcc/cp/ChangeLog:
    
            * pt.cc (iterative_hash_template_arg) <case TEMPLATE_DECL>:
            Adjust hashing to match cp_tree_equal.
            (ctp_hasher::hash): Also hash CLASS_PLACEHOLDER_TEMPLATE.
            * tree.cc (cp_tree_equal) <case TEMPLATE_DECL>: Return true
            for ttp TEMPLATE_DECLs if their TEMPLATE_TEMPLATE_PARMs are
            equivalent.
            * typeck.cc (structural_comptypes) <case TEMPLATE_TYPE_PARM>:
            Use cp_tree_equal to compare CLASS_PLACEHOLDER_TEMPLATE.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/ttp42.C: New test.
            * g++.dg/template/ttp43.C: New test.
    
    Reviewed-by: Jason Merrill <jason@redhat.com>

Diff:
---
 gcc/cp/pt.cc                          |  7 +++++++
 gcc/cp/tree.cc                        |  6 +++++-
 gcc/cp/typeck.cc                      |  4 ++--
 gcc/testsuite/g++.dg/template/ttp42.C | 14 ++++++++++++++
 gcc/testsuite/g++.dg/template/ttp43.C | 17 +++++++++++++++++
 5 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 5871cb668d0c..16febb1ba7f0 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -1816,6 +1816,11 @@ iterative_hash_template_arg (tree arg, hashval_t val)
 	}
       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);
 
@@ -4499,6 +4504,8 @@ struct ctp_hasher : ggc_ptr_hash<tree_node>
     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;
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 77f57e0f9ac6..5c8c05dc168b 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -4084,11 +4084,15 @@ cp_tree_equal (tree t1, tree t2)
 	}
       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:
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 4937022ff207..132c55cfc6d5 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -1573,8 +1573,8 @@ structural_comptypes (tree t1, tree t2, int strict)
 	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.  */
diff --git a/gcc/testsuite/g++.dg/template/ttp42.C b/gcc/testsuite/g++.dg/template/ttp42.C
new file mode 100644
index 000000000000..da08e857fc56
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp42.C
@@ -0,0 +1,14 @@
+// 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>();
+}
diff --git a/gcc/testsuite/g++.dg/template/ttp43.C b/gcc/testsuite/g++.dg/template/ttp43.C
new file mode 100644
index 000000000000..afafd321348d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp43.C
@@ -0,0 +1,17 @@
+// 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);
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-02-01 18:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-01 18:17 [gcc r14-8705] c++: ttp TEMPLATE_DECL equivalence [PR112737] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).