diff mbox series

[C++] overloaded operator fns [1/N]

Message ID 40b48778-5335-2398-3dd5-e59f68b8f052@acm.org
State New
Headers show
Series [C++] overloaded operator fns [1/N] | expand

Commit Message

Nathan Sidwell Oct. 31, 2017, 12:49 p.m. UTC
This patch breaks DECL_OVERLOADED_OPERATOR_P apart into a predicate (as 
its name suggests) and DECL_OVERLOADED_OPERATOR_CODE, an accessor. I 
also add DECL_OVERLOADED_OPERATOR_IS, whose current implementation is a 
stepping stone to more a compressed operator enumeration.  Also add 
assign_op_identifier and call_op_identifier, which we use reasonably 
commonly.

I also notice that we're marking a lambda's conversion operator as an 
overloaded TYPE_EXPR.  That's weird and unnecessary, so this marks it 
simply as a conversion operator.

We're a little inconsistent in whether we check those two overloads by 
looking for identifier equivalence or examining the operator code 
enumeration.  I've not addressed that.

Applying to trunk.

nathan
diff mbox series

Patch

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

	* cp-tree.h (assign_op_identifier, call_op_identifier): Define.
	(LAMBDA_FUNCTION_P): Use DECL_OVERLOADED_OPERATOR_IS.
	(DECL_OVERLOADED_OPERATOR_P): Just retuurn true/false.
	(DECL_OVERLOADED_OPERATOR_CODE, DECL_OVERLOADED_OPERATOR_IS): Define.
	* call.c (add_function_candidate): Use
	DECL_OVERLOADED_OPERATOR_IS.
	(build_op_call_1): Use call_op_identifier &
	DECL_OVERLOADED_OPERATOR_IS.
	(build_over_call): Likewise.
	(has_trivial_copy_assign_p): Use assign_op_identifier.
	(build_special_member_call): Likewise.
	* class.c (dfs_declare_virt_assop_and_dtor): Likewise.
	(vbase_has_user_provided_move_assign,
	classtype_has_move_assign_or_move_ctor_p): Likewise.
	* decl.c (duplicate_decls): Use DECL_OVERLOADED_OPERATOR_CODE.
	(grok_special_member_properties): Use assign_op_identifier.
	(start_preparsed_function): Use DECL_OVERLOADED_OPERATOR_IS.
	* decl2.c (mark_used): Use DECL_CONV_FN_P.
	* dump.c (dump_access): Delete prototype.
	(dump_op): Delete.
	(cp_dump_tree): Don't call it.
	* lambda.c (lambda_function): Use call_op_identifier.
	(maybe_add_lambda_conv_op): Not an overloaded operator.  Remove
	unneeded braces.
	* mangle.c (write_unqualified_name): Use DECL_OVERLOADED_OPERTOR_CODE.
	* method.c (do_build_copy_assign): Use assign_op_identifier.
	(synthesize_method): Use DECL_OVERLOADED_OPERATOR_IS.
	(get_copy_assign): Use assign_op_identifier.
	(synthesized_method_walk): Likewise.
	(defaultable_fn_check): Use DECL_OVERLOADED_OPERATOR_IS.
	* parser.c (cp_parser_lambda_declarator_opt): Use
	call_op_identifier.
	* semanitics.c (classtype_has_nothrow_assign_or_copy_p): Use
	assign_op_identifier.
	* tree.c (special_function_p):  Use DECL_OVERLOADED_OPERATOR_IS.
	* typeck.c (check_return_expr): Use DECL_OVERLOADED_OPERATOR_CODE.
	(check_return_expr): Use assign_op_identifier.

Index: call.c
===================================================================
--- call.c	(revision 254243)
+++ call.c	(working copy)
@@ -2082,7 +2082,7 @@  add_function_candidate (struct z_candida
       if (DECL_CONSTRUCTOR_P (fn))
 	i = 1;
       else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
-	       && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR)
+	       && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR))
 	i = 2;
       else
 	i = 0;
