]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/call.c
Wrap option names in gcc internal messages with %< and %>.
[thirdparty/gcc.git] / gcc / cp / call.c
index 626830c0d9a43a26f7973b5d107309d37c49a524..98aa5ee89f72e6ed0d3f9ff5749945ca3fcb3033 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions related to invoking -*- C++ -*- methods and overloaded functions.
-   Copyright (C) 1987-2018 Free Software Foundation, Inc.
+   Copyright (C) 1987-2019 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) and
    modified by Brendan Kehoe (brendan@cygnus.com).
 
@@ -94,7 +94,7 @@ struct conversion {
   BOOL_BITFIELD bad_p : 1;
   /* If KIND is ck_ref_bind ck_base_conv, true to indicate that a
      temporary should be created to hold the result of the
-     conversion.  If KIND is ck_ambig, true if the context is
+     conversion.  If KIND is ck_ambig or ck_user, true means force
      copy-initialization.  */
   BOOL_BITFIELD need_temporary_p : 1;
   /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion
@@ -102,10 +102,10 @@ struct conversion {
   BOOL_BITFIELD base_p : 1;
   /* If KIND is ck_ref_bind, true when either an lvalue reference is
      being bound to an lvalue expression or an rvalue reference is
-     being bound to an rvalue expression.  If KIND is ck_rvalue,
+     being bound to an rvalue expression.  If KIND is ck_rvalue or ck_base,
      true when we are treating an lvalue as an rvalue (12.8p33).  If
-     KIND is ck_base, always false.  If ck_identity, we will be
-     binding a reference directly or decaying to a pointer.  */
+     ck_identity, we will be binding a reference directly or decaying to
+     a pointer.  */
   BOOL_BITFIELD rvaluedness_matches_p: 1;
   BOOL_BITFIELD check_narrowing: 1;
   /* Whether check_narrowing should only check TREE_CONSTANTs; used
@@ -166,8 +166,8 @@ static tree build_over_call (struct z_candidate *, int, tsubst_flags_t);
                     /*c_cast_p=*/false, (COMPLAIN))
 static tree convert_like_real (conversion *, tree, tree, int, bool,
                               bool, tsubst_flags_t);
-static void op_error (location_t, enum tree_code, enum tree_code, tree,
-                     tree, tree, bool);
+static void op_error (const op_location_t &, enum tree_code, enum tree_code,
+                     tree, tree, tree, bool);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
                                                         tsubst_flags_t);
 static void print_z_candidate (location_t, const char *, struct z_candidate *);
@@ -389,7 +389,7 @@ build_call_a (tree function, int n, tree *argarray)
   /* Don't pass empty class objects by value.  This is useful
      for tags in STL, which are used to control overload resolution.
      We don't need to handle other cases of copying empty classes.  */
-  if (! decl || ! DECL_BUILT_IN (decl))
+  if (!decl || !fndecl_built_in_p (decl))
     for (i = 0; i < n; i++)
       {
        tree arg = CALL_EXPR_ARG (function, i);
@@ -436,6 +436,8 @@ struct conversion_info {
   tree from;
   /* The type of the parameter.  */
   tree to_type;
+  /* The location of the argument.  */
+  location_t loc;
 };
   
 struct rejection_reason {
@@ -627,24 +629,28 @@ arity_rejection (tree first_arg, int expected, int actual)
 }
 
 static struct rejection_reason *
-arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to)
+arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to,
+                         location_t loc)
 {
   struct rejection_reason *r = alloc_rejection (rr_arg_conversion);
   int adjust = first_arg != NULL_TREE;
   r->u.conversion.n_arg = n_arg - adjust;
   r->u.conversion.from = from;
   r->u.conversion.to_type = to;
+  r->u.conversion.loc = loc;
   return r;
 }
 
 static struct rejection_reason *
-bad_arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to)
+bad_arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to,
+                             location_t loc)
 {
   struct rejection_reason *r = alloc_rejection (rr_bad_arg_conversion);
   int adjust = first_arg != NULL_TREE;
   r->u.bad_conversion.n_arg = n_arg - adjust;
   r->u.bad_conversion.from = from;
   r->u.bad_conversion.to_type = to;
+  r->u.bad_conversion.loc = loc;
   return r;
 }
 
@@ -655,6 +661,7 @@ explicit_conversion_rejection (tree from, tree to)
   r->u.conversion.n_arg = 0;
   r->u.conversion.from = from;
   r->u.conversion.to_type = to;
+  r->u.conversion.loc = UNKNOWN_LOCATION;
   return r;
 }
 
@@ -665,6 +672,7 @@ template_conversion_rejection (tree from, tree to)
   r->u.conversion.n_arg = 0;
   r->u.conversion.from = from;
   r->u.conversion.to_type = to;
+  r->u.conversion.loc = UNKNOWN_LOCATION;
   return r;
 }
 
@@ -894,6 +902,28 @@ can_convert_array (tree atype, tree ctor, int flags, tsubst_flags_t complain)
   return true;
 }
 
+/* Helper for build_aggr_conv.  Return true if FIELD is in PSET, or if
+   FIELD has ANON_AGGR_TYPE_P and any initializable field in there recursively
+   is in PSET.  */
+
+static bool
+field_in_pset (hash_set<tree> *pset, tree field)
+{
+  if (pset->contains (field))
+    return true;
+  if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+    for (field = TYPE_FIELDS (TREE_TYPE (field));
+        field; field = DECL_CHAIN (field))
+      {
+       field = next_initializable_field (field);
+       if (field == NULL_TREE)
+         break;
+       if (field_in_pset (pset, field))
+         return true;
+      }
+  return false;
+}
+
 /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
    aggregate class, if such a conversion is possible.  */
 
@@ -904,6 +934,7 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
   conversion *c;
   tree field = next_initializable_field (TYPE_FIELDS (type));
   tree empty_ctor = NULL_TREE;
+  hash_set<tree> *pset = NULL;
 
   /* We already called reshape_init in implicit_conversion.  */
 
@@ -911,26 +942,69 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
      context; they're always simple copy-initialization.  */
   flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
 
