public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-modules] Adjust duplicate checker
@ 2020-12-07 20:09 Nathan Sidwell
  0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2020-12-07 20:09 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b0db6b0b5e8b6eb23ad91f672d484162d62f6161

commit b0db6b0b5e8b6eb23ad91f672d484162d62f6161
Author: Nathan Sidwell <nathan@acm.org>
Date:   Mon Dec 7 12:09:24 2020 -0800

    Adjust duplicate checker
    
            gcc/cp/
            * cp-tree.h (comparing_typenames): Replace with ...
            (map_context_from, map_context_to): ... this.
            * typeck.c (structural_comptypes): Adjust.
            * pt.c (comparing_typenames): Delete.
            (spec_hasher::equal): Adjust.
            * tree.c (cp_tree_equal): Check map_context_from & to for failed
            parameter context.
            * module.cc (map_context_from, map_context_to): Define.
            (check_mergeable_decl): Set & unset map_context vars.
            (trees_in::is_matching_decl): Likewise.
            (module_state::read_cluster): Set & unset
            comparing_specializations, not comparing_typenames.

Diff:
---
 ChangeLog.modules | 14 ++++++++++++++
 gcc/cp/cp-tree.h  |  6 +++---
 gcc/cp/module.cc  | 57 ++++++++++++++++++++++++++++++++++++++-----------------
 gcc/cp/pt.c       |  3 ---
 gcc/cp/tree.c     |  7 ++++++-
 gcc/cp/typeck.c   |  6 +++---
 6 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/ChangeLog.modules b/ChangeLog.modules
index 80c70a73824..2647f796929 100644
--- a/ChangeLog.modules
+++ b/ChangeLog.modules
@@ -1,5 +1,19 @@
 2020-12-07  Nathan Sidwell  <nathan@acm.org>
 
+	gcc/cp/
+	* cp-tree.h (comparing_typenames): Replace with ...
+	(map_context_from, map_context_to): ... this.
+	* typeck.c (structural_comptypes): Adjust.
+	* pt.c (comparing_typenames): Delete.
+	(spec_hasher::equal): Adjust.
+	* tree.c (cp_tree_equal): Check map_context_from & to for failed
+	parameter context.
+	* module.cc (map_context_from, map_context_to): Define.
+	(check_mergeable_decl): Set & unset map_context vars.
+	(trees_in::is_matching_decl): Likewise.
+	(module_state::read_cluster): Set & unset
+	comparing_specializations, not comparing_typenames.
+
 	Merge trunk ffb268ffcf9
 	c++: Adjust array type construction
 
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3a6ab999de2..1369a0eb33d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5422,9 +5422,9 @@ 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;
+/* When comparing specializations permit context _FROM to match _TO.  */
+extern tree map_context_from;
+extern tree map_context_to;
 
 /* In parser.c.  */
 
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 5701f3f14bf..7d210747bd9 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -268,6 +268,11 @@ static inline const_tree identifier (const cpp_hashnode *node)
   return identifier (const_cast <cpp_hashnode *> (node));
 }
 
+/* During duplicate detection we need to tell some comparators that
+   these are equivalent.  */
+tree map_context_from;
+tree map_context_to;
+
 /* Id for dumping module information.  */
 int module_dump_id;
 
@@ -10600,7 +10605,8 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
 static tree
 check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
 {
-  for (ovl_iterator iter (ovl); iter; ++iter)
+  tree found = NULL_TREE;
+  for (ovl_iterator iter (ovl); !found && iter; ++iter)
     {
       tree match = *iter;
 
@@ -10613,7 +10619,7 @@ check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
 	  if (TREE_CODE (match) == NAMESPACE_DECL
 	      && !DECL_NAMESPACE_ALIAS (match))
 	    /* Namespaces are never overloaded.  */
-	    return match;
+	    found = match;
 
 	  continue;
 	}
@@ -10627,12 +10633,17 @@ check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
 	      m_inner = DECL_TEMPLATE_RESULT (m_inner);
 	      if (d_inner == error_mark_node
 		  && TYPE_DECL_ALIAS_P (m_inner))
-		return match;
+		{
+		  found = match;
+		  break;
+		}
 	      goto again;
 	    }
 	  break;
 
 	case FUNCTION_DECL:
+	  map_context_from = d_inner;
+	  map_context_to = m_inner;
 	  if (tree m_type = TREE_TYPE (m_inner))
 	    if ((!key.ret
 		 || same_type_p (key.ret, fndecl_declared_return_type (m_inner)))
@@ -10653,9 +10664,10 @@ check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
 		      m_reqs = CI_DECLARATOR_REQS (m_reqs);
 		  }
 
-		if (cp_tree_equal (m_reqs, key.constraints))
-		  return match;
+		if (cp_tree_equal (key.constraints, m_reqs))
+		  found = match;
 	      }
+	  map_context_from = map_context_to = NULL_TREE;
 	  break;
 
 	case TYPE_DECL:
@@ -10667,16 +10679,17 @@ check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
 	      else if (mk == MK_enum
 		       && (TYPE_NAME (ENUM_UNDERLYING_TYPE (TREE_TYPE (m_inner)))
 			   == key.ret))
-		return match;
+		found = match;
 	    }
 	  break;
 
 	default:
-	  return match;
+	  found = match;
+	  break;
 	}
     }
 
