2017-05-10  Nathan Sidwell  <nathan@acm.org>

	gcc/cp/
	* cp-tree.h (add_method, clone_function_decl): Change last arg to
	bool.
	* class.c (add_method): Change third arg to bool.  Adjust.
	(one_inheriting_sig, one_inherited_ctor): Adjust.
	(clone_function_decl): Change 2nd arg to bool.  Adjust.
	(clone_constructors_and_destructors): Adjust.
	* lambda.c (maybe_add_lambda_conv_op): Adjust.
	* method.c (lazily_declare_fn): Adjust.
	* pt.c (tsubst_decl, instantiate_template_1): Adjust.
	* semantics.c (finish_member_declaration): Adjust.

	libcc1/
	* libcp1plugin.cc (plugin_build_decl): Adjust add_method call.

Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 247831)
+++ gcc/cp/class.c	(working copy)
@@ -1002,12 +1002,12 @@ modify_vtable_entry (tree t,
 }
 
 
-/* Add method METHOD to class TYPE.  If USING_DECL is non-null, it is
-   the USING_DECL naming METHOD.  Returns true if the method could be
-   added to the method vec.  */
+/* Add method METHOD to class TYPE.  If VIA_USING indicates whether
+   METHOD is being injected via a using_decl.  Returns true if the
+   method could be added to the method vec.  */
 
 bool