+  /* For designated initializers, verify that each initializer is convertible
+     to corresponding TREE_TYPE (ce->index) and mark those FIELD_DECLs as
+     visited.  In the following loop then ignore already visited
+     FIELD_DECLs.  */
+  if (CONSTRUCTOR_IS_DESIGNATED_INIT (ctor))
+    {
+      tree idx, val;
+      FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, idx, val)
+       {
+         if (idx && TREE_CODE (idx) == FIELD_DECL)
+           {
+             tree ftype = TREE_TYPE (idx);
+             bool ok;
+
+             if (TREE_CODE (ftype) == ARRAY_TYPE
+                 && TREE_CODE (val) == CONSTRUCTOR)
+               ok = can_convert_array (ftype, val, flags, complain);
+             else
+               ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags,
+                                     complain);
+
+             if (!ok)
+               goto fail;
+             /* For unions, there should be just one initializer.  */
+             if (TREE_CODE (type) == UNION_TYPE)
+               {
+                 field = NULL_TREE;
+                 i = 1;
+                 break;
+               }
+             if (pset == NULL)
+               pset = new hash_set<tree>;
+             pset->add (idx);
+           }
+         else
+           goto fail;
+       }
+    }
+
   for (; field; field = next_initializable_field (DECL_CHAIN (field)))
     {
       tree ftype = TREE_TYPE (field);
       tree val;
       bool ok;
 
+      if (pset && field_in_pset (pset, field))
+       continue;
       if (i < CONSTRUCTOR_NELTS (ctor))
-       val = CONSTRUCTOR_ELT (ctor, i)->value;
+       {
+         val = CONSTRUCTOR_ELT (ctor, i)->value;
+         ++i;
+       }
       else if (DECL_INITIAL (field))
        val = get_nsdmi (field, /*ctor*/false, complain);
       else if (TYPE_REF_P (ftype))
        /* Value-initialization of reference is ill-formed.  */
-       return NULL;
+       goto fail;
       else
        {
          if (empty_ctor == NULL_TREE)
            empty_ctor = build_constructor (init_list_type_node, NULL);
          val = empty_ctor;
        }
-      ++i;
 
       if (TREE_CODE (ftype) == ARRAY_TYPE
          && TREE_CODE (val) == CONSTRUCTOR)
@@ -940,15 +1014,22 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
                              complain);
 
       if (!ok)
-       return NULL;
+       goto fail;
 
       if (TREE_CODE (type) == UNION_TYPE)
        break;
     }
 
   if (i < CONSTRUCTOR_NELTS (ctor))
-    return NULL;
+    {
+    fail:
+      if (pset)
+       delete pset;
+      return NULL;
+    }
 
+  if (pset)
+    delete pset;
   c = alloc_conversion (ck_aggr);
   c->type = type;
   c->rank = cr_exact;
@@ -1404,6 +1485,13 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
             || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL)))
           || SCOPED_ENUM_P (from))
        return NULL;
+
+      /* If we're parsing an enum with no fixed underlying type, we're
+        dealing with an incomplete type, which renders the conversion
+        ill-formed.  */
+      if (!COMPLETE_TYPE_P (from))
+       return NULL;
+
       conv = build_conv (ck_std, to, conv);
 
       /* Give this a better rank if it's a promotion.  */
@@ -1425,6 +1513,9 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
         type.  A temporary object is created to hold the result of
         the conversion unless we're binding directly to a reference.  */
       conv->need_temporary_p = !(flags & LOOKUP_NO_TEMP_BIND);
+      if (flags & LOOKUP_PREFER_RVALUE)
+       /* Tell convert_like_real to set LOOKUP_PREFER_RVALUE.  */
+       conv->rvaluedness_matches_p = true;
     }
   else
     return NULL;
@@ -1549,6 +1640,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
       from = TREE_TYPE (expr);
     }
 
+  bool copy_list_init = false;
   if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
     {
       maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
@@ -1571,7 +1663,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
       /* Otherwise, if T is a reference type, a prvalue temporary of the type
         referenced by T is copy-list-initialized, and the reference is bound
         to that temporary. */
-      CONSTRUCTOR_IS_DIRECT_INIT (expr) = false;
+      copy_list_init = true;
     skip:;
     }
 
@@ -1759,6 +1851,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
 
   if (conv->user_conv_p)
     {
+      if (copy_list_init)
+       /* Remember this was copy-list-initialization.  */
+       conv->need_temporary_p = true;
+
       /* If initializing the temporary used a conversion function,
         recalculate the second conversion sequence.  */
       for (conversion *t = conv; t; t = next_conversion (t))
@@ -1853,11 +1949,12 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
   if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
     {
-      if (is_std_init_list (to))
+      if (is_std_init_list (to) && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
        return build_list_conv (to, expr, flags, complain);
 
       /* As an extension, allow list-initialization of _Complex.  */
-      if (TREE_CODE (to) == COMPLEX_TYPE)
+      if (TREE_CODE (to) == COMPLEX_TYPE
+         && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
        {
          conv = build_complex_conv (to, expr, flags, complain);
          if (conv)
@@ -1873,7 +1970,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
          if (nelts == 0)
            elt = build_value_init (to, tf_none);
-         else if (nelts == 1)
+         else if (nelts == 1 && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
            elt = CONSTRUCTOR_ELT (expr, 0)->value;
          else
            elt = error_mark_node;
@@ -2254,14 +2351,17 @@ add_function_candidate (struct z_candidate **candidates,
       if (! t)
        {
          viable = 0;
-         reason = arg_conversion_rejection (first_arg, i, argtype, to_type);
+         reason = arg_conversion_rejection (first_arg, i, argtype, to_type,
+                                            EXPR_LOCATION (arg));
          break;
        }
 
       if (t->bad_p)
        {
          viable = -1;
-         reason = bad_arg_conversion_rejection (first_arg, i, arg, to_type);
+         reason = bad_arg_conversion_rejection (first_arg, i, arg, to_type,
+                                                EXPR_LOCATION (arg));
+
        }
     }
 
@@ -2350,7 +2450,8 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
       if (t->bad_p)
        {
          viable = -1;
-         reason = bad_arg_conversion_rejection (NULL_TREE, i, arg, convert_type);
+         reason = bad_arg_conversion_rejection (NULL_TREE, i, arg, convert_type,
+                                                EXPR_LOCATION (arg));
        }
 
       if (i == 0)
@@ -2411,13 +2512,14 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
          /* We need something for printing the candidate.  */
          t = build_identity_conv (types[i], NULL_TREE);
          reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i],
-                                            types[i]);
+                                            types[i], EXPR_LOCATION (args[i]));
        }
       else if (t->bad_p)
        {
          viable = 0;
          reason = bad_arg_conversion_rejection (NULL_TREE, i, args[i],
-                                                types[i]);
+                                                types[i],
+                                                EXPR_LOCATION (args[i]));
        }
       convs[i] = t;
     }
@@ -2436,7 +2538,8 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
        {
          viable = 0;
          reason = arg_conversion_rejection (NULL_TREE, 0, argtypes[2],
-                                            boolean_type_node);
+                                            boolean_type_node,
+                                            EXPR_LOCATION (args[2]));
        }
     }
 
@@ -3234,6 +3337,12 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
       goto fail;
     }
 