-  return NULL_TREE;
+  return found;
 }
 
 /* DECL, INNER & TYPE are a skeleton set of nodes for a decl.  Only
@@ -11061,7 +11074,13 @@ trees_in::is_matching_decl (tree existing, tree decl)
       gcc_checking_assert (TREE_CODE (DECL_TEMPLATE_RESULT (existing))
 			   == TREE_CODE (inner));
     }
-  
+
+  gcc_checking_assert (!map_context_from);
+  /* This mapping requres the new decl on the lhs and the existing
+     entity on the rhs of the comparitors below.  */
+  map_context_from = inner;
+  map_context_to = STRIP_TEMPLATE (existing);
+
   if (TREE_CODE (inner) == FUNCTION_DECL)
     {
       tree e_ret = fndecl_declared_return_type (existing);
@@ -11070,7 +11089,7 @@ trees_in::is_matching_decl (tree existing, tree decl)
       if (decl != inner && DECL_NAME (inner) == fun_identifier
 	  && LAMBDA_TYPE_P (DECL_CONTEXT (inner)))
 	/* This has a recursive type that will compare different.  */;
-      else if (!same_type_p (e_ret, d_ret))
+      else if (!same_type_p (d_ret, e_ret))
 	goto mismatch;
 
       tree e_type = TREE_TYPE (existing);
@@ -11087,9 +11106,9 @@ trees_in::is_matching_decl (tree existing, tree decl)
 	  if (!(e_args && d_args))
 	    goto mismatch;
 
-	  if (!same_type_p (TREE_VALUE (e_args), TREE_VALUE (d_args)))
+	  if (!same_type_p (TREE_VALUE (d_args), TREE_VALUE (e_args)))
 	    goto mismatch;
-	  
+
 	  // FIXME: Check default values
 	}
 
@@ -11122,15 +11141,16 @@ trees_in::is_matching_decl (tree existing, tree decl)
 	    }
 	}
       else if (!DEFERRED_NOEXCEPT_SPEC_P (d_spec)
-	       && !comp_except_specs (e_spec, d_spec, ce_type))
+	       && !comp_except_specs (d_spec, e_spec, ce_type))
 	goto mismatch;
     }
   /* Using cp_tree_equal because we can meet TYPE_ARGUMENT_PACKs
      here. I suspect the entities that directly do that are things
      that shouldn't go to duplicate_decls (FIELD_DECLs etc).   */
-  else if (!cp_tree_equal (TREE_TYPE (existing), TREE_TYPE (decl)))
+  else if (!cp_tree_equal (TREE_TYPE (decl), TREE_TYPE (existing)))
     {
     mismatch:
+      map_context_from = map_context_to = NULL_TREE;
       if (DECL_IS_UNDECLARED_BUILTIN (existing))
 	/* Just like duplicate_decls, presum the user knows what
 	   they're doing in overriding a builtin.   */
@@ -11147,6 +11167,8 @@ trees_in::is_matching_decl (tree existing, tree decl)
 	}
     }
 
+  map_context_from = map_context_to = NULL_TREE;
+
   if (DECL_IS_UNDECLARED_BUILTIN (existing)
       && !DECL_IS_UNDECLARED_BUILTIN (decl))
     {
@@ -14737,8 +14759,8 @@ module_state::read_cluster (unsigned snum)
   dump () && dump ("Reading section:%u", snum);
   dump.indent ();
 
-  /* We care about typename structural equality.  */
-  comparing_typenames++;
+  /* We care about structural equality.  */
+  comparing_specializations++;
 
   /* First seed the imports.  */
   while (tree import = sec.tree_node ())
@@ -14913,7 +14935,8 @@ module_state::read_cluster (unsigned snum)
 #undef cfun
   cfun = old_cfun;
   current_function_decl = old_cfd;
-  comparing_typenames--;
+  comparing_specializations--;
+
   dump.outdent ();
   dump () && dump ("Read section:%u", snum);
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4a03b93c4ed..95035905a8c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1710,7 +1710,6 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 
 /* Restricts tree and type comparisons.  */
 int comparing_specializations;
-int comparing_typenames;
 
 /* Returns true iff two spec_entry nodes are equivalent.  */
 
@@ -1720,7 +1719,6 @@ 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
@@ -1736,7 +1734,6 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2)
       equal = equivalent_constraints (c1, c2);
     }
   --comparing_specializations;
-  --comparing_typenames;
 
   return equal;
 }
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 2bc4d92f2a0..0584a7b725e 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3837,7 +3837,12 @@ cp_tree_equal (tree t1, tree t2)
 	 template.  */
 
       if (comparing_specializations
-	  && DECL_CONTEXT (t1) != DECL_CONTEXT (t2))
+	  && DECL_CONTEXT (t1) != DECL_CONTEXT (t2)
+	  /* Module duplicate checking can have t1 = new, t2 =
+	     existing, and they should be considered matching at this
+	     point.  */
+	  && (DECL_CONTEXT (t1) != map_context_from
+	      && DECL_CONTEXT (t2) != map_context_to))
 	/* When comparing hash table entries, only an exact match is
 	   good enough; we don't want to replace 'this' with the
 	   version from another function.  But be more flexible
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 5d52089ffaa..c3b94df64d9 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1252,12 +1252,12 @@ structural_comptypes (tree t1, tree t2, int strict)
 
   /* 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
+     structural equality.  The comparing_specialiations check is after the
      code check, in order to early-out the common case.  */
-  if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_typenames)
+  if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_specializations)
     t1 = resolve_typename_type (t1, /*only_current_p=*/true);
 
-  if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_typenames)
+  if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_specializations)
     t2 = resolve_typename_type (t2, /*only_current_p=*/true);
 
   if (TYPE_PTRMEMFUNC_P (t1))


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

only message in thread, other threads:[~2020-12-07 20:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-07 20:09 [gcc/devel/c++-modules] Adjust duplicate checker Nathan Sidwell

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).