diff gcc/cp/method.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/cp/method.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/cp/method.c	Thu Oct 25 07:37:49 2018 +0900
@@ -1,6 +1,6 @@
 /* Handle the hair of processing (but not expanding) inline functions.
    Also manage function and variable name overloading.
-   Copyright (C) 1987-2017 Free Software Foundation, Inc.
+   Copyright (C) 1987-2018 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -32,22 +32,6 @@
 #include "toplev.h"
 #include "common/common-target.h"
 
-/* Various flags to control the mangling process.  */
-
-enum mangling_flags
-{
-  /* No flags.  */
-  mf_none = 0,
-  /* The thing we are presently mangling is part of a template type,
-     rather than a fully instantiated type.  Therefore, we may see
-     complex expressions where we would normally expect to see a
-     simple integer constant.  */
-  mf_maybe_uninstantiated = 1,
-  /* When mangling a numeric value, use the form `_XX_' (instead of
-     just `XX') if the value has more than one digit.  */
-  mf_use_underscores_around_value = 2
-};
-
 static void do_build_copy_assign (tree);
 static void do_build_copy_constructor (tree);
 static tree make_alias_for_thunk (tree);
@@ -206,7 +190,7 @@
 			   TREE_CODE (target), newid, TREE_TYPE (target));
   DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
   cxx_dup_lang_specific_decl (alias);
-  DECL_CONTEXT (alias) = NULL;
+  DECL_CONTEXT (alias) = DECL_CONTEXT (target);
   TREE_READONLY (alias) = TREE_READONLY (target);
   TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
   TREE_PUBLIC (alias) = 0;
@@ -391,7 +375,7 @@
   gcc_checking_assert (funcn);
   thunk_node = funcn->create_thunk (thunk_fndecl, function,
 				    this_adjusting, fixed_offset, virtual_value,
-				    virtual_offset, alias);
+				    0, virtual_offset, alias);
   if (DECL_ONE_ONLY (function))
     thunk_node->add_to_same_comdat_group (funcn);
 
@@ -484,7 +468,7 @@
   tree type = TREE_TYPE (parm);
   if (DECL_PACK_P (parm))
     type = PACK_EXPANSION_PATTERN (type);
-  if (TREE_CODE (type) != REFERENCE_TYPE)
+  if (!TYPE_REF_P (type))
     type = cp_build_reference_type (type, /*rval=*/true);
   warning_sentinel w (warn_useless_cast);
   exp = build_static_cast (type, exp, tf_warning_or_error);
@@ -747,7 +731,7 @@
 	     the field is "T", then the type will usually be "const
 	     T".  (There are no cv-qualified variants of reference
 	     types.)  */
-	  if (TREE_CODE (expr_type) != REFERENCE_TYPE)
+	  if (!TYPE_REF_P (expr_type))
 	    {
 	      int quals = cvquals;
 
@@ -758,7 +742,7 @@
 	    }
 
 	  init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE);
-	  if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE
+	  if (move_p && !TYPE_REF_P (expr_type)
 	      /* 'move' breaks bit-fields, and has no effect for scalars.  */
 	      && !scalarish_type_p (expr_type))
 	    init = move (init);
@@ -815,7 +799,7 @@
 	  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,
@@ -845,7 +829,7 @@
 		     "assignment operator", field);
 	      continue;
 	    }