+  /* Now the explicit specifier might have been deduced; check if this
+     declaration is explicit.  If it is and we're ignoring non-converting
+     constructors, don't add this function to the set of candidates.  */
+  if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn))
+    return NULL;
+
   if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
     {
       tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
@@ -3432,10 +3541,11 @@ equal_functions (tree fn1, tree fn2)
   return fn1 == fn2;
 }
 
-/* Print information about a candidate being rejected due to INFO.  */
+/* Print information about a candidate FN being rejected due to INFO.  */
 
 static void
-print_conversion_rejection (location_t loc, struct conversion_info *info)
+print_conversion_rejection (location_t loc, struct conversion_info *info,
+                           tree fn)
 {
   tree from = info->from;
   if (!TYPE_P (from))
@@ -3466,8 +3576,12 @@ print_conversion_rejection (location_t loc, struct conversion_info *info)
     inform (loc, "  no known conversion from %qH to %qI",
            from, info->to_type);
   else
-    inform (loc, "  no known conversion for argument %d from %qH to %qI",
-           info->n_arg + 1, from, info->to_type);
+    {
+      if (TREE_CODE (fn) == FUNCTION_DECL)
+       loc = get_fndecl_argument_location (fn, info->n_arg);
+      inform (loc, "  no known conversion for argument %d from %qH to %qI",
+             info->n_arg + 1, from, info->to_type);
+    }
 }
 
 /* Print information about a candidate with WANT parameters and we found
@@ -3542,10 +3656,10 @@ print_z_candidate (location_t loc, const char *msgstr,
                                   r->u.arity.expected);
          break;
        case rr_arg_conversion:
-         print_conversion_rejection (cloc, &r->u.conversion);
+         print_conversion_rejection (cloc, &r->u.conversion, fn);
          break;
        case rr_bad_arg_conversion:
-         print_conversion_rejection (cloc, &r->u.bad_conversion);
+         print_conversion_rejection (cloc, &r->u.bad_conversion, fn);
          break;
        case rr_explicit_conversion:
          inform (cloc, "  return type %qT of explicit conversion function "
@@ -3922,7 +4036,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
            {
              cand->viable = 0;
              cand->reason = arg_conversion_rejection (NULL_TREE, -2,
-                                                      rettype, totype);
+                                                      rettype, totype,
+                                                      EXPR_LOCATION (expr));
            }
          else if (DECL_NONCONVERTING_P (cand->fn)
                   && ics->rank > cr_exact)
@@ -3942,7 +4057,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
              cand->viable = -1;
              cand->reason
                = bad_arg_conversion_rejection (NULL_TREE, -2,
-                                               rettype, totype);
+                                               rettype, totype,
+                                               EXPR_LOCATION (expr));
            }
          else if (primary_template_specialization_p (cand->fn)
                   && ics->rank > cr_exact)
@@ -3966,7 +4082,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
     }
 
   cand = tourney (candidates, complain);
-  if (cand == 0)
+  if (cand == NULL)
     {
       if (complain & tf_error)
        {
@@ -4009,6 +4125,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
   if (cand->viable == -1)
     conv->bad_p = true;
 
+  /* We're performing the maybe-rvalue overload resolution and
+     a conversion function is in play.  Reject converting the return
+     value of the conversion function to a base class.  */
+  if ((flags & LOOKUP_PREFER_RVALUE) && !DECL_CONSTRUCTOR_P (cand->fn))
+    for (conversion *t = cand->second_conv; t; t = next_conversion (t))
+      if (t->kind == ck_base)
+       return NULL;
+
   /* Remember that this was a list-initialization.  */
   if (flags & LOOKUP_NO_NARROWING)
     conv->check_narrowing = true;
@@ -4196,7 +4320,7 @@ resolve_args (vec<tree, va_gc> *args, tsubst_flags_t complain)
            error ("invalid use of void expression");
          return NULL;
        }
-      else if (invalid_nonstatic_memfn_p (arg->exp.locus, arg, complain))
+      else if (invalid_nonstatic_memfn_p (EXPR_LOCATION (arg), arg, complain))
        return NULL;
     }
   return args;
@@ -4675,7 +4799,8 @@ op_error_string (const char *errmsg, int ntypes, bool match)
 }
 
 static void