@@ -4474,7 +4474,7 @@  build_op_call_1 (tree obj, vec<tree, va_
 
   if (TYPE_BINFO (type))
     {
-      fns = lookup_fnfields (TYPE_BINFO (type), cp_operator_id (CALL_EXPR), 1);
+      fns = lookup_fnfields (TYPE_BINFO (type), call_op_identifier, 1);
       if (fns == error_mark_node)
 	return error_mark_node;
     }
@@ -4557,11 +4557,9 @@  build_op_call_1 (tree obj, vec<tree, va_
             }
 	  result = error_mark_node;
 	}
-      /* Since cand->fn will be a type, not a function, for a conversion
-	 function, we must be careful not to unconditionally look at
-	 DECL_NAME here.  */
       else if (TREE_CODE (cand->fn) == FUNCTION_DECL
-	       && DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR)
+	       && DECL_OVERLOADED_OPERATOR_P (cand->fn)
+	       && DECL_OVERLOADED_OPERATOR_IS (cand->fn, CALL_EXPR))
 	result = build_over_call (cand, LOOKUP_NORMAL, complain);
       else
 	{
@@ -8116,7 +8114,8 @@  build_over_call (struct z_candidate *can
 	  return val;
 	}
     }
-  else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
+  else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
+	   && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR)
 	   && trivial_fn_p (fn)
 	   && !DECL_DELETED_FN (fn))
     {
@@ -8284,7 +8283,7 @@  first_non_public_field (tree type)
 static bool
 has_trivial_copy_assign_p (tree type, bool access, bool *hasassign)
 {
-  tree fns = get_class_binding (type, cp_assignment_operator_id (NOP_EXPR));
+  tree fns = get_class_binding (type, assign_op_identifier);
   bool all_trivial = true;
 
   /* Iterate over overloads of the assignment operator, checking
@@ -8784,8 +8783,7 @@  build_special_member_call (tree instance
   vec<tree, va_gc> *allocated = NULL;
   tree ret;
 
-  gcc_assert (IDENTIFIER_CDTOR_P (name)
-	      || name == cp_assignment_operator_id (NOP_EXPR));
+  gcc_assert (IDENTIFIER_CDTOR_P (name) || name == assign_op_identifier);
   if (TYPE_P (binfo))
     {
       /* Resolve the name.  */
@@ -8811,7 +8809,7 @@  build_special_member_call (tree instance
       if (!same_type_ignoring_top_level_qualifiers_p
 	  (TREE_TYPE (instance), BINFO_TYPE (binfo)))
 	{
-	  if (name != cp_assignment_operator_id (NOP_EXPR))
+	  if (IDENTIFIER_CDTOR_P (name))
 	    /* For constructors and destructors, either the base is
 	       non-virtual, or it is virtual but we are doing the
 	       conversion from a constructor or destructor for the
@@ -8819,10 +8817,13 @@  build_special_member_call (tree instance
 	       statically.  */
 	    instance = convert_to_base_statically (instance, binfo);
 	  else
-	    /* However, for assignment operators, we must convert
-	       dynamically if the base is virtual.  */
-	    instance = build_base_path (PLUS_EXPR, instance,
-					binfo, /*nonnull=*/1, complain);
+	    {
+	      /* However, for assignment operators, we must convert
+		 dynamically if the base is virtual.  */
+	      gcc_checking_assert (name == assign_op_identifier);
+	      instance = build_base_path (PLUS_EXPR, instance,
+					  binfo, /*nonnull=*/1, complain);
+	    }
 	}
     }
 
Index: class.c
===================================================================
--- class.c	(revision 254243)
+++ class.c	(working copy)
@@ -3011,7 +3011,7 @@  static tree
 dfs_declare_virt_assop_and_dtor (tree binfo, void *data)
 {
   tree bv, fn, t = (tree)data;
-  tree opname = cp_assignment_operator_id (NOP_EXPR);
+  tree opname = assign_op_identifier;
 
   gcc_assert (t && CLASS_TYPE_P (t));
   gcc_assert (binfo && TREE_CODE (binfo) == TREE_BINFO);
@@ -5038,7 +5038,7 @@  vbase_has_user_provided_move_assign (tre
   /* Does the type itself have a user-provided move assignment operator?  */
   if (!CLASSTYPE_LAZY_MOVE_ASSIGN (type))
     for (ovl_iterator iter (get_class_binding_direct
-			    (type, cp_assignment_operator_id (NOP_EXPR)));
+			    (type, assign_op_identifier));
 	 iter; ++iter)
       if (!DECL_ARTIFICIAL (*iter) && move_fn_p (*iter))
 	return true;
@@ -5186,7 +5186,7 @@  classtype_has_move_assign_or_move_ctor_p
 
   if (!CLASSTYPE_LAZY_MOVE_ASSIGN (t))
     for (ovl_iterator iter (get_class_binding_direct
-			    (t, cp_assignment_operator_id (NOP_EXPR)));
+			    (t, assign_op_identifier));
 	 iter; ++iter)
       if ((!user_p || !DECL_ARTIFICIAL (*iter)) && move_fn_p (*iter))
 	return true;
Index: cp-tree.h
===================================================================
--- cp-tree.h	(revision 254243)
+++ cp-tree.h	(working copy)
@@ -217,7 +217,7 @@  extern GTY(()) tree cp_global_trees[CPTI
    things) to iterate over their overloads defined by/for a type.  For
    example:
 
-     tree ovlid = cp_assignment_operator_id (NOP_EXPR);
+     tree ovlid = assign_op_identifier;
      tree overloads = get_class_binding (type, ovlid);
      for (ovl_iterator it (overloads); it; ++it) { ... }
 
@@ -244,6 +244,9 @@  extern GTY(()) tree cp_global_trees[CPTI
 /* The name of a destructor that destroys virtual base classes, and
    then deletes the entire object.  */
 #define deleting_dtor_identifier	cp_global_trees[CPTI_DELETING_DTOR_IDENTIFIER]
+
+#define assign_op_identifier (cp_assignment_operator_id (NOP_EXPR))
+#define call_op_identifier (cp_operator_id (CALL_EXPR))
 /* The name used for conversion operators -- but note that actual
    conversion functions use special identifiers outside the identifier
    table.  */
@@ -1203,9 +1206,10 @@  struct GTY (()) tree_trait_expr {
   (CLASS_TYPE_P (NODE) && CLASSTYPE_LAMBDA_EXPR (NODE))
 
 /* Test if FUNCTION_DECL is a lambda function.  */
-#define LAMBDA_FUNCTION_P(FNDECL)			\
-  (DECL_DECLARES_FUNCTION_P (FNDECL)			\
-   && DECL_OVERLOADED_OPERATOR_P (FNDECL) == CALL_EXPR	\
+#define LAMBDA_FUNCTION_P(FNDECL)				\
+  (DECL_DECLARES_FUNCTION_P (FNDECL)				\
+   && DECL_OVERLOADED_OPERATOR_P (FNDECL)			\
+   && DECL_OVERLOADED_OPERATOR_IS (FNDECL, CALL_EXPR)		\
    && LAMBDA_TYPE_P (CP_DECL_CONTEXT (FNDECL)))
 
 enum cp_lambda_default_capture_mode_type {
@@ -2810,19 +2814,24 @@  struct GTY(()) lang_decl {
 #define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \
   (LANG_DECL_FN_CHECK (NODE)->operator_code = (CODE))
 
-/* If NODE is an overloaded operator, then this returns the TREE_CODE
-   associated with the overloaded operator.  If NODE is not an
-   overloaded operator, ERROR_MARK is returned.  Since the numerical
-   value of ERROR_MARK is zero, this macro can be used as a predicate
-   to test whether or not NODE is an overloaded operator.  */
+/* True iff decl NODE is for an overloaded operator.  */
 #define DECL_OVERLOADED_OPERATOR_P(NODE)		\
-  (IDENTIFIER_ANY_OP_P (DECL_NAME (NODE))		\
-   ? LANG_DECL_FN_CHECK (NODE)->operator_code : ERROR_MARK)
+  IDENTIFIER_ANY_OP_P (DECL_NAME (NODE))
 
 /* Nonzero if NODE is an assignment operator (including += and such).  */
-#define DECL_ASSIGNMENT_OPERATOR_P(NODE) \
+#define DECL_ASSIGNMENT_OPERATOR_P(NODE)		 \
   IDENTIFIER_ASSIGN_OP_P (DECL_NAME (NODE))
 
+/* NODE is a function_decl for an overloaded operator.  Return its
+   operator code.   */
+#define DECL_OVERLOADED_OPERATOR_CODE(NODE)			\
+  (LANG_DECL_FN_CHECK (NODE)->operator_code)
+
+/* DECL is an overloaded operator.  Test whether it is for TREE_CODE
+   (a literal constant).  */
+#define DECL_OVERLOADED_OPERATOR_IS(DECL, CODE)			\
+  (DECL_OVERLOADED_OPERATOR_CODE (DECL) == CODE)
+
 /* For FUNCTION_DECLs: nonzero means that this function is a
    constructor or a destructor with an extra in-charge parameter to
    control whether or not virtual bases are constructed.  */
Index: decl.c
===================================================================
--- decl.c	(revision 254243)
+++ decl.c	(working copy)
@@ -1921,9 +1921,9 @@  next_arg:;
       DECL_FINAL_P (newdecl) |= DECL_FINAL_P (olddecl);
       DECL_OVERRIDE_P (newdecl) |= DECL_OVERRIDE_P (olddecl);
       DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
-      if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
+      if (DECL_OVERLOADED_OPERATOR_P (olddecl))
 	SET_OVERLOADED_OPERATOR_CODE
-	  (newdecl, DECL_OVERLOADED_OPERATOR_P (olddecl));
+	  (newdecl, DECL_OVERLOADED_OPERATOR_CODE (olddecl));
       new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
 
       /* Optionally warn about more than one declaration for the same
@@ -12816,7 +12816,7 @@  grok_special_member_properties (tree dec
 	  && !ctor && !move_fn_p (decl))
 	TYPE_HAS_CONSTEXPR_CTOR (class_type) = 1;
     }
-  else if (DECL_NAME (decl) == cp_assignment_operator_id (NOP_EXPR))
+  else if (DECL_NAME (decl) == assign_op_identifier)
     {
       /* [class.copy]
 
@@ -14769,9 +14769,11 @@  start_preparsed_function (tree decl1, tr
 
   /* Effective C++ rule 15.  */
   if (warn_ecpp
-      && DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR
+      && DECL_ASSIGNMENT_OPERATOR_P (decl1)
+      && DECL_OVERLOADED_OPERATOR_IS (decl1, NOP_EXPR)
       && VOID_TYPE_P (TREE_TYPE (fntype)))
-    warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>");
+    warning (OPT_Weffc__,
+	     "%<operator=%> should return a reference to %<*this%>");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
      error_mark_node is replaced below (in poplevel) with the BLOCK.  */
Index: decl2.c
===================================================================
--- decl2.c	(revision 254243)
+++ decl2.c	(working copy)
@@ -5101,11 +5101,11 @@  mark_used (tree decl, tsubst_flags_t com
       && DECL_DELETED_FN (decl))
     {
       if (DECL_ARTIFICIAL (decl)
-	  && DECL_OVERLOADED_OPERATOR_P (decl) == TYPE_EXPR
+	  && DECL_CONV_FN_P (decl)
 	  && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
 	/* We mark a lambda conversion op as deleted if we can't
 	   generate it properly; see maybe_add_lambda_conv_op.  */
-	sorry ("converting lambda which uses %<...%> to function pointer");
+	sorry ("converting lambda that uses %<...%> to function pointer");
       else if (complain & tf_error)
 	{
 	  error ("use of deleted function %qD", decl);
Index: dump.c
===================================================================
--- dump.c	(revision 254243)
+++ dump.c	(working copy)
@@ -24,10 +24,6 @@  along with GCC; see the file COPYING3.
 #include "cp-tree.h"
 #include "tree-dump.h"
 
-static void dump_access (dump_info_p, tree);
-
-static void dump_op (dump_info_p, tree);
-
 /* Dump a representation of the accessibility information associated
    with T.  */
 
@@ -42,163 +38,6 @@  dump_access (dump_info_p di, tree t)
     dump_string_field (di, "accs", "pub");
 }
 
-/* Dump a representation of the specific operator for an overloaded
-   operator associated with node t.  */
-
-static void
-dump_op (dump_info_p di, tree t)
-{
-  switch (DECL_OVERLOADED_OPERATOR_P (t)) {
-    case NEW_EXPR:
-      dump_string (di, "new");
-      break;
-    case VEC_NEW_EXPR:
-      dump_string (di, "vecnew");
-      break;
-    case DELETE_EXPR:
-      dump_string (di, "delete");
-      break;
-    case VEC_DELETE_EXPR:
-      dump_string (di, "vecdelete");
-      break;
-    case UNARY_PLUS_EXPR:
-      dump_string (di, "pos");
-      break;
-    case NEGATE_EXPR:
-      dump_string (di, "neg");
-      break;
-    case ADDR_EXPR:
-      dump_string (di, "addr");
-      break;
-    case INDIRECT_REF:
-      dump_string(di, "deref");
-      break;
-    case BIT_NOT_EXPR:
-      dump_string(di, "not");
-      break;
-    case TRUTH_NOT_EXPR:
-      dump_string(di, "lnot");
-      break;
-    case PREINCREMENT_EXPR:
-      dump_string(di, "preinc");
-      break;
-    case PREDECREMENT_EXPR:
-      dump_string(di, "predec");
-      break;
-    case PLUS_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "plusassign");
-      else
-	dump_string(di, "plus");
-      break;
-    case MINUS_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "minusassign");
-      else
-	dump_string(di, "minus");
-      break;
-    case MULT_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "multassign");
-      else
-	dump_string (di, "mult");
-      break;
-    case TRUNC_DIV_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "divassign");
-      else
-	dump_string (di, "div");
-      break;
-    case TRUNC_MOD_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	 dump_string (di, "modassign");
-      else
-	dump_string (di, "mod");
-      break;
-    case BIT_AND_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "andassign");
-      else
-	dump_string (di, "and");
-      break;
-    case BIT_IOR_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "orassign");
-      else
-	dump_string (di, "or");
-      break;
-    case BIT_XOR_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "xorassign");
-      else
-	dump_string (di, "xor");
-      break;
-    case LSHIFT_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "lshiftassign");
-      else
-	dump_string (di, "lshift");
-      break;
-    case RSHIFT_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "rshiftassign");
-      else
-	dump_string (di, "rshift");
-      break;
-    case EQ_EXPR:
-      dump_string (di, "eq");
-      break;
-    case NE_EXPR:
-      dump_string (di, "ne");
-      break;
-    case LT_EXPR:
-      dump_string (di, "lt");
-      break;
-    case GT_EXPR:
-      dump_string (di, "gt");
-      break;
-    case LE_EXPR:
-      dump_string (di, "le");
-      break;
-    case GE_EXPR:
-      dump_string (di, "ge");
-      break;
-    case TRUTH_ANDIF_EXPR:
-      dump_string (di, "land");
-      break;
-    case TRUTH_ORIF_EXPR:
-      dump_string (di, "lor");
-      break;
-    case COMPOUND_EXPR:
-      dump_string (di, "compound");
-      break;
-    case MEMBER_REF:
-      dump_string (di, "memref");
-      break;
-    case COMPONENT_REF:
-      dump_string (di, "ref");
-      break;
-    case ARRAY_REF:
-      dump_string (di, "subs");
-      break;
-    case POSTINCREMENT_EXPR:
-      dump_string (di, "postinc");
-      break;
-    case POSTDECREMENT_EXPR:
-      dump_string (di, "postdec");
-      break;
-    case CALL_EXPR:
-      dump_string (di, "call");
-      break;
-    case NOP_EXPR:
-      if (DECL_ASSIGNMENT_OPERATOR_P (t))
-	dump_string (di, "assign");
-      break;
-    default:
-      break;
-  }
-}
-
 /* Dump information common to statements from STMT.  */
 
 static void