-	  else if (TREE_CODE (expr_type) == REFERENCE_TYPE)
+	  else if (TYPE_REF_P (expr_type))
 	    {
 	      error ("non-static reference member %q#D, can%'t use "
 		     "default assignment operator", field);
@@ -874,7 +858,7 @@
 	  expr_type = cp_build_qualified_type (expr_type, quals);
 
 	  init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
-	  if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE
+	  if (move_p && !TYPE_REF_P (expr_type)
 	      /* 'move' breaks bit-fields, and has no effect for scalars.  */
 	      && !scalarish_type_p (expr_type))
 	    init = move (init);
@@ -929,7 +913,8 @@
   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;
@@ -965,7 +950,7 @@
   pop_deferring_access_checks ();
 
   if (error_count != errorcount || warning_count != warningcount + werrorcount)
-    inform (input_location, "synthesized method %qD first required here ",
+    inform (input_location, "synthesized method %qD first required here",
 	    fndecl);
 }
 
@@ -985,7 +970,7 @@
 static tree
 build_stub_object (tree reftype)
 {
-  if (TREE_CODE (reftype) != REFERENCE_TYPE)
+  if (!TYPE_REF_P (reftype))
     reftype = cp_build_reference_type (reftype, /*rval*/true);
   tree stub = build1 (CONVERT_EXPR, reftype, integer_one_node);
   return convert_from_reference (stub);
@@ -1108,7 +1093,7 @@
   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;
@@ -1159,12 +1144,12 @@
 constructible_expr (tree to, tree from)
 {
   tree expr;
+  cp_unevaluated cp_uneval_guard;
   if (CLASS_TYPE_P (to))
     {
       tree ctype = to;
       vec<tree, va_gc> *args = NULL;
-      cp_unevaluated cp_uneval_guard;
-      if (TREE_CODE (to) != REFERENCE_TYPE)
+      if (!TYPE_REF_P (to))
 	to = cp_build_reference_type (to, /*rval*/false);
       tree ob = build_stub_object (to);
       for (; from; from = TREE_CHAIN (from))
@@ -1231,7 +1216,7 @@
   tree expr;
   expr = is_xible_helper (code, to, from, /*trivial*/true);
 
-  if (expr == error_mark_node)
+  if (expr == NULL_TREE || expr == error_mark_node)
     return false;
   tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL);
   return !nt;
@@ -1292,7 +1277,7 @@
       if (diag)
 	{
 	  inform (DECL_SOURCE_LOCATION (fn),
-		  "defaulted constructor calls non-constexpr %qD", fn);
+		  "defaulted constructor calls non-%<constexpr%> %qD", fn);
 	  explain_invalid_constexpr_fn (fn);
 	}
     }
@@ -1320,6 +1305,15 @@
 	  || DECL_ARTIFICIAL (field))
 	continue;
 
+      /* Variant members only affect deletedness.  In particular, they don't
+	 affect the exception-specification of a user-provided destructor,
+	 which we're figuring out via get_defaulted_eh_spec.  So if we aren't
+	 asking if this is deleted, don't even look up the function; we don't
+	 want an error about a deleted function we aren't actually calling.  */
+      if (sfk == sfk_destructor && deleted_p == NULL
+	  && TREE_CODE (DECL_CONTEXT (field)) == UNION_TYPE)
+	break;
+
       mem_type = strip_array_types (TREE_TYPE (field));
       if (assign_p)
 	{
@@ -1330,7 +1324,7 @@
 		error ("non-static const member %q#D, can%'t use default "
 		       "assignment operator", field);
 	    }
-	  else if (TREE_CODE (mem_type) == REFERENCE_TYPE)
+	  else if (TYPE_REF_P (mem_type))
 	    {
 	      if (diag)
 		error ("non-static reference member %q#D, can%'t use "
@@ -1378,7 +1372,7 @@
 		}
 	      bad = true;
 	    }