-op_error (location_t loc, enum tree_code code, enum tree_code code2,
+op_error (const op_location_t &loc,
+         enum tree_code code, enum tree_code code2,
          tree arg1, tree arg2, tree arg3, bool match)
 {
   bool assop = code == MODIFY_EXPR;
@@ -4729,8 +4854,12 @@ op_error (location_t loc, enum tree_code code, enum tree_code code2,
     default:
       if (arg2)
        if (flag_diagnostics_show_caret)
-         error_at (loc, op_error_string (G_("%<operator%s%>"), 2, match),
-                   opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
+         {
+           binary_op_rich_location richloc (loc, arg1, arg2, true);
+           error_at (&richloc,
+                     op_error_string (G_("%<operator%s%>"), 2, match),
+                     opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
+         }
        else
          error_at (loc, op_error_string (G_("%<operator%s%> in %<%E %s %E%>"),
                                          2, match),
@@ -4829,7 +4958,8 @@ conditional_conversion (tree e1, tree e2, tsubst_flags_t complain)
    arguments to the conditional expression.  */
 
 static tree
-build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
+build_conditional_expr_1 (const op_location_t &loc,
+                         tree arg1, tree arg2, tree arg3,
                           tsubst_flags_t complain)
 {
   tree arg2_type;
@@ -5023,6 +5153,19 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
   arg3_type = unlowered_expr_type (arg3);
   if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
     {
+      /* 'void' won't help in resolving an overloaded expression on the
+        other side, so require it to resolve by itself.  */
+      if (arg2_type == unknown_type_node)
+       {
+         arg2 = resolve_nondeduced_context_or_error (arg2, complain);
+         arg2_type = TREE_TYPE (arg2);
+       }
+      if (arg3_type == unknown_type_node)
+       {
+         arg3 = resolve_nondeduced_context_or_error (arg3, complain);
+         arg3_type = TREE_TYPE (arg3);
+       }
+
       /* [expr.cond]
 
         One of the following shall hold:
@@ -5309,9 +5452,12 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
       if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
          && TREE_CODE (arg3_type) == ENUMERAL_TYPE)
         {
-         if (TREE_CODE (orig_arg2) == CONST_DECL
-             && TREE_CODE (orig_arg3) == CONST_DECL
-             && DECL_CONTEXT (orig_arg2) == DECL_CONTEXT (orig_arg3))
+         tree stripped_orig_arg2 = tree_strip_any_location_wrapper (orig_arg2);
+         tree stripped_orig_arg3 = tree_strip_any_location_wrapper (orig_arg3);
+         if (TREE_CODE (stripped_orig_arg2) == CONST_DECL
+             && TREE_CODE (stripped_orig_arg3) == CONST_DECL
+             && (DECL_CONTEXT (stripped_orig_arg2)
+                 == DECL_CONTEXT (stripped_orig_arg3)))
            /* Two enumerators from the same enumeration can have different
               types when the enumeration is still being defined.  */;
           else if (complain & tf_warning)
@@ -5420,7 +5566,8 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
 /* Wrapper for above.  */
 
 tree
-build_conditional_expr (location_t loc, tree arg1, tree arg2, tree arg3,
+build_conditional_expr (const op_location_t &loc,
+                       tree arg1, tree arg2, tree arg3,
                         tsubst_flags_t complain)
 {
   tree ret;
@@ -5609,8 +5756,9 @@ op_is_ordered (tree_code code)
 }
 
 static tree
-build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
-               tree arg2, tree arg3, tree *overload, tsubst_flags_t complain)
+build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags,
+               tree arg1, tree arg2, tree arg3, tree *overload,
+               tsubst_flags_t complain)
 {
   struct z_candidate *candidates = 0, *cand;
   vec<tree, va_gc> *arglist;
@@ -6089,7 +6237,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
 /* Wrapper for above.  */
 
 tree
-build_new_op (location_t loc, enum tree_code code, int flags,
+build_new_op (const op_location_t &loc, enum tree_code code, int flags,
              tree arg1, tree arg2, tree arg3,
              tree *overload, tsubst_flags_t complain)
 {
@@ -6152,6 +6300,31 @@ aligned_allocation_fn_p (tree t)
   return (a && same_type_p (TREE_VALUE (a), align_type_node));
 }
 
+/* True if T is std::destroying_delete_t.  */
+
+static bool
+std_destroying_delete_t_p (tree t)
+{
+  return (TYPE_CONTEXT (t) == std_node
+         && id_equal (TYPE_IDENTIFIER (t), "destroying_delete_t"));
+}
+
+/* A deallocation function with at least two parameters whose second parameter
+   type is of type std::destroying_delete_t is a destroying operator delete. A
+   destroying operator delete shall be a class member function named operator
+   delete. [ Note: Array deletion cannot use a destroying operator
+   delete. --end note ] */
+
+tree
+destroying_delete_p (tree t)
+{
+  tree a = TYPE_ARG_TYPES (TREE_TYPE (t));
+  if (!a || !TREE_CHAIN (a))
+    return NULL_TREE;
+  tree type = TREE_VALUE (TREE_CHAIN (a));
+  return std_destroying_delete_t_p (type) ? type : NULL_TREE;
+}
+
 /* Returns true iff T, an element of an OVERLOAD chain, is a usual deallocation
    function (3.7.4.2 [basic.stc.dynamic.deallocation]) with a parameter of
    std::align_val_t.  */
@@ -6169,6 +6342,8 @@ aligned_deallocation_fn_p (tree t)
     return false;
 
   tree a = FUNCTION_ARG_CHAIN (t);
+  if (destroying_delete_p (t))
+    a = TREE_CHAIN (a);
   if (same_type_p (TREE_VALUE (a), align_type_node)
       && TREE_CHAIN (a) == void_list_node)
     return true;
@@ -6204,6 +6379,8 @@ usual_deallocation_fn_p (tree t)
   tree chain = FUNCTION_ARG_CHAIN (t);
   if (!chain)
     return false;
+  if (destroying_delete_p (t))
+    chain = TREE_CHAIN (chain);
   if (chain == void_list_node
       || ((!global || flag_sized_deallocation)
          && second_parm_is_size_t (t)))
@@ -6269,6 +6446,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
     fns = lookup_name_nonclass (fnname);
 
   /* Strip const and volatile from addr.  */
+  tree oaddr = addr;
   addr = cp_convert (ptr_type_node, addr, complain);
 
   if (placement)
@@ -6364,6 +6542,19 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
                continue;
              }
 
+           /* -- If any of the deallocation functions is a destroying
+              operator delete, all deallocation functions that are not
+              destroying operator deletes are eliminated from further
+              consideration.  */
+           bool fn_destroying = destroying_delete_p (fn);
+           bool elt_destroying = destroying_delete_p (elt);
+           if (elt_destroying != fn_destroying)
+             {
+               if (elt_destroying)
+                 fn = elt;
+               continue;
+             }
+
            /* -- If the type has new-extended alignment, a function with a
               parameter of type std::align_val_t is preferred; otherwise a
               function without such a parameter is preferred. If exactly one
@@ -6446,9 +6637,24 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
        }
       else
        {
+         tree destroying = destroying_delete_p (fn);
+         if (destroying)
+           {
+             /* Strip const and volatile from addr but retain the type of the
+                object.  */
+             tree rtype = TREE_TYPE (TREE_TYPE (oaddr));
+             rtype = cv_unqualified (rtype);
+             rtype = TYPE_POINTER_TO (rtype);
+             addr = cp_convert (rtype, oaddr, complain);
+             destroying = build_functional_cast (destroying, NULL_TREE,
+                                                 complain);
+           }
+
          tree ret;
          vec<tree, va_gc> *args = make_tree_vector ();
          args->quick_push (addr);
+         if (destroying)
+           args->quick_push (destroying);
          if (second_parm_is_size_t (fn))
            args->quick_push (size);
          if (aligned_deallocation_fn_p (fn))
@@ -6482,6 +6688,38 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
   return error_mark_node;
 }
 
+/* Issue diagnostics about a disallowed access of DECL, using DIAG_DECL
+   in the diagnostics.
+
+   If ISSUE_ERROR is true, then issue an error about the
+   access, followed by a note showing the declaration.
+   Otherwise, just show the note.  */
+
+void
+complain_about_access (tree decl, tree diag_decl, bool issue_error)
+{
+  if (TREE_PRIVATE (decl))
+    {
+      if (issue_error)
+       error ("%q#D is private within this context", diag_decl);
+      inform (DECL_SOURCE_LOCATION (diag_decl),
+             "declared private here");
+    }
+  else if (TREE_PROTECTED (decl))
+    {
+      if (issue_error)
+       error ("%q#D is protected within this context", diag_decl);
+      inform (DECL_SOURCE_LOCATION (diag_decl),
+             "declared protected here");
+    }
+  else
+    {
+      if (issue_error)
+       error ("%q#D is inaccessible within this context", diag_decl);
+      inform (DECL_SOURCE_LOCATION (diag_decl), "declared here");
+    }
+}
+
 /* If the current scope isn't allowed to access DECL along
    BASETYPE_PATH, give an error.  The most derived class in
    BASETYPE_PATH is the one used to qualify DECL. DIAG_DECL is
@@ -6506,34 +6744,12 @@ enforce_access (tree basetype_path, tree decl, tree diag_decl,
 
   if (!accessible_p (basetype_path, decl, true))
     {
+      if (flag_new_inheriting_ctors)
+       diag_decl = strip_inheriting_ctors (diag_decl);
       if (complain & tf_error)
-       {
-         if (flag_new_inheriting_ctors)
-           diag_decl = strip_inheriting_ctors (diag_decl);
-         if (TREE_PRIVATE (decl))
-           {
-             error ("%q#D is private within this context", diag_decl);
-             inform (DECL_SOURCE_LOCATION (diag_decl),
-                     "declared private here");
-             if (afi)
-               afi->record_access_failure (basetype_path, diag_decl);
-           }
-         else if (TREE_PROTECTED (decl))
-           {
-             error ("%q#D is protected within this context", diag_decl);
-             inform (DECL_SOURCE_LOCATION (diag_decl),
-                     "declared protected here");
-             if (afi)
-               afi->record_access_failure (basetype_path, diag_decl);
-           }
-         else
-           {
-             error ("%q#D is inaccessible within this context", diag_decl);
-             inform (DECL_SOURCE_LOCATION (diag_decl), "declared here");
-             if (afi)
-               afi->record_access_failure (basetype_path, diag_decl);
-           }
-       }
+       complain_about_access (decl, diag_decl, true);
+      if (afi)
+       afi->record_access_failure (basetype_path, decl, diag_decl);
       return false;
     }
 
@@ -6576,6 +6792,22 @@ build_temp (tree expr, tree type, int flags,
   return expr;
 }
 
+/* Get any location for EXPR, falling back to input_location.
+
+   If the result is in a system header and is the virtual location for
+   a token coming from the expansion of a macro, unwind it to the
+   location of the expansion point of the macro (e.g. to avoid the
+   diagnostic being suppressed for expansions of NULL where "NULL" is
+   in a system header).  */
+
+static location_t
+get_location_for_expr_unwinding_for_system_header (tree expr)
+{
+  location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+  loc = expansion_point_location_if_in_system_header (loc);
+  return loc;
+}
+
 /* Perform warnings about peculiar, but valid, conversions from/to NULL.
    Also handle a subset of zero as null warnings.
    EXPR is implicitly converted to type TOTYPE.
@@ -6588,13 +6820,16 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
   if (null_node_p (expr) && TREE_CODE (totype) != BOOLEAN_TYPE
       && ARITHMETIC_TYPE_P (totype))
     {
-      source_location loc =
-       expansion_point_location_if_in_system_header (input_location);
-
+      location_t loc = get_location_for_expr_unwinding_for_system_header (expr);
       if (fn)
-       warning_at (loc, OPT_Wconversion_null,
-                   "passing NULL to non-pointer argument %P of %qD",
-                   argnum, fn);
+       {
+         auto_diagnostic_group d;
+         if (warning_at (loc, OPT_Wconversion_null,
+                         "passing NULL to non-pointer argument %P of %qD",
+                         argnum, fn))
+           inform (get_fndecl_argument_location (fn, argnum),
+                   "  declared here");
+       }
       else
        warning_at (loc, OPT_Wconversion_null,
                    "converting to non-pointer type %qT from NULL", totype);
@@ -6604,12 +6839,18 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
   else if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
           && TYPE_PTR_P (totype))
     {
+      location_t loc = get_location_for_expr_unwinding_for_system_header (expr);
       if (fn)
-       warning_at (input_location, OPT_Wconversion_null,
-                   "converting %<false%> to pointer type for argument %P "
-                   "of %qD", argnum, fn);
+       {
+         auto_diagnostic_group d;
+         if (warning_at (loc, OPT_Wconversion_null,
+                         "converting %<false%> to pointer type for argument "
+                         "%P of %qD", argnum, fn))
+           inform (get_fndecl_argument_location (fn, argnum),
+                   "  declared here");
+       }
       else
-       warning_at (input_location, OPT_Wconversion_null,
+       warning_at (loc, OPT_Wconversion_null,
                    "converting %<false%> to pointer type %qT", totype);
     }
   /* Handle zero as null pointer warnings for cases other
@@ -6617,8 +6858,7 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
   else if (null_ptr_cst_p (expr) &&
           (TYPE_PTR_OR_PTRMEM_P (totype) || NULLPTR_TYPE_P (totype)))
     {
-      source_location loc =
-       expansion_point_location_if_in_system_header (input_location);
+      location_t loc = get_location_for_expr_unwinding_for_system_header (expr);
       maybe_warn_zero_as_null_pointer_constant (expr, loc);
     }
 }
@@ -6647,6 +6887,11 @@ maybe_print_user_conv_context (conversion *convs)
 location_t
 get_fndecl_argument_location (tree fndecl, int argnum)
 {
+  /* The locations of implicitly-declared functions are likely to be
+     more meaningful than those of their parameters.  */
+  if (DECL_ARTIFICIAL (fndecl))
+    return DECL_SOURCE_LOCATION (fndecl);
+
   int i;
   tree param;
 
@@ -6664,6 +6909,18 @@ get_fndecl_argument_location (tree fndecl, int argnum)
   return DECL_SOURCE_LOCATION (param);
 }
 
+/* If FNDECL is non-NULL, issue a note highlighting ARGNUM
+   within its declaration (or the fndecl itself if something went
+   wrong).  */
+
+void
+maybe_inform_about_fndecl_for_bogus_argument_init (tree fn, int argnum)
+{
+  if (fn)
+    inform (get_fndecl_argument_location (fn, argnum),
+           "  initializing argument %P of %qD", argnum, fn);
+}
+
 /* Perform the conversions in CONVS on the expression EXPR.  FN and
    ARGNUM are used for diagnostics.  ARGNUM is zero based, -1
    indicates the `this' argument of a method.  INNER is nonzero when
@@ -6741,9 +6998,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
                                             complain);
              else
                expr = cp_convert (totype, expr, complain);
-             if (complained && fn)
-               inform (DECL_SOURCE_LOCATION (fn),
-                       "  initializing argument %P of %qD", argnum, fn);
+             if (complained)
+               maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
              return expr;
            }
          else if (t->kind == ck_user || !t->bad_p)
@@ -6770,9 +7026,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
                                  "invalid conversion from %qH to %qI",
                                  TREE_TYPE (expr), totype);
        }
-      if (complained && fn)
-       inform (get_fndecl_argument_location (fn, argnum),
-               "  initializing argument %P of %qD", argnum, fn);
+      if (complained)
+       maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
 
       return cp_convert (totype, expr, complain);
     }
@@ -6799,7 +7054,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
            && BRACE_ENCLOSED_INITIALIZER_P (expr)
            /* Unless this is for direct-list-initialization.  */
-           && !CONSTRUCTOR_IS_DIRECT_INIT (expr)
+           && (!CONSTRUCTOR_IS_DIRECT_INIT (expr) || convs->need_temporary_p)
            /* And in C++98 a default constructor can't be explicit.  */
            && cxx_dialect >= cxx11)
          {
@@ -6824,7 +7079,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        /* If we're initializing from {}, it's value-initialization.  */
        if (BRACE_ENCLOSED_INITIALIZER_P (expr)
            && CONSTRUCTOR_NELTS (expr) == 0
-           && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
+           && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype)
+           && !processing_template_decl)
          {
            bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr);
            if (abstract_virtuals_error_sfinae (NULL_TREE, totype, complain))
@@ -6839,7 +7095,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            return expr;
          }
 
-       expr = mark_rvalue_use (expr);
+       /* We don't know here whether EXPR is being used as an lvalue or
+          rvalue, but we know it's read.  */
+       mark_exp_read (expr);
 
        /* Pass LOOKUP_NO_CONVERSION so rvalue/base handling knows not to allow
           any more UDCs.  */
@@ -6894,9 +7152,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
                       ? LOOKUP_IMPLICIT : LOOKUP_NORMAL);
          build_user_type_conversion (totype, convs->u.expr, flags, complain);
          gcc_assert (seen_error ());
-         if (fn)
-           inform (DECL_SOURCE_LOCATION (fn),
-                   "  initializing argument %P of %qD", argnum, fn);
+         maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
        }
       return error_mark_node;
 
@@ -6904,34 +7160,42 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       {
        /* Conversion to std::initializer_list<T>.  */
        tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
-       tree new_ctor = build_constructor (init_list_type_node, NULL);
        unsigned len = CONSTRUCTOR_NELTS (expr);
-       tree array, val, field;
-       vec<constructor_elt, va_gc> *vec = NULL;
-       unsigned ix;
+       tree array;
 
-       /* Convert all the elements.  */
-       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val)
+       if (len)
          {
-           tree sub = convert_like_real (convs->u.list[ix], val, fn, argnum,
-                                         false, false, complain);
-           if (sub == error_mark_node)
-             return sub;
-           if (!BRACE_ENCLOSED_INITIALIZER_P (val)
-               && !check_narrowing (TREE_TYPE (sub), val, complain))
-             return error_mark_node;
-           CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), NULL_TREE, sub);
-           if (!TREE_CONSTANT (sub))
-             TREE_CONSTANT (new_ctor) = false;
+           tree val; unsigned ix;
+
+           tree new_ctor = build_constructor (init_list_type_node, NULL);
+
+           /* Convert all the elements.  */
+           FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val)
+             {
+               tree sub = convert_like_real (convs->u.list[ix], val, fn,
+                                             argnum, false, false, complain);
+               if (sub == error_mark_node)
+                 return sub;
+               if (!BRACE_ENCLOSED_INITIALIZER_P (val)
+                   && !check_narrowing (TREE_TYPE (sub), val, complain))
+                 return error_mark_node;
+               CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor),
+                                       NULL_TREE, sub);
+               if (!TREE_CONSTANT (sub))
+                 TREE_CONSTANT (new_ctor) = false;
+             }
+           /* Build up the array.  */
+           elttype = cp_build_qualified_type
+             (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
+           array = build_array_of_n_type (elttype, len);
+           array = finish_compound_literal (array, new_ctor, complain);
+           /* Take the address explicitly rather than via decay_conversion
+              to avoid the error about taking the address of a temporary.  */
+           array = cp_build_addr_expr (array, complain);
          }