@@ -303,10 +142,8 @@  cp_dump_tree (void* dump_info, tree t)
     case FUNCTION_DECL:
       if (!DECL_THUNK_P (t))
 	{
-	  if (DECL_OVERLOADED_OPERATOR_P (t)) {
+	  if (DECL_OVERLOADED_OPERATOR_P (t))
 	    dump_string_field (di, "note", "operator");
-	    dump_op (di, t);
-	  }
 	  if (DECL_FUNCTION_MEMBER_P (t))
 	    {
 	      dump_string_field (di, "note", "member");
Index: lambda.c
===================================================================
--- lambda.c	(revision 254243)
+++ lambda.c	(working copy)
@@ -201,7 +201,7 @@  lambda_function (tree lambda)
   if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
       && !COMPLETE_OR_OPEN_TYPE_P (type))
     return NULL_TREE;
-  lambda = lookup_member (type, cp_operator_id (CALL_EXPR),
+  lambda = lookup_member (type, call_op_identifier,
 			  /*protect=*/0, /*want_type=*/false,
 			  tf_warning_or_error);
   if (lambda)
@@ -1258,7 +1258,6 @@  maybe_add_lambda_conv_op (tree type)
   tree fn = convfn;
   DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
   SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
-  SET_OVERLOADED_OPERATOR_CODE (fn, TYPE_EXPR);
   grokclassfn (type, fn, NO_SPECIAL);
   set_linkage_according_to_type (type, fn);
   rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
@@ -1312,11 +1311,9 @@  maybe_add_lambda_conv_op (tree type)
     fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
 
   if (flag_sanitize & SANITIZE_NULL)
-    {
-      /* Don't UBsan this function; we're deliberately calling op() with a null
-	 object argument.  */
-      add_no_sanitize_value (fn, SANITIZE_UNDEFINED);
-    }
+    /* Don't UBsan this function; we're deliberately calling op() with a null
+       object argument.  */
+    add_no_sanitize_value (fn, SANITIZE_UNDEFINED);
 
   add_method (type, fn, false);
 
Index: mangle.c
===================================================================
--- mangle.c	(revision 254243)
+++ mangle.c	(working copy)
@@ -1351,7 +1351,7 @@  write_unqualified_name (tree decl)
 	  else
 	    oni = operator_name_info;
 
-	  write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
+	  write_string (oni[DECL_OVERLOADED_OPERATOR_CODE (decl)].mangled_name);
 	}
       else if (UDLIT_OPER_P (DECL_NAME (decl)))
 	write_literal_operator_name (DECL_NAME (decl));
Index: method.c
===================================================================
--- method.c	(revision 254243)
+++ method.c	(working copy)
@@ -815,7 +815,7 @@  do_build_copy_assign (tree fndecl)
 	  parmvec = make_tree_vector_single (converted_parm);
 	  finish_expr_stmt
 	    (build_special_member_call (current_class_ref,
-					cp_assignment_operator_id (NOP_EXPR),
+					assign_op_identifier,
 					&parmvec,
 					base_binfo,
 					flags,
@@ -929,7 +929,8 @@  synthesize_method (tree fndecl)
   start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
   stmt = begin_function_body ();
 
-  if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
+  if (DECL_ASSIGNMENT_OPERATOR_P (fndecl)
+      && DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR))
     {
       do_build_copy_assign (fndecl);
       need_body = false;
@@ -1108,7 +1109,7 @@  get_copy_assign (tree type)
   int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type)
 	       ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
   tree argtype = build_stub_type (type, quals, false);
-  tree fn = locate_fn_flags (type, cp_assignment_operator_id (NOP_EXPR), argtype,
+  tree fn = locate_fn_flags (type, assign_op_identifier, argtype,
 			     LOOKUP_NORMAL, tf_warning_or_error);
   if (fn == error_mark_node)
     return NULL_TREE;
@@ -1565,7 +1566,7 @@  synthesized_method_walk (tree ctype, spe
     case sfk_move_assignment:
     case sfk_copy_assignment:
       assign_p = true;
-      fnname = cp_assignment_operator_id (NOP_EXPR);
+      fnname = assign_op_identifier;
       break;
 
     case sfk_destructor:
@@ -2318,7 +2319,7 @@  defaultable_fn_check (tree fn)
   else if (DECL_DESTRUCTOR_P (fn))
     kind = sfk_destructor;
   else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
-	   && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR)
+	   && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR))
     {
       if (copy_fn_p (fn))
 	kind = sfk_copy_assignment;
Index: parser.c
===================================================================
--- parser.c	(revision 254243)
+++ parser.c	(working copy)
@@ -10614,8 +10614,7 @@  cp_parser_lambda_declarator_opt (cp_pars
 
     p = obstack_alloc (&declarator_obstack, 0);
 
-    declarator = make_id_declarator (NULL_TREE, cp_operator_id (CALL_EXPR),
-				     sfk_none);
+    declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk_none);
 
     quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
 	     ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
Index: semantics.c
===================================================================
--- semantics.c	(revision 254243)
+++ semantics.c	(working copy)
@@ -9020,8 +9020,7 @@  classtype_has_nothrow_assign_or_copy_p (
   tree fns = NULL_TREE;
 
   if (assign_p || TYPE_HAS_COPY_CTOR (type))
-    fns = get_class_binding (type,
-			     assign_p ? cp_assignment_operator_id (NOP_EXPR)
+    fns = get_class_binding (type, assign_p ? assign_op_identifier
 			     : ctor_identifier);
 
   bool saw_copy = false;
Index: tree.c
===================================================================
--- tree.c	(revision 254243)
+++ tree.c	(working copy)
@@ -4847,7 +4847,8 @@  special_function_p (const_tree decl)
     return sfk_move_constructor;
   if (DECL_CONSTRUCTOR_P (decl))
     return sfk_constructor;
-  if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
+  if (DECL_ASSIGNMENT_OPERATOR_P (decl)
+      && DECL_OVERLOADED_OPERATOR_IS (decl, NOP_EXPR))
     {
       if (copy_fn_p (decl))
 	return sfk_copy_assignment;
Index: typeck.c
===================================================================
--- typeck.c	(revision 254243)
+++ typeck.c	(working copy)
@@ -9073,8 +9073,10 @@  check_return_expr (tree retval, bool *no
     }
 
   /* Only operator new(...) throw(), can return NULL [expr.new/13].  */
-  if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR
-       || DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR)
+  if (DECL_OVERLOADED_OPERATOR_P (current_function_decl)
+      && (DECL_OVERLOADED_OPERATOR_CODE (current_function_decl) == NEW_EXPR
+	  || (DECL_OVERLOADED_OPERATOR_CODE (current_function_decl)
+	      == VEC_NEW_EXPR))
       && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
       && ! flag_check_new
       && retval && null_ptr_cst_p (retval))
@@ -9083,7 +9085,7 @@  check_return_expr (tree retval, bool *no
 
   /* Effective C++ rule 15.  See also start_function.  */
   if (warn_ecpp
-      && DECL_NAME (current_function_decl) == cp_assignment_operator_id (NOP_EXPR))
+      && DECL_NAME (current_function_decl) == assign_op_identifier)
     {
       bool warn = true;