[gcc/devel/c++-modules] c++: Adjust pushdecl/duplicate_decls API (merge c74e6f7cfd7)

Nathan Sidwell nathan@gcc.gnu.org
Wed Sep 30 20:27:11 GMT 2020


https://gcc.gnu.org/g:23841c9ab8477e0350afbe8c6723fd09ef64a700

commit 23841c9ab8477e0350afbe8c6723fd09ef64a700
Author: Nathan Sidwell <nathan@acm.org>
Date:   Wed Sep 30 10:40:50 2020 -0700

    c++: Adjust pushdecl/duplicate_decls API (merge c74e6f7cfd7)

Diff:
---
 ChangeLog.modules    |  3 +++
 gcc/cp/cp-tree.h     |  3 ++-
 gcc/cp/decl.c        | 66 +++++++++++++++++++++++++++----------------------
 gcc/cp/friend.c      |  8 +++---
 gcc/cp/module.cc     | 19 +++++++++++----
 gcc/cp/name-lookup.c | 69 ++++++++++++++++++++++++++++++++--------------------
 gcc/cp/name-lookup.h |  6 ++---
 gcc/cp/pt.c          | 12 ++++-----
 gcc/cp/tree.c        |  6 +++--
 9 files changed, 116 insertions(+), 76 deletions(-)

diff --git a/ChangeLog.modules b/ChangeLog.modules
index 8f18657793f..377d976b9a5 100644
--- a/ChangeLog.modules
+++ b/ChangeLog.modules
@@ -1,5 +1,8 @@
 2020-09-30  Nathan Sidwell  <nathan@acm.org>
 
+	Merge trunk c74e6f7cfd7
+	c++: Adjust pushdecl/duplicate_decls API
+
 	gcc/cp/
 	* tree.h (ovl_insert): Make usingness unsigned.
 	* tree.c (ovl_insert): Make usingness unsigned, change semantics.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index eacc459da92..501ee64af88 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6656,7 +6656,8 @@ extern void determine_local_discriminator	(tree);
 extern int decls_match				(tree, tree, bool = true);
 extern bool maybe_version_functions		(tree, tree, bool);
 extern tree duplicate_decls			(tree, tree,
-						 bool is_friend = false);
+						 bool hiding = false,
+						 bool was_hidden = false);
 extern tree declare_local_label			(tree);
 extern tree define_label			(location_t, tree);
 extern void check_goto				(tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1bb539a24f0..d4f1e8b3691 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1341,17 +1341,16 @@ check_redeclaration_no_default_args (tree decl)
 
 static void
 check_no_redeclaration_friend_default_args (tree olddecl, tree newdecl,
-					    bool olddecl_hidden_friend_p)
+					    bool olddecl_hidden_p)
 {
-  if (!olddecl_hidden_friend_p && !DECL_FRIEND_P (newdecl))
+  if (!olddecl_hidden_p && !DECL_FRIEND_P (newdecl))
     return;
 
-  tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl);
-  tree t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
-
-  for (; t1 && t1 != void_list_node;
+  for (tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl),
+	 t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
+       t1 && t1 != void_list_node;
        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
-    if ((olddecl_hidden_friend_p && TREE_PURPOSE (t1))
+    if ((olddecl_hidden_p && TREE_PURPOSE (t1))
 	|| (DECL_FRIEND_P (newdecl) && TREE_PURPOSE (t2)))
       {
 	auto_diagnostic_group d;
@@ -1435,10 +1434,14 @@ duplicate_function_template_decls (tree newdecl, tree olddecl)
    If NEWDECL is not a redeclaration of OLDDECL, NULL_TREE is
    returned.
 
-   NEWDECL_IS_FRIEND is true if NEWDECL was declared as a friend.  */
+   HIDING is true if the new decl is being hidden.  WAS_HIDDEN is true
+   if the old decl was hidden.
+
+   Hidden decls can be anticipated builtins, injected friends, or
+   (coming soon) injected from a local-extern decl.   */
 
 tree
-duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
+duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
 {
   unsigned olddecl_uid = DECL_UID (olddecl);
   int olddecl_friend = 0, types_match = 0, hidden_friend = 0;
@@ -1510,7 +1513,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	{
 	  /* Avoid warnings redeclaring built-ins which have not been
 	     explicitly declared.  */
-	  if (DECL_ANTICIPATED (olddecl))
+	  if (was_hidden)
 	    {
 	      tree t1, t2;
 
@@ -1550,7 +1553,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 			    types_match = decls_match (newdecl, olddecl);
 			    if (types_match)
 			      return duplicate_decls (newdecl, olddecl,
-						      newdecl_is_friend);
+						      hiding, was_hidden);
 			    TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs;
 			  }
 			goto next_arg;
@@ -1985,7 +1988,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 		 declaration of the function or function template in the
 		 translation unit."  */
 	      check_no_redeclaration_friend_default_args
-		(olddecl, newdecl, DECL_HIDDEN_FRIEND_P (olddecl));
+		(olddecl, newdecl, was_hidden);
 	    }
 	}
     }
@@ -2008,7 +2011,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
   if (modules_p ()
       && TREE_CODE (CP_DECL_CONTEXT (olddecl)) == NAMESPACE_DECL
       && TREE_CODE (olddecl) != NAMESPACE_DECL
-      && !newdecl_is_friend)
+      && !hiding)
     {
       if (DECL_ARTIFICIAL (olddecl))
 	{
@@ -2112,8 +2115,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	  && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
 	  /* Don't warn about extern decl followed by definition.  */
 	  && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))