-       /* Build up the array.  */
-       elttype = cp_build_qualified_type
-         (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
-       array = build_array_of_n_type (elttype, len);
-       array = finish_compound_literal (array, new_ctor, complain);
-       /* Take the address explicitly rather than via decay_conversion
-          to avoid the error about taking the address of a temporary.  */
-       array = cp_build_addr_expr (array, complain);
+       else
+         array = nullptr_node;
+
        array = cp_convert (build_pointer_type (elttype), array, complain);
        if (array == error_mark_node)
          return error_mark_node;
@@ -6942,11 +7206,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        totype = complete_type_or_maybe_complain (totype, NULL_TREE, complain);
        if (!totype)
          return error_mark_node;
-       field = next_initializable_field (TYPE_FIELDS (totype));
+       tree field = next_initializable_field (TYPE_FIELDS (totype));
+       vec<constructor_elt, va_gc> *vec = NULL;
        CONSTRUCTOR_APPEND_ELT (vec, field, array);
        field = next_initializable_field (DECL_CHAIN (field));
        CONSTRUCTOR_APPEND_ELT (vec, field, size_int (len));
-       new_ctor = build_constructor (totype, vec);
+       tree new_ctor = build_constructor (totype, vec);
        return get_target_expr_sfinae (new_ctor, complain);
       }
 
