diff mbox series

c++: typename_type structural comparison

Message ID e7e900c2-8cae-28c7-cc34-cb9aa586195a@acm.org
State New
Headers show
Series c++: typename_type structural comparison | expand

Commit Message

Nathan Sidwell Dec. 2, 2020, 8:58 p.m. UTC
For modules we need to compare structurally all	the way	down.  This
means inhibiting typename_type resolution, independent of comparing
specializations.

         gcc/cp/
         * cp-tree.h (comparing_typenames): Declare.
         * pt.c (comparing_typenames): Define.
         (spec_hasher::equal): Increment it around comparisons.
         * typeck.c (structural_comptypes): Adjust TYPENAME resolution
         check.

pushing to trunk

nathan
diff mbox series

Patch

diff --git i/gcc/cp/cp-tree.h w/gcc/cp/cp-tree.h
index 3b67e7ae76a..f7a737910b6 100644
--- i/gcc/cp/cp-tree.h
+++ w/gcc/cp/cp-tree.h
@@ -5399,6 +5399,10 @@  extern int function_depth;
    in structrual_comptypes.  */
 extern int comparing_specializations;
 
+/* Nonzero if we are inside eq_specializations, which affects
+   resolving of typenames in structural_comptypes.  */
+extern int comparing_typenames;
+
 /* In parser.c.  */
 
 /* Nonzero if we are parsing an unevaluated operand: an operand to
diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
index 4fb0bc82c31..19a2ea0acd4 100644
--- i/gcc/cp/pt.c
+++ w/gcc/cp/pt.c
@@ -1702,9 +1702,11 @@  register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
   return spec;
 }
 
-/* Returns true iff two spec_entry nodes are equivalent.  */
-
+/* Restricts tree and type comparisons.  */
 int comparing_specializations;
+int comparing_typenames;
+
+/* Returns true iff two spec_entry nodes are equivalent.  */
 
 bool
 spec_hasher::equal (spec_entry *e1, spec_entry *e2)
@@ -1712,6 +1714,7 @@  spec_hasher::equal (spec_entry *e1, spec_entry *e2)
   int equal;
 
   ++comparing_specializations;
+  ++comparing_typenames;
   equal = (e1->tmpl == e2->tmpl
 	   && comp_template_args (e1->args, e2->args));
   if (equal && flag_concepts
@@ -1727,6 +1730,7 @@  spec_hasher::equal (spec_entry *e1, spec_entry *e2)
       equal = equivalent_constraints (c1, c2);
     }
   --comparing_specializations;
+  --comparing_typenames;
 
   return equal;
 }
diff --git i/gcc/cp/typeck.c w/gcc/cp/typeck.c
index 267b284ea40..6294a787b5a 100644
--- i/gcc/cp/typeck.c
+++ w/gcc/cp/typeck.c
@@ -1256,16 +1256,15 @@  structural_comptypes (tree t1, tree t2, int strict)
 
   gcc_assert (TYPE_P (t1) && TYPE_P (t2));
 
-  if (!comparing_specializations)
-    {
-      /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
-	 current instantiation.  */
-      if (TREE_CODE (t1) == TYPENAME_TYPE)
-	t1 = resolve_typename_type (t1, /*only_current_p=*/true);
-
-      if (TREE_CODE (t2) == TYPENAME_TYPE)
-	t2 = resolve_typename_type (t2, /*only_current_p=*/true);
-    }
+  /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
+     current instantiation, and we don't care about typename
+     structural equality.  The comparing_typenames check is after the
+     code check, in order to early-out the common case.  */
+  if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_typenames)
+    t1 = resolve_typename_type (t1, /*only_current_p=*/true);
+
+  if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_typenames)
+    t2 = resolve_typename_type (t2, /*only_current_p=*/true);
 
   if (TYPE_PTRMEMFUNC_P (t1))
     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);