-	  /* Don't warn about friends, let add_friend take care of it.  */
-	  && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl))
+	  /* Don't warn if at least one is/was hidden.  */
+	  && !(hiding || was_hidden)
 	  /* Don't warn about declaration followed by specialization.  */
 	  && (! DECL_TEMPLATE_SPECIALIZATION (newdecl)
 	      || DECL_TEMPLATE_SPECIALIZATION (olddecl)))
@@ -2171,11 +2174,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 
   if (DECL_DECLARES_FUNCTION_P (olddecl))
     {
-      olddecl_friend = DECL_FRIEND_P (olddecl);
-      olddecl_hidden_friend = DECL_HIDDEN_FRIEND_P (olddecl);
-      hidden_friend = (DECL_ANTICIPATED (olddecl)
-		       && DECL_HIDDEN_FRIEND_P (olddecl)
-		       && newdecl_is_friend);
+      olddecl_friend = DECL_FRIEND_P (STRIP_TEMPLATE (olddecl));
+      olddecl_hidden_friend = olddecl_friend && was_hidden;
+      hidden_friend = olddecl_hidden_friend && hiding;
       if (!hidden_friend)
 	{
 	  DECL_ANTICIPATED (olddecl) = 0;
@@ -4786,16 +4787,23 @@ cxx_builtin_function (tree decl)
 
   tree id = DECL_NAME (decl);
   const char *name = IDENTIFIER_POINTER (id);
+  bool hiding = false;
   if (name[0] != '_' || name[1] != '_')
-    /* In the user's namespace, it must be declared before use.  */
-    DECL_ANTICIPATED (decl) = 1;
+    {
+      /* In the user's namespace, it must be declared before use.  */
+      DECL_ANTICIPATED (decl) = 1;
+      hiding = true;
+    }
   else if (IDENTIFIER_LENGTH (id) > strlen ("___chk")
 	   && 0 != strncmp (name + 2, "builtin_", strlen ("builtin_"))
 	   && 0 == memcmp (name + IDENTIFIER_LENGTH (id) - strlen ("_chk"),
 			   "_chk", strlen ("_chk") + 1))
-    /* Treat __*_chk fortification functions as anticipated as well,
-       unless they are __builtin_*_chk.  */
-    DECL_ANTICIPATED (decl) = 1;
+    {
+      /* Treat __*_chk fortification functions as anticipated as well,
+	 unless they are __builtin_*_chk.  */
+      DECL_ANTICIPATED (decl) = 1;
+      hiding = true;
+    }
 
   /* All builtins that don't begin with an '_' should additionally
      go in the 'std' namespace.  */
@@ -4805,12 +4813,12 @@ cxx_builtin_function (tree decl)
 
       push_nested_namespace (std_node);
       DECL_CONTEXT (std_decl) = FROB_CONTEXT (std_node);
-      pushdecl (std_decl);
+      pushdecl (std_decl, hiding);
       pop_nested_namespace (std_node);
     }
 
-  DECL_CONTEXT (decl) = FROB_CONTEXT (global_namespace);
-  decl = pushdecl (decl);
+  DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+  decl = pushdecl (decl, hiding);
 
   return decl;
 }