@@ -6990,9 +7255,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            {
              auto_diagnostic_group d;
              maybe_print_user_conv_context (convs);
-             if (fn)
-               inform (DECL_SOURCE_LOCATION (fn),
-                       "  initializing argument %P of %qD", argnum, fn);
+             maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
            }
          return error_mark_node;
        }
@@ -7043,9 +7306,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        {
          auto_diagnostic_group d;
          maybe_print_user_conv_context (convs);
-         if (fn)
-           inform (DECL_SOURCE_LOCATION (fn),
-                   "  initializing argument %P of %qD", argnum, fn);
+         maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
        }
 
       return build_cplus_new (totype, expr, complain);
@@ -7072,9 +7333,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            else
              gcc_unreachable ();
            maybe_print_user_conv_context (convs);
-           if (fn)
-             inform (DECL_SOURCE_LOCATION (fn),
-                     "  initializing argument %P of %qD", argnum, fn);
+           maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
+
            return error_mark_node;
          }
 
@@ -7239,7 +7499,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
              && TYPE_MODE (TREE_TYPE (prom)) != TYPE_MODE (arg_type)
              && (complain & tf_warning))
            warning_at (loc, OPT_Wabi, "scoped enum %qT passed through ... as "
-                       "%qT before -fabi-version=6, %qT after", arg_type,
+                       "%qT before %<-fabi-version=6%>, %qT after", arg_type,
                        TREE_TYPE (prom), ENUM_UNDERLYING_TYPE (arg_type));
          if (!abi_version_at_least (6))
            arg = prom;
@@ -7293,7 +7553,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
 /* va_arg (EXPR, TYPE) is a builtin. Make sure it is not abused.  */
 
 tree
-build_x_va_arg (source_location loc, tree expr, tree type)
+build_x_va_arg (location_t loc, tree expr, tree type)
 {
   if (processing_template_decl)
     {
@@ -7507,6 +7767,10 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
        }
       maybe_warn_parm_abi (type, cp_expr_loc_or_loc (val, input_location));
     }