-	  else if (TREE_CODE (mem_type) == REFERENCE_TYPE)
+	  else if (TYPE_REF_P (mem_type))
 	    {
 	      if (diag)
 		{
@@ -1409,7 +1403,7 @@
       else if (sfk == sfk_copy_constructor)
 	{
 	  /* 12.8p11b5 */
-	  if (TREE_CODE (mem_type) == REFERENCE_TYPE
+	  if (TYPE_REF_P (mem_type)
 	      && TYPE_REF_IS_RVALUE (mem_type))
 	    {
 	      if (diag)
@@ -1545,10 +1539,15 @@
     {
       /* "The closure type associated with a lambda-expression has a deleted
 	 default constructor and a deleted copy assignment operator."
-         This is diagnosed in maybe_explain_implicit_delete.  */
+	 This is diagnosed in maybe_explain_implicit_delete.
+	 In C++2a, only lambda-expressions with lambda-captures have those
+	 deleted.  */
       if (LAMBDA_TYPE_P (ctype)
-	  && (sfk == sfk_constructor
-	      || sfk == sfk_copy_assignment))
+	  && (sfk == sfk_constructor || sfk == sfk_copy_assignment)
+	  && (cxx_dialect < cxx2a
+	      || LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (ctype))
+	      || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE
+				(CLASSTYPE_LAMBDA_EXPR (ctype)) != CPLD_NONE))
 	{
 	  *deleted_p = true;
 	  return;
@@ -1565,7 +1564,7 @@
     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:
@@ -1702,12 +1701,12 @@
 	{
 	  /* Unlike for base ctor/op=/dtor, for operator delete it's fine
 	     to have a null fn (no class-specific op delete).  */
-	  fn = locate_fn_flags (ctype, cp_operator_id (DELETE_EXPR),
+	  fn = locate_fn_flags (ctype, ovl_op_identifier (false, DELETE_EXPR),
 				ptr_type_node, flags, tf_none);
 	  if (fn && fn == error_mark_node)
 	    {
 	      if (complain & tf_error)
-		locate_fn_flags (ctype, cp_operator_id (DELETE_EXPR),
+		locate_fn_flags (ctype, ovl_op_identifier (false, DELETE_EXPR),
 				 ptr_type_node, flags, complain);
 	      if (deleted_p)
 		*deleted_p = true;
@@ -1865,7 +1864,7 @@
 		      "%q#D is implicitly deleted because the default "
 		      "definition would be ill-formed:", decl);
 	      synthesized_method_walk (ctype, sfk, const_p,
-				       NULL, NULL, NULL, NULL, true,
+				       NULL, NULL, &deleted_p, NULL, true,
 				       &inh, parms);
 	    }
 	  else if (!comp_except_specs
@@ -2007,7 +2006,7 @@
 	  || kind == sfk_move_assignment)
 	{
 	  return_type = build_reference_type (type);
-	  name = cp_assignment_operator_id (NOP_EXPR);
+	  name = assign_op_identifier;
 	}
       else
 	name = ctor_identifier;
@@ -2077,7 +2076,7 @@
 
   if (!IDENTIFIER_CDTOR_P (name))
     /* Assignment operator.  */
-    SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
+    DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) = OVL_OP_NOP_EXPR;
   else if (IDENTIFIER_CTOR_P (name))
     DECL_CXX_CONSTRUCTOR_P (fn) = true;
   else
@@ -2195,7 +2194,6 @@
 	     "expected signature", fn);
       inform (DECL_SOURCE_LOCATION (fn),
 	      "expected signature: %qD", implicit_fn);
-      return;
     }
 
   if (DECL_DELETED_FN (implicit_fn))
@@ -2256,8 +2254,8 @@
       if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
 	{
 	  error ("explicitly defaulted function %q+D cannot be declared "
-		 "as constexpr because the implicit declaration is not "
-		 "constexpr:", fn);
+		 "as %<constexpr%> because the implicit declaration is not "
+		 "%<constexpr%>:", fn);
 	  explain_implicit_non_constexpr (fn);
 	}
       DECL_DECLARED_CONSTEXPR_P (fn) = false;
@@ -2318,7 +2316,7 @@
   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;
@@ -2401,8 +2399,19 @@
      move assignment operator, the implicitly declared copy constructor is
      defined as deleted.... */
   if ((sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
-      && classtype_has_move_assign_or_move_ctor_p (type, true))
-    DECL_DELETED_FN (fn) = true;
+      && cxx_dialect >= cxx11)
+    {
+      if (classtype_has_move_assign_or_move_ctor_p (type, true))
+	DECL_DELETED_FN (fn) = true;
+      else if (classtype_has_user_copy_or_dtor (type))
+	/* The implicit definition of a copy constructor as defaulted is
+	   deprecated if the class has a user-declared copy assignment operator
+	   or a user-declared destructor. The implicit definition of a copy
+	   assignment operator as defaulted is deprecated if the class has a
+	   user-declared copy constructor or a user-declared destructor (15.4,
+	   15.8).  */
+	TREE_DEPRECATED (fn) = true;
+    }
 
   /* Destructors and assignment operators may be virtual.  */
   if (sfk == sfk_destructor
@@ -2412,7 +2421,7 @@
 
   /* Add it to the class  */
   bool added = add_method (type, fn, false);
-  gcc_assert (added);
+  gcc_assert (added || errorcount);
 
   /* Add it to TYPE_FIELDS.  */
   if (sfk == sfk_destructor
@@ -2429,8 +2438,7 @@
   fixup_type_variants (type);
 
   maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
-  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
-      || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
+  if (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
     /* Create appropriate clones.  */
     clone_function_decl (fn, /*update_methods=*/true);