@@ -9985,7 +9993,7 @@ grokfndecl (tree ctype,
 	  /* Attempt to merge the declarations.  This can fail, in
 	     the case of some invalid specialization declarations.  */
 	  pushed_scope = push_scope (ctype);
-	  ok = duplicate_decls (decl, old_decl, friendp);
+	  ok = duplicate_decls (decl, old_decl);
 	  if (pushed_scope)
 	    pop_scope (pushed_scope);
 	  if (!ok)
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index e9802b9e75c..f1e3d38b00d 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -611,8 +611,8 @@ do_friend (tree ctype, tree declarator, tree decl,
       if (! DECL_USE_TEMPLATE (decl))
 	{
 	  /* We must check whether the decl refers to template
-	     arguments before push_template_decl_real adds a
-	     reference to the containing template class.  */
+	     arguments before push_template_decl adds a reference to
+	     the containing template class.  */
 	  int warn = (warn_nontemplate_friend
 		      && ! funcdef_flag && ! is_friend_template
 		      && current_template_parms
@@ -627,7 +627,7 @@ do_friend (tree ctype, tree declarator, tree decl,
 	    decl = push_template_decl (decl, /*is_friend=*/true);
 	  else if (current_function_decl)
 	    /* pushdecl will check there's a local decl already.  */
-	    decl = pushdecl (decl, /*is_friend=*/true);
+	    decl = pushdecl (decl, /*hiding=*/true);
 	  else
 	    {
 	      /* We can't use pushdecl, as we might be in a template
@@ -637,7 +637,7 @@ do_friend (tree ctype, tree declarator, tree decl,
 
 	      tree ns = decl_namespace_context (decl);
 	      push_nested_namespace (ns);
-	      decl = pushdecl_namespace_level (decl, /*is_friend=*/true);
+	      decl = pushdecl_namespace_level (decl, /*hiding=*/true);
 	      pop_nested_namespace (ns);
 	    }
 
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 3316f9396e1..639ba1363a6 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -10890,11 +10890,20 @@ trees_in::is_matching_decl (tree existing, tree decl)
       // FIXME: Might be template specialization from a module, not
       // necessarily global module
     mismatch:
-      error_at (DECL_SOURCE_LOCATION (decl),
-		"conflicting global module declaration %#qD", decl);
-      inform (DECL_SOURCE_LOCATION (existing),
-	      "existing declaration %#qD", existing);
-      return false;
+      if (DECL_IS_BUILTIN (existing))
+	// FIXME: it'd be nice if we had a way of determining
+	// whether this builtin had already met a proper decl.  For
+	// now just copy the type.  Perhaps we should update
+	// SOURCE_LOCATION in those cases?
+	TREE_TYPE (existing) = TREE_TYPE (decl);
+      else
+	{
+	  error_at (DECL_SOURCE_LOCATION (decl),
+		    "conflicting global module declaration %#qD", decl);
+	  inform (DECL_SOURCE_LOCATION (existing),
+		  "existing declaration %#qD", existing);
+	  return false;
+	}
     }
 
   if (DECL_IS_BUILTIN (existing) && DECL_ANTICIPATED (existing))
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 0cac59d4a0d..ab31b191545 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2822,7 +2822,7 @@ supplement_binding_1 (cxx_binding *binding, tree decl)
 	   && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval)
 	   && !DECL_CLASS_SCOPE_P (target_decl))
     {
-      duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
+      duplicate_decls (decl, binding->value);
       ok = false;
     }
   else if (TREE_CODE (decl) == NAMESPACE_DECL
@@ -2944,7 +2944,7 @@ matching_fn_p (tree one, tree two)
 
 static tree
 update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
-		tree old, tree decl, bool is_friend)
+		tree old, tree decl, bool hiding = false)
 {
   tree to_val = decl;
   tree old_type = slot ? MAYBE_STAT_TYPE (*slot) : binding->type;
@@ -3001,13 +3001,14 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
 
 	      if (iter.using_p () && matching_fn_p (fn, decl))
 		{
+		  gcc_checking_assert (!iter.hidden_p ());
 		  /* If a function declaration in namespace scope or
 		     block scope has the same name and the same
 		     parameter-type- list (8.3.5) as a function
 		     introduced by a using-declaration, and the
 		     declarations do not declare the same function,
 		     the program is ill-formed.  [namespace.udecl]/14 */
-		  if (tree match = duplicate_decls (decl, fn, is_friend))
+		  if (tree match = duplicate_decls (decl, fn, hiding))
 		    return match;
 		  else
 		    /* FIXME: To preserve existing error behavior, we
@@ -3059,7 +3060,7 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
 	 variable, so long as they are `extern' declarations.  */
       if (!DECL_EXTERNAL (old) || !DECL_EXTERNAL (decl))
 	goto conflict;
-      else if (tree match = duplicate_decls (decl, old, false))
+      else if (tree match = duplicate_decls (decl, old))
 	return match;
       else
 	goto conflict;
@@ -3767,12 +3768,12 @@ check_module_override (tree decl, tree mvec, bool is_friend,
    says.  */
 
 static tree
-do_pushdecl (tree decl, bool is_friend)
+do_pushdecl (tree decl, bool hiding)
 {
   if (decl == error_mark_node)
     return error_mark_node;
 
-  if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl && !is_friend)
+  if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl && !hiding)
     set_decl_context_in_fn (current_function_decl, decl);
 
   /* The binding level we will be pushing into.  During local class
@@ -3793,6 +3794,14 @@ do_pushdecl (tree decl, bool is_friend)
       tree *mslot = NULL; /* Current module slot in namespace.  */
       tree old = NULL_TREE;
 
+      if (!hiding)
+	/* We should never unknownly push an anticipated decl.  */
+	gcc_checking_assert (!((TREE_CODE (decl) == TYPE_DECL
+				|| TREE_CODE (decl) == FUNCTION_DECL
+				|| TREE_CODE (decl) == TEMPLATE_DECL)
+			       && DECL_LANG_SPECIFIC (decl)
+			       && DECL_ANTICIPATED (decl)));
+
       if (level->kind == sk_namespace)
 	{
 	  /* We look in the decl's namespace for an existing
@@ -3828,7 +3837,8 @@ do_pushdecl (tree decl, bool is_friend)
       for (ovl_iterator iter (old); iter; ++iter)
 	if (iter.using_p ())
 	  ; /* Ignore using decls here.  */
-	else if (tree match = duplicate_decls (decl, *iter, is_friend))
+	else if (tree match
+		 = duplicate_decls (decl, *iter, hiding, iter.hidden_p ()))
 	  {
 	    if (match == error_mark_node)
 	      ;
@@ -3836,7 +3846,7 @@ do_pushdecl (tree decl, bool is_friend)
 	      /* The IDENTIFIER will have the type referring to the
 		 now-smashed TYPE_DECL, because ...?  Reset it.  */
 	      SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (match));
-	    else if (iter.hidden_p () && !DECL_HIDDEN_P (match))
+	    else if (iter.hidden_p () && !hiding)
 	      {
 		/* Unhiding a previously hidden decl.  */
 		tree head = iter.reveal_node (old);
@@ -3862,7 +3872,7 @@ do_pushdecl (tree decl, bool is_friend)
       /* Check for redeclaring an import.  */
       if (slot && *slot && TREE_CODE (*slot) == MODULE_VECTOR)
 	if (tree match
-	    = check_module_override (decl, *slot, is_friend, ns, name))
+	    = check_module_override (decl, *slot, hiding, ns, name))
 	  {
 	    if (match == error_mark_node)
 	      return match;
@@ -3870,7 +3880,7 @@ do_pushdecl (tree decl, bool is_friend)
 	    /* We found a decl in an interface, push it into this
 	       binding.  */
 	    decl = update_binding (NULL, binding, mslot, old,
-				   match, is_friend);
+				   match, hiding);
 
 	    if (match == decl && DECL_MODULE_EXPORT_P (decl)
 		&& !DECL_MODULE_EXPORT_P (level->this_entity))
@@ -3892,7 +3902,7 @@ do_pushdecl (tree decl, bool is_friend)
 	{
 	  check_default_args (decl);
 
-	  if (is_friend)
+	  if (hiding)
 	    {
 	      if (level->kind != sk_namespace)
 		{
@@ -3931,7 +3941,7 @@ do_pushdecl (tree decl, bool is_friend)
 	  old = MAYBE_STAT_DECL (*mslot);
 	}
 
-      old = update_binding (level, binding, mslot, old, decl, is_friend);
+      old = update_binding (level, binding, mslot, old, decl, hiding);
 
       if (old != decl)
 	/* An existing decl matched, use it.  */
@@ -3964,10 +3974,10 @@ do_pushdecl (tree decl, bool is_friend)
    we push it.  */
 
 tree
-pushdecl (tree x, bool is_friend)
+pushdecl (tree x, bool hiding)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  tree ret = do_pushdecl (x, is_friend);
+  tree ret = do_pushdecl (x, hiding);
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return ret;
 }
@@ -4907,7 +4917,7 @@ set_identifier_type_value_with_scope (tree id, tree decl, cp_binding_level *b)
     {
       tree *slot = find_namespace_slot (current_namespace, id, true);
       gcc_assert (decl);
-      update_binding (b, NULL, slot, MAYBE_STAT_DECL (*slot), decl, false);
+      update_binding (b, NULL, slot, MAYBE_STAT_DECL (*slot), decl);
 
       /* Store marker instead of real type.  */
       type = global_type_node;
@@ -4963,12 +4973,13 @@ constructor_name_p (tree name, tree type)
    closer binding level than LEVEL.  */
 
 static tree
-do_pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
+do_pushdecl_with_scope (tree x, cp_binding_level *level, bool hiding = false)
 {
   cp_binding_level *b;
 
   if (level->kind == sk_class)
     {
+      gcc_checking_assert (!hiding);
       b = class_binding_level;
       class_binding_level = level;
       pushdecl_class_level (x);
@@ -4981,7 +4992,7 @@ do_pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
 	current_function_decl = NULL_TREE;
       b = current_binding_level;
       current_binding_level = level;
-      x = pushdecl (x, is_friend);
+      x = pushdecl (x, hiding);
       current_binding_level = b;
       current_function_decl = function_decl;
     }
@@ -5001,7 +5012,7 @@ pushdecl_outermost_localscope (tree x)
        n->kind != sk_function_parms; n = b->level_chain)
     b = n;
 
-  tree ret = b ? do_pushdecl_with_scope (x, b, false) : error_mark_node;
+  tree ret = b ? do_pushdecl_with_scope (x, b) : error_mark_node;
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 
   return ret;
@@ -6248,14 +6259,13 @@ do_namespace_alias (tree alias, tree name_space)
    if appropriate.  */
 
 tree
-pushdecl_namespace_level (tree x, bool is_friend)
+pushdecl_namespace_level (tree x, bool hiding)
 {
   cp_binding_level *b = current_binding_level;
   tree t;
 
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  t = do_pushdecl_with_scope
-    (x, NAMESPACE_LEVEL (current_namespace), is_friend);
+  t = do_pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), hiding);
 
   /* Now, the type_shadowed stack may screw us.  Munge it so it does
      what we want.  */
@@ -8610,15 +8620,13 @@ finish_using_directive (tree target, tree attribs)
 /* Pushes X into the global namespace.  */
 
 tree
-pushdecl_top_level (tree x, tree *maybe_init)
+pushdecl_top_level (tree x)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   do_push_to_top_level ();
   if (!DECL_CONTEXT (x))
     DECL_CONTEXT (x) = FROB_CONTEXT (global_namespace);
-  x = pushdecl_namespace_level (x, false);
-  if (maybe_init)
-    cp_finish_decl (x, *maybe_init, false, NULL_TREE, 0);
+  x = pushdecl_namespace_level (x);
   do_pop_from_top_level ();
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return x;
@@ -8630,7 +8638,16 @@ pushdecl_top_level (tree x, tree *maybe_init)
 tree
 pushdecl_top_level_and_finish (tree x, tree init)
 {
-  return pushdecl_top_level (x, &init);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  do_push_to_top_level ();
+  if (!DECL_CONTEXT (x))
+    // FIXME: Who is pushing with no context?
+    DECL_CONTEXT (x) = FROB_CONTEXT (global_namespace);
+  x = pushdecl_namespace_level (x);
+  cp_finish_decl (x, init, false, NULL_TREE, 0);
+  do_pop_from_top_level ();
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return x;
 }
 
 /* Enter the namespaces from current_namerspace to NS.  */
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index b052ba8eb6b..7281008868d 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -377,7 +377,7 @@ extern tree lookup_qualified_name (tree scope, const char *name,
 				   bool = true);
 extern bool is_local_extern (tree);
 extern bool pushdecl_class_level (tree);
-extern tree pushdecl_namespace_level (tree, bool is_friend = false);
+extern tree pushdecl_namespace_level (tree, bool hiding = false);
 extern bool push_class_level_binding (tree, tree);
 extern tree get_local_decls ();
 extern int function_parm_depth (void);
@@ -403,9 +403,9 @@ extern void cp_emit_debug_info_for_using (tree, tree);
 
 extern void finish_nonmember_using_decl (tree scope, tree name);
 extern void finish_using_directive (tree target, tree attribs);
-extern tree pushdecl (tree, bool is_friend = false);
+extern tree pushdecl (tree, bool hiding = false);
 extern tree pushdecl_outermost_localscope (tree);
-extern tree pushdecl_top_level (tree, tree *maybe_init = NULL);
+extern tree pushdecl_top_level (tree);
 extern tree pushdecl_top_level_and_finish (tree, tree);
 extern tree pushtag (tree, tree, TAG_how = TAG_how::CURRENT_ONLY);
 extern int push_namespace (tree, bool make_inline = false);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d5de4527058..4f859e59401 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1634,7 +1634,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 		 for the specialization, we want this to look as if
 		 there were no definition, and vice versa.  */
 	      DECL_INITIAL (fn) = NULL_TREE;
-	      duplicate_decls (spec, fn, is_friend);
+	      duplicate_decls (spec, fn, /*hiding=*/is_friend);
 	      /* The call to duplicate_decls will have applied
 		 [temp.expl.spec]:
 
@@ -1661,7 +1661,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 	}
       else if (DECL_TEMPLATE_SPECIALIZATION (fn))
 	{
-	  tree dd = duplicate_decls (spec, fn, is_friend);
+	  tree dd = duplicate_decls (spec, fn, /*hiding=*/is_friend);
 	  if (dd == error_mark_node)
 	    /* We've already complained in duplicate_decls.  */
 	    return error_mark_node;
@@ -1676,7 +1676,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 	}
     }
   else if (fn)
-    return duplicate_decls (spec, fn, is_friend);
+    return duplicate_decls (spec, fn, /*hiding=*/is_friend);
 
   /* A specialization must be declared in the same namespace as the
      template it is specializing.  */
@@ -6032,7 +6032,7 @@ push_template_decl (tree decl, bool is_friend)
       if (!ctx
 	  && !(is_friend && template_class_depth (current_class_type) > 0))
 	{
-	  tmpl = pushdecl_namespace_level (tmpl, is_friend);
+	  tmpl = pushdecl_namespace_level (tmpl, /*hiding=*/is_friend);
 	  if (tmpl == error_mark_node)
 	    return error_mark_node;
 
@@ -11120,7 +11120,7 @@ tsubst_friend_function (tree decl, tree args)
 	 into the namespace of the template.  */
       ns = decl_namespace_context (new_friend);
       push_nested_namespace (ns);
-      old_decl = pushdecl_namespace_level (new_friend, /*is_friend=*/true);
+      old_decl = pushdecl_namespace_level (new_friend, /*hiding=*/true);
       pop_nested_namespace (ns);
 
       if (old_decl == error_mark_node)
@@ -11365,7 +11365,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
 	    }
 
 	  /* Inject this template into the enclosing namspace scope.  */
-	  tmpl = pushdecl_namespace_level (tmpl, true);
+	  tmpl = pushdecl_namespace_level (tmpl, /*hiding=*/true);
 	}
     }
 
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index c2816dd5321..4dbd4107393 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2323,8 +2323,10 @@ ovl_skip_hidden (tree ovl)
     {
       /* Any hidden functions should have been wrapped in an
 	 overload, but injected friend classes will not.  */
-      gcc_checking_assert (!DECL_DECLARES_FUNCTION_P (ovl));
-      ovl = NULL_TREE;
+      // FIXME: This is temporarily wrong -- consider builtin that is
+      // anticipated in current TU, but known by an import
+      if (!DECL_DECLARES_FUNCTION_P (ovl))
+	ovl = NULL_TREE;
     }
 
   return ovl;


More information about the Gcc-cvs mailing list