+
+  if (complain & tf_warning)
+    warn_for_address_or_pointer_of_packed_member (type, val);
+
   return val;
 }
 
@@ -7922,7 +8186,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        {
          /* The implicit move specified in 15.8.3/3 fails "...if the type of
             the first parameter of the selected constructor is not an rvalue
-            reference to the objects type (possibly cv-qualified)...." */
+            reference to the object's type (possibly cv-qualified)...." */
          gcc_assert (!(complain & tf_error));
          tree ptype = convs[0]->type;
          if (!TYPE_REF_P (ptype)
@@ -8071,7 +8335,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
              pedwarn (DECL_SOURCE_LOCATION (cand->fn), 0,
                       "  in call to %qD", cand->fn);
              pedwarn (input_location, 0,
-                      "  (you can disable this with -fno-deduce-init-list)");
+                      "  (you can disable this with "
+                      "%<-fno-deduce-init-list%>)");
            }
        }
 
@@ -8164,7 +8429,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
              && TYPE_REF_P (TREE_TYPE (argarray[j])))
            fargs[j] = TREE_OPERAND (argarray[j], 0);
          else
-           fargs[j] = maybe_constant_value (argarray[j]);
+           fargs[j] = argarray[j];
        }
 
       warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn),
@@ -8302,7 +8567,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       tree arg = argarray[1];
       location_t loc = cp_expr_loc_or_loc (arg, input_location);
 
-      if (is_really_empty_class (type))
+      if (is_really_empty_class (type, /*ignore_vptr*/true))
        {
          /* Avoid copying empty classes.  */
          val = build2 (COMPOUND_EXPR, type, arg, to);
@@ -8369,10 +8634,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
     maybe_warn_class_memaccess (input_location, fn, args);
 
-  if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
-      /* Don't mess with virtual lookup in instantiate_non_dependent_expr;
-        virtual functions can't be constexpr.  */
-      && !in_template_function ())
+  if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
     {
       tree t;
       tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (argarray[0])),
@@ -8624,15 +8886,6 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl,
       bool special = same_type_ignoring_top_level_qualifiers_p (ctx, desttype);
       tree binfo = TYPE_BINFO (ctx);
 
-      /* FIXME: The following if statement is overly permissive (see
-        bug 84851).  Remove it in GCC 9.  */
-      if (special
-         && !BINFO_VTABLE (binfo)
-         && !BINFO_N_BASE_BINFOS (binfo)
-         && (DECL_CONSTRUCTOR_P (current_function_decl)
-             || DECL_DESTRUCTOR_P (current_function_decl)))
-       return;
-
       if (special
          && !BINFO_VTABLE (binfo)
          && !first_non_trivial_field (desttype))
@@ -8869,8 +9122,7 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
   /* Check that arguments to builtin functions match the expectations.  */
   if (fndecl
       && !processing_template_decl
-      && DECL_BUILT_IN (fndecl)
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+      && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       int i;
 
@@ -9152,6 +9404,129 @@ name_as_c_string (tree name, tree type, bool *free_p)
   return CONST_CAST (char *, pretty_name);
 }
 
+/* If CANDIDATES contains exactly one candidate, return it, otherwise
+   return NULL.  */
+
+static z_candidate *
+single_z_candidate (z_candidate *candidates)
+{
+  if (candidates == NULL)
+    return NULL;
+
+  if (candidates->next)
+    return NULL;
+
+  return candidates;
+}
+
+/* If CANDIDATE is invalid due to a bad argument type, return the
+   pertinent conversion_info.
+
+   Otherwise, return NULL.  */
+
+static const conversion_info *
+maybe_get_bad_conversion_for_unmatched_call (const z_candidate *candidate)
+{
+  /* Must be an rr_arg_conversion or rr_bad_arg_conversion.  */
+  rejection_reason *r = candidate->reason;
+
+  if (r == NULL)
+    return NULL;
+
+  switch (r->code)
+    {
+    default:
+      return NULL;
+
+    case rr_arg_conversion:
+      return &r->u.conversion;
+
+    case rr_bad_arg_conversion:
+      return &r->u.bad_conversion;
+    }
+}
+
+/* Issue an error and note complaining about a bad argument type at a
+   callsite with a single candidate FNDECL.
+
+   ARG_LOC is the location of the argument (or UNKNOWN_LOCATION, in which
+   case input_location is used).
+   FROM_TYPE is the type of the actual argument; TO_TYPE is the type of
+   the formal parameter.  */
+
+void
+complain_about_bad_argument (location_t arg_loc,
+                            tree from_type, tree to_type,
+                            tree fndecl, int parmnum)
+{
+  auto_diagnostic_group d;
+  range_label_for_type_mismatch rhs_label (from_type, to_type);
+  range_label *label = &rhs_label;
+  if (arg_loc == UNKNOWN_LOCATION)
+    {
+      arg_loc = input_location;
+      label = NULL;
+    }
+  gcc_rich_location richloc (arg_loc, label);
+  error_at (&richloc,
+           "cannot convert %qH to %qI",
+           from_type, to_type);
+  maybe_inform_about_fndecl_for_bogus_argument_init (fndecl,
+                                                    parmnum);
+}
+
+/* Subroutine of build_new_method_call_1, for where there are no viable
+   candidates for the call.  */
+
+static void
+complain_about_no_candidates_for_method_call (tree instance,
+                                             z_candidate *candidates,
+                                             tree explicit_targs,
+                                             tree basetype,
+                                             tree optype, tree name,
+                                             bool skip_first_for_error,
+                                             vec<tree, va_gc> *user_args)
+{
+  auto_diagnostic_group d;
+  if (!COMPLETE_OR_OPEN_TYPE_P (basetype))
+    cxx_incomplete_type_error (instance, basetype);
+  else if (optype)
+    error ("no matching function for call to %<%T::operator %T(%A)%#V%>",
+          basetype, optype, build_tree_list_vec (user_args),
+          TREE_TYPE (instance));
+  else
+    {
+      /* Special-case for when there's a single candidate that's failing
+        due to a bad argument type.  */
+      if (z_candidate *candidate = single_z_candidate (candidates))
+         if (const conversion_info *conv
+               = maybe_get_bad_conversion_for_unmatched_call (candidate))
+           {
+             complain_about_bad_argument (conv->loc,
+                                          conv->from, conv->to_type,
+                                          candidate->fn, conv->n_arg);
+             return;
+           }
+
+      tree arglist = build_tree_list_vec (user_args);
+      tree errname = name;
+      bool twiddle = false;
+      if (IDENTIFIER_CDTOR_P (errname))
+       {
+         twiddle = IDENTIFIER_DTOR_P (errname);
+         errname = constructor_name (basetype);
+       }
+      if (explicit_targs)
+       errname = lookup_template_function (errname, explicit_targs);
+      if (skip_first_for_error)
+       arglist = TREE_CHAIN (arglist);
+      error ("no matching function for call to %<%T::%s%E(%A)%#V%>",
+            basetype, &"~"[!twiddle], errname, arglist,
+            TREE_TYPE (instance));
+    }
+  print_z_candidates (location_of (name), candidates);
+}
+
 /* Build a call to "INSTANCE.FN (ARGS)".  If FN_P is non-NULL, it will
    be set, upon return, to the function called.  ARGS may be NULL.
    This may change ARGS.  */