-add_method (tree type, tree method, tree using_decl)
+add_method (tree type, tree method, bool via_using)
 {
   unsigned slot;
   tree overload;
@@ -1097,7 +1097,7 @@ add_method (tree type, tree method, tree
 
       /* Two using-declarations can coexist, we'll complain about ambiguity in
 	 overload resolution.  */
-      if (using_decl && TREE_CODE (fns) == OVERLOAD && OVL_USED (fns)
+      if (via_using && TREE_CODE (fns) == OVERLOAD && OVL_USED (fns)
 	  /* Except handle inherited constructors specially.  */
 	  && ! DECL_CONSTRUCTOR_P (fn))
 	goto cont;
@@ -1221,12 +1221,10 @@ add_method (tree type, tree method, tree
 	      /* Otherwise defer to the other function.  */
 	      return false;
 	    }
-	  if (using_decl)
-	    {
-	      if (DECL_CONTEXT (fn) == type)
-		/* Defer to the local function.  */
-		return false;
-	    }
+
+	  if (via_using)
+	    /* Defer to the local function.  */
+	    return false;
 	  else if (flag_new_inheriting_ctors
 		   && DECL_INHERITED_CTOR (fn))
 	    {
@@ -1238,13 +1236,9 @@ add_method (tree type, tree method, tree
 	    {
 	      error ("%q+#D cannot be overloaded", method);
 	      error ("with %q+#D", fn);
+	      return false;
 	    }
 
-	  /* We don't call duplicate_decls here to merge the
-	     declarations because that will confuse things if the
-	     methods have inline definitions.  In particular, we
-	     will crash while processing the definitions.  */
-	  return false;
 	}
 
     cont:
@@ -1259,7 +1253,7 @@ add_method (tree type, tree method, tree
     return false;
 
   /* Add the new binding.  */
-  if (using_decl)
+  if (via_using)
     {
       overload = ovl_cons (method, current_fns);
       OVL_USED (overload) = true;
@@ -3340,7 +3334,7 @@ one_inheriting_sig (tree t, tree ctor, t
   tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
 				   t, false, ctor, parmlist);
   gcc_assert (TYPE_MAIN_VARIANT (t) == t);
-  if (add_method (t, fn, NULL_TREE))
+  if (add_method (t, fn, false))
     {
       DECL_CHAIN (fn) = TYPE_METHODS (t);
       TYPE_METHODS (t) = fn;
@@ -3359,7 +3353,7 @@ one_inherited_ctor (tree ctor, tree t, t
     {
       ctor = implicitly_declare_fn (sfk_inheriting_constructor,
 				    t, /*const*/false, ctor, parms);
-      add_method (t, ctor, using_decl);
+      add_method (t, ctor, using_decl != NULL_TREE);
       TYPE_HAS_USER_CONSTRUCTOR (t) = true;
       return;
     }
@@ -4890,11 +4884,12 @@ decl_cloned_function_p (const_tree decl,
 }
 
 /* Produce declarations for all appropriate clones of FN.  If
-   UPDATE_METHOD_VEC_P is nonzero, the clones are added to the
-   CLASTYPE_METHOD_VEC as well.  */
+   UPDATE_METHODS is true, the clones are added to the
+   CLASTYPE_METHOD_VEC.  VIA_USING indicates whether these are cloning
+   decls brought in via using declarations (i.e. inheriting ctors).  */
 
 void
-clone_function_decl (tree fn, int update_method_vec_p)
+clone_function_decl (tree fn, bool update_methods)
 {
   tree clone;
 
@@ -4908,11 +4903,11 @@ clone_function_decl (tree fn, int update
       /* For each constructor, we need two variants: an in-charge version
 	 and a not-in-charge version.  */
       clone = build_clone (fn, complete_ctor_identifier);
-      if (update_method_vec_p)
-	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+      if (update_methods)
+	add_method (DECL_CONTEXT (clone), clone, false);
       clone = build_clone (fn, base_ctor_identifier);
-      if (update_method_vec_p)
-	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+      if (update_methods)
+	add_method (DECL_CONTEXT (clone), clone, false);
     }
   else
     {
@@ -4930,15 +4925,15 @@ clone_function_decl (tree fn, int update
       if (DECL_VIRTUAL_P (fn))
 	{
 	  clone = build_clone (fn, deleting_dtor_identifier);
-	  if (update_method_vec_p)
-	    add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+	  if (update_methods)
+	    add_method (DECL_CONTEXT (clone), clone, false);
 	}
       clone = build_clone (fn, complete_dtor_identifier);
-      if (update_method_vec_p)
-	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+      if (update_methods)
+	add_method (DECL_CONTEXT (clone), clone, false);
       clone = build_clone (fn, base_dtor_identifier);
-      if (update_method_vec_p)
-	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+      if (update_methods)
+	add_method (DECL_CONTEXT (clone), clone, false);
     }
 
   /* Note that this is an abstract function that is never emitted.  */
@@ -5041,10 +5036,12 @@ clone_constructors_and_destructors (tree
   if (!CLASSTYPE_METHOD_VEC (t))
     return;
 
+  /* While constructors can be via a using declaration, at this point
+     we no longer need to know that.  */
   for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
-    clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
+    clone_function_decl (OVL_CURRENT (fns), /*update_methods=*/true);
   for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
-    clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
+    clone_function_decl (OVL_CURRENT (fns), /*update_methods=*/true);
 }
 
 /* Deduce noexcept for a destructor DTOR.  */
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 247831)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -5722,7 +5722,7 @@ extern tree build_vfn_ref			(tree, tree)
 extern tree get_vtable_decl			(tree, int);
 extern void resort_type_method_vec		(void *, void *,
 						 gt_pointer_operator, void *);
-extern bool add_method				(tree, tree, tree);
+extern bool add_method				(tree, tree, bool);
 extern tree declared_access			(tree);
 extern tree currently_open_class		(tree);
 extern tree currently_open_derived_class	(tree);
@@ -5785,7 +5785,7 @@ extern tree missing_abi_tags			(tree);
 extern void fixup_type_variants			(tree);
 extern void fixup_attribute_variants		(tree);
 extern tree* decl_cloned_function_p		(const_tree, bool);
-extern void clone_function_decl			(tree, int);
+extern void clone_function_decl			(tree, bool);
 extern void adjust_clone_args			(tree);
 extern void deduce_noexcept_on_destructor       (tree);
 extern void insert_late_enum_def_into_classtype_sorted_fields (tree, tree);
Index: gcc/cp/lambda.c
===================================================================
--- gcc/cp/lambda.c	(revision 247831)
+++ gcc/cp/lambda.c	(working copy)
@@ -1110,7 +1110,7 @@ maybe_add_lambda_conv_op (tree type)
   if (generic_lambda_p)
     fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
 
-  add_method (type, fn, NULL_TREE);
+  add_method (type, fn, false);
 
   /* Generic thunk code fails for varargs; we'll complain in mark_used if
      the conversion op is used.  */
@@ -1156,7 +1156,7 @@ maybe_add_lambda_conv_op (tree type)
       cplus_decl_attributes (&fn, attrs, 0);
     }
 
-  add_method (type, fn, NULL_TREE);
+  add_method (type, fn, false);
 
   if (nested)
     push_function_context ();
Index: gcc/cp/method.c
===================================================================
--- gcc/cp/method.c	(revision 247831)
+++ gcc/cp/method.c	(working copy)
@@ -2359,7 +2359,7 @@ lazily_declare_fn (special_function_kind
       || sfk == sfk_copy_assignment)
     check_for_override (fn, type);
   /* Add it to CLASSTYPE_METHOD_VEC.  */
-  add_method (type, fn, NULL_TREE);
+  add_method (type, fn, false);
   /* Add it to TYPE_METHODS.  */
   if (sfk == sfk_destructor
       && DECL_VIRTUAL_P (fn))
@@ -2375,7 +2375,7 @@ lazily_declare_fn (special_function_kind
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
       || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
     /* Create appropriate clones.  */
-    clone_function_decl (fn, /*update_method_vec=*/true);
+    clone_function_decl (fn, /*update_methods=*/true);
 
   return fn;
 }
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 247831)
+++ gcc/cp/pt.c	(working copy)
@@ -12413,7 +12413,7 @@ tsubst_decl (tree t, tree args, tsubst_f
 	       If it isn't, that'll be handled by
 	       clone_constructors_and_destructors.  */
 	    if (PRIMARY_TEMPLATE_P (gen_tmpl))
-	      clone_function_decl (r, /*update_method_vec_p=*/0);
+	      clone_function_decl (r, /*update_methods=*/false);
 	  }
 	else if ((complain & tf_error) != 0
 		 && IDENTIFIER_OPNAME_P (DECL_NAME (r))
@@ -18205,7 +18205,7 @@ instantiate_template_1 (tree tmpl, tree
      by cloning the instantiation of the main entry point, not by
      instantiating the template clones.  */
   if (DECL_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (gen_tmpl)))
-    clone_function_decl (fndecl, /*update_method_vec_p=*/0);
+    clone_function_decl (fndecl, /*update_methods=*/false);
 
   if (!access_ok)
     {
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 247831)
+++ gcc/cp/semantics.c	(working copy)
@@ -3018,7 +3018,7 @@ finish_member_declaration (tree decl)
     {
       /* We also need to add this function to the
 	 CLASSTYPE_METHOD_VEC.  */
-      if (add_method (current_class_type, decl, NULL_TREE))
+      if (add_method (current_class_type, decl, false))
 	{
 	  gcc_assert (TYPE_MAIN_VARIANT (current_class_type) == current_class_type);
 	  DECL_CHAIN (decl) = TYPE_METHODS (current_class_type);
Index: libcc1/libcp1plugin.cc
===================================================================
--- libcc1/libcp1plugin.cc	(revision 247831)
+++ libcc1/libcp1plugin.cc	(working copy)
@@ -1579,7 +1579,7 @@ plugin_build_decl (cc1_plugin::connectio
 	 reversal.  */
       tree save = DECL_CHAIN (decl);
       DECL_CHAIN (decl) = NULL_TREE;
-      clone_function_decl (decl, /*update_method_vec_p=*/1);
+      clone_function_decl (decl, /*update_methods=*/true);
       gcc_assert (TYPE_METHODS (current_class_type) == decl);
       TYPE_METHODS (current_class_type)
 	= nreverse (TYPE_METHODS (current_class_type));