@@ -9369,34 +9744,11 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
   if (!any_viable_p)
     {
       if (complain & tf_error)
-       {
-         auto_diagnostic_group d;
-         if (!COMPLETE_OR_OPEN_TYPE_P (basetype))
-           cxx_incomplete_type_error (instance, basetype);
-         else if (optype)
-           error ("no matching function for call to %<%T::operator %T(%A)%#V%>",
-                  basetype, optype, build_tree_list_vec (user_args),
-                  TREE_TYPE (instance));
-         else
-           {
-             tree arglist = build_tree_list_vec (user_args);
-             tree errname = name;
-             bool twiddle = false;
-             if (IDENTIFIER_CDTOR_P (errname))
-               {
-                 twiddle = IDENTIFIER_DTOR_P (errname);
-                 errname = constructor_name (basetype);
-               }
-             if (explicit_targs)
-               errname = lookup_template_function (errname, explicit_targs);
-             if (skip_first_for_error)
-               arglist = TREE_CHAIN (arglist);
-             error ("no matching function for call to %<%T::%s%E(%A)%#V%>",
-                    basetype, &"~"[!twiddle], errname, arglist,
-                    TREE_TYPE (instance));
-           }
-         print_z_candidates (location_of (name), candidates);
-       }
+       complain_about_no_candidates_for_method_call (instance, candidates,
+                                                     explicit_targs, basetype,
+                                                     optype, name,
+                                                     skip_first_for_error,
+                                                     user_args);
       call = error_mark_node;
     }
   else
@@ -9782,21 +10134,22 @@ compare_ics (conversion *ics1, conversion *ics2)
      Specifically, we need to do the reference binding comparison at the
      end of this function.  */
 
-  if (ics1->user_conv_p || ics1->kind == ck_list || ics1->kind == ck_aggr)
+  if (ics1->user_conv_p || ics1->kind == ck_list
+      || ics1->kind == ck_aggr || ics2->kind == ck_aggr)
     {
       conversion *t1;
       conversion *t2;
 
-      for (t1 = ics1; t1->kind != ck_user; t1 = next_conversion (t1))
+      for (t1 = ics1; t1 && t1->kind != ck_user; t1 = next_conversion (t1))
        if (t1->kind == ck_ambig || t1->kind == ck_aggr
            || t1->kind == ck_list)
          break;
-      for (t2 = ics2; t2->kind != ck_user; t2 = next_conversion (t2))
+      for (t2 = ics2; t2 && t2->kind != ck_user; t2 = next_conversion (t2))
        if (t2->kind == ck_ambig || t2->kind == ck_aggr
            || t2->kind == ck_list)
          break;
 
-      if (t1->kind != t2->kind)
+      if (!t1 || !t2 || t1->kind != t2->kind)
        return 0;
       else if (t1->kind == ck_user)
        {
@@ -10576,7 +10929,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
 
 tweak:
 
-  /* Extension: If the worst conversion for one candidate is worse than the
+  /* Extension: If the worst conversion for one candidate is better than the
      worst conversion for the other, take the first.  */
   if (!pedantic && (complain & tf_warning_or_error))
     {
@@ -10602,12 +10955,14 @@ tweak:
          if (warn)
            {
              auto_diagnostic_group d;
-             pedwarn (input_location, 0,
-             "ISO C++ says that these are ambiguous, even "
-             "though the worst conversion for the first is better than "
-             "the worst conversion for the second:");
-             print_z_candidate (input_location, _("candidate 1:"), w);
-             print_z_candidate (input_location, _("candidate 2:"), l);
+             if (pedwarn (input_location, 0,
+                          "ISO C++ says that these are ambiguous, even "
+                          "though the worst conversion for the first is "
+                          "better than the worst conversion for the second:"))
+               {
+                 print_z_candidate (input_location, _("candidate 1:"), w);
+                 print_z_candidate (input_location, _("candidate 2:"), l);
+               }
            }
          else
            add_warning (w, l);
@@ -10805,6 +11160,8 @@ perform_implicit_conversion_flags (tree type, tree expr,
       expr = build1 (IMPLICIT_CONV_EXPR, type, expr);
       if (!(flags & LOOKUP_ONLYCONVERTING))
        IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true;
+      if (flags & LOOKUP_NO_NARROWING)
+       IMPLICIT_CONV_EXPR_BRACED_INIT (expr) = true;
     }
   else
     expr = convert_like (conv, expr, complain);
@@ -10941,23 +11298,33 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
       && (TREE_STATIC (decl) || CP_DECL_THREAD_LOCAL_P (decl)))
     {
       /* Namespace-scope or local static; give it a mangled name.  */
-      /* FIXME share comdat with decl?  */
+
+      /* If an initializer is visible to multiple translation units, those
+        translation units must agree on the addresses of the
+        temporaries. Therefore the temporaries must be given a consistent name
+        and vague linkage. The mangled name of a temporary is the name of the
+        non-temporary object in whose initializer they appear, prefixed with
+        GR and suffixed with a sequence number mangled using the usual rules
+        for a seq-id. Temporaries are numbered with a pre-order, depth-first,
+        left-to-right walk of the complete initializer.  */
 
       TREE_STATIC (var) = TREE_STATIC (decl);
+      TREE_PUBLIC (var) = TREE_PUBLIC (decl);
+      if (vague_linkage_p (decl))
+       comdat_linkage (var);
+
       CP_DECL_THREAD_LOCAL_P (var) = CP_DECL_THREAD_LOCAL_P (decl);
       set_decl_tls_model (var, DECL_TLS_MODEL (decl));
 
       tree name = mangle_ref_init_variable (decl);
       DECL_NAME (var) = name;
       SET_DECL_ASSEMBLER_NAME (var, name);
-
-      var = pushdecl (var);
     }
   else
     /* Create a new cleanup level if necessary.  */
     maybe_push_cleanup_level (type);
 
-  return var;
+  return pushdecl (var);
 }
 
 /* EXPR is the initializer for a variable DECL of reference or