]> 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 7176e4afa1507a0e5a45de7931c10e19b299a2a0..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).
 
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "internal-fn.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "gcc-rich-location.h"
 
 /* The various kinds of conversion.  */
 
@@ -93,19 +94,23 @@ 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.  */
+     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
      from a pointer-to-derived to pointer-to-base is being performed.  */
   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.  */
+     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
+     in build_converted_constant_expr.  */
+  BOOL_BITFIELD check_narrowing_const_only: 1;
   /* The type of the expression resulting from the conversion.  */
   tree type;
   union {
@@ -161,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 *);
@@ -191,7 +196,7 @@ static struct z_candidate *add_conv_candidate
         tree, tsubst_flags_t);
 static struct z_candidate *add_function_candidate
        (struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *, tree,
-        tree, int, tsubst_flags_t);
+        tree, int, conversion**, tsubst_flags_t);
 static conversion *implicit_conversion (tree, tree, tree, bool, int,
                                        tsubst_flags_t);
 static conversion *reference_binding (tree, tree, tree, bool, int,
@@ -318,15 +323,17 @@ build_call_n (tree function, int n, ...)
 void
 set_flags_from_callee (tree call)
 {
-  bool nothrow;
-  tree decl = get_callee_fndecl (call);
+  /* Handle both CALL_EXPRs and AGGR_INIT_EXPRs.  */
+  tree decl = cp_get_callee_fndecl_nofold (call);
 
   /* We check both the decl and the type; a function may be known not to
      throw without being declared throw().  */
-  nothrow = decl && TREE_NOTHROW (decl);
-  if (CALL_EXPR_FN (call))
-    nothrow |= TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (call))));
-  else if (internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW)
+  bool nothrow = decl && TREE_NOTHROW (decl);
+  tree callee = cp_get_callee (call);
+  if (callee)
+    nothrow |= TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (callee)));
+  else if (TREE_CODE (call) == CALL_EXPR
+          && internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW)
     nothrow = true;
 
   if (!nothrow && at_function_scope_p () && cfun && cp_function_chain)
@@ -382,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);
@@ -429,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 {
@@ -541,7 +550,7 @@ null_ptr_cst_p (tree t)
     }
   else if (CP_INTEGRAL_TYPE_P (type))
     {
-      t = fold_non_dependent_expr (t);
+      t = fold_non_dependent_expr (t, tf_none);
       STRIP_NOPS (t);
       if (integer_zerop (t) && !TREE_OVERFLOW (t))
        return true;
@@ -620,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;
 }
 
@@ -648,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;
 }
 
@@ -658,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;
 }
 
@@ -813,7 +828,7 @@ build_list_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
   flags |= LOOKUP_NO_NARROWING;
 
   /* Can't make an array of these types.  */
-  if (TREE_CODE (elttype) == REFERENCE_TYPE
+  if (TYPE_REF_P (elttype)
       || TREE_CODE (elttype) == FUNCTION_TYPE
       || VOID_TYPE_P (elttype))
     return NULL;
@@ -887,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.  */
 
@@ -897,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.  */
 
@@ -904,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 (TREE_CODE (ftype) == REFERENCE_TYPE)
+      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)
@@ -933,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;
@@ -1104,7 +1192,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   tree qualified_to;
 
   to = non_reference (to);
-  if (TREE_CODE (from) == REFERENCE_TYPE)
+  if (TYPE_REF_P (from))
     {
       fromref = true;
       from = TREE_TYPE (from);
@@ -1139,6 +1227,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
     {
       from = type_decays_to (from);
       fcode = TREE_CODE (from);
+      /* Tell convert_like_real that we're using the address.  */
+      conv->rvaluedness_matches_p = true;
       conv = build_conv (ck_lvalue, from, conv);
     }
   /* Wrapping a ck_rvalue around a class prvalue (as a result of using
@@ -1379,6 +1469,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
            conv->rank = cr_pbool;
          if (NULLPTR_TYPE_P (from) && (flags & LOOKUP_ONLYCONVERTING))
            conv->bad_p = true;
+         if (flags & LOOKUP_NO_NARROWING)
+           conv->check_narrowing = true;
          return conv;
        }
 
@@ -1393,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.  */
@@ -1414,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;
@@ -1472,8 +1574,8 @@ direct_reference_binding (tree type, conversion *conv)
 {
   tree t;
 
-  gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
-  gcc_assert (TREE_CODE (conv->type) != REFERENCE_TYPE);
+  gcc_assert (TYPE_REF_P (type));
+  gcc_assert (!TYPE_REF_P (conv->type));
 
   t = TREE_TYPE (type);
 
@@ -1538,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);
@@ -1557,16 +1660,14 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
              goto skip;
            }
        }
-      /* Otherwise, if T is a reference type, a prvalue temporary of the
-        type referenced by T is copy-list-initialized or
-        direct-list-initialized, depending on the kind of initialization
-        for the reference, and the reference is bound to that temporary. */
-      conv = implicit_conversion (to, from, expr, c_cast_p,
-                                 flags|LOOKUP_NO_TEMP_BIND, complain);
+      /* 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. */
+      copy_list_init = true;
     skip:;
     }
 
-  if (TREE_CODE (from) == REFERENCE_TYPE)
+  if (TYPE_REF_P (from))
     {
       from = TREE_TYPE (from);
       if (!TYPE_REF_IS_RVALUE (rfrom)
@@ -1632,7 +1733,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
       conv = build_identity_conv (tfrom, expr);
       conv = direct_reference_binding (rto, conv);
 
-      if (TREE_CODE (rfrom) == REFERENCE_TYPE)
+      if (TYPE_REF_P (rfrom))
        /* Handle rvalue reference to function properly.  */
        conv->rvaluedness_matches_p
          = (TYPE_REF_IS_RVALUE (rto) == TYPE_REF_IS_RVALUE (rfrom));
@@ -1750,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))
@@ -1834,7 +1939,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
       from = TREE_TYPE (expr);
     }
 
-  if (TREE_CODE (to) == REFERENCE_TYPE)
+  if (TYPE_REF_P (to))
     conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
   else
     conv = standard_conversion (to, from, expr, c_cast_p, flags, complain);
@@ -1844,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)
@@ -1864,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;
@@ -1926,6 +2032,23 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
   return NULL;
 }
 
+/* Like implicit_conversion, but return NULL if the conversion is bad.
+
+   This is not static so that check_non_deducible_conversion can call it within
+   add_template_candidate_real as part of overload resolution; it should not be
+   called outside of overload resolution.  */
+
+conversion *
+good_conversion (tree to, tree from, tree expr,
+                int flags, tsubst_flags_t complain)
+{
+  conversion *c = implicit_conversion (to, from, expr, /*cast*/false,
+                                      flags, complain);
+  if (c && c->bad_p)
+    c = NULL;
+  return c;
+}
+
 /* Add a new entry to the list of candidates.  Used by the add_*_candidate
    functions.  ARGS will not be changed until a single candidate is
    selected.  */
@@ -1972,6 +2095,37 @@ remaining_arguments (tree arg)
   return n;
 }
 
+/* [over.match.copy]: When initializing a temporary object (12.2) to be bound
+   to the first parameter of a constructor where the parameter is of type
+   "reference to possibly cv-qualified T" and the constructor is called with a
+   single argument in the context of direct-initialization of an object of type
+   "cv2 T", explicit conversion functions are also considered.
+
+   So set LOOKUP_COPY_PARM to let reference_binding know that
+   it's being called in that context.  */
+
+int
+conv_flags (int i, int nargs, tree fn, tree arg, int flags)
+{
+  int lflags = flags;
+  tree t;
+  if (i == 0 && nargs == 1 && DECL_CONSTRUCTOR_P (fn)
+      && (t = FUNCTION_FIRST_USER_PARMTYPE (fn))
+      && (same_type_ignoring_top_level_qualifiers_p
+         (non_reference (TREE_VALUE (t)), DECL_CONTEXT (fn))))
+    {
+      if (!(flags & LOOKUP_ONLYCONVERTING))
+       lflags |= LOOKUP_COPY_PARM;
+      if ((flags & LOOKUP_LIST_INIT_CTOR)
+         && BRACE_ENCLOSED_INITIALIZER_P (arg))
+       lflags |= LOOKUP_NO_CONVERSION;
+    }
+  else
+    lflags |= LOOKUP_ONLYCONVERTING;
+
+  return lflags;
+}
+
 /* Create an overload candidate for the function or method FN called
    with the argument list FIRST_ARG/ARGS and add it to CANDIDATES.
    FLAGS is passed on to implicit_conversion.
@@ -1986,11 +2140,11 @@ add_function_candidate (struct z_candidate **candidates,
                        tree fn, tree ctype, tree first_arg,
                        const vec<tree, va_gc> *args, tree access_path,
                        tree conversion_path, int flags,
+                       conversion **convs,
                        tsubst_flags_t complain)
 {
   tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
   int i, len;
-  conversion **convs;
   tree parmnode;
   tree orig_first_arg = first_arg;
   int skip;
@@ -2022,7 +2176,8 @@ add_function_candidate (struct z_candidate **candidates,
     skip = 0;
 
   len = vec_safe_length (args) - skip + (first_arg != NULL_TREE ? 1 : 0);
-  convs = alloc_conversions (len);
+  if (!convs)
+    convs = alloc_conversions (len);
 
   /* 13.3.2 - Viable functions [over.match.viable]
      First, to be a viable function, a candidate function shall have enough
@@ -2119,6 +2274,13 @@ add_function_candidate (struct z_candidate **candidates,
       if (parmnode == void_list_node)
        break;
 
+      if (convs[i])
+       {
+         /* Already set during deduction.  */
+         parmnode = TREE_CHAIN (parmnode);
+         continue;
+       }
+
       if (i == 0 && first_arg != NULL_TREE)
        arg = first_arg;
       else
@@ -2132,7 +2294,6 @@ add_function_candidate (struct z_candidate **candidates,
       if (parmnode)
        {
          tree parmtype = TREE_VALUE (parmnode);
-         int lflags = flags;
 
          parmnode = TREE_CHAIN (parmnode);
 
@@ -2170,32 +2331,7 @@ add_function_candidate (struct z_candidate **candidates,
                }
            }
 
-         /* Core issue 899: When [copy-]initializing a temporary to be bound
-            to the first parameter of a copy constructor (12.8) called with
-            a single argument in the context of direct-initialization,
-            explicit conversion functions are also considered.
-
-            So set LOOKUP_COPY_PARM to let reference_binding know that
-            it's being called in that context.  We generalize the above
-            to handle move constructors and template constructors as well;
-            the standardese should soon be updated similarly.  */
-         if (ctype && i == 0 && (len-skip == 1)
-             && DECL_CONSTRUCTOR_P (fn)
-             && parmtype != error_mark_node
-             && (same_type_ignoring_top_level_qualifiers_p
-                 (non_reference (parmtype), ctype)))
-           {
-             if (!(flags & LOOKUP_ONLYCONVERTING))
-               lflags |= LOOKUP_COPY_PARM;
-             /* We allow user-defined conversions within init-lists, but
-                don't list-initialize the copy parm, as that would mean
-                using two levels of braces for the same type.  */
-             if ((flags & LOOKUP_LIST_INIT_CTOR)
-                 && BRACE_ENCLOSED_INITIALIZER_P (arg))
-               lflags |= LOOKUP_NO_CONVERSION;
-           }
-         else
-           lflags |= LOOKUP_ONLYCONVERTING;
+         int lflags = conv_flags (i, len-skip, fn, arg, flags);
 
          t = implicit_conversion (parmtype, argtype, arg,
                                   /*c_cast_p=*/false, lflags, complain);
@@ -2215,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));
+
        }
     }
 
@@ -2311,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)
@@ -2372,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;
     }
@@ -2397,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]));
        }
     }
 
@@ -2844,7 +2986,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
      we need candidates for both of them.  */
   if (type2 && !same_type_p (type1, type2)
       && TREE_CODE (type1) == TREE_CODE (type2)
-      && (TREE_CODE (type1) == REFERENCE_TYPE
+      && (TYPE_REF_P (type1)
          || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
          || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
          || TYPE_PTRMEMFUNC_P (type1)
@@ -3006,11 +3148,11 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
              type = TREE_TYPE (convs);
 
              if (i == 0 && ref1
-                 && (TREE_CODE (type) != REFERENCE_TYPE
+                 && (!TYPE_REF_P (type)
                      || CP_TYPE_CONST_P (TREE_TYPE (type))))
                continue;
 
-             if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE)
+             if (code == COND_EXPR && TYPE_REF_P (type))
                vec_safe_push (types[i], type);
 
              type = non_reference (type);
@@ -3099,6 +3241,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
   tree fn;
   struct rejection_reason *reason = NULL;
   int errs;
+  conversion **convs = NULL;
 
   /* We don't do deduction on the in-charge parameter, the VTT
      parameter or 'this'.  */
@@ -3173,11 +3316,13 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
   gcc_assert (ia == nargs_without_in_chrg);
 
   errs = errorcount+sorrycount;
+  if (!obj)
+    convs = alloc_conversions (nargs);
   fn = fn_type_unification (tmpl, explicit_targs, targs,
                            args_without_in_chrg,
                            nargs_without_in_chrg,
-                           return_type, strict, flags, false,
-                           complain & tf_decltype);
+                           return_type, strict, flags, convs,
+                           false, complain & tf_decltype);
 
   if (fn == error_mark_node)
     {
@@ -3192,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);
@@ -3213,7 +3364,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
   else
     cand = add_function_candidate (candidates, fn, ctype,
                                   first_arg, arglist, access_path,
-                                  conversion_path, flags, complain);
+                                  conversion_path, flags, convs, complain);
   if (DECL_TI_TEMPLATE (fn) != tmpl)
     /* This situation can occur if a member template of a template
        class is specialized.  Then, instantiate_template might return
@@ -3271,10 +3422,10 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
                             tree return_type, tree access_path,
                             tree conversion_path, tsubst_flags_t complain)
 {
-  /* Making this work broke PR 71117, so until the committee resolves core
-     issue 2189, let's disable this candidate if there are any viable call
+  /* Making this work broke PR 71117 and 85118, so until the committee resolves
+     core issue 2189, let's disable this candidate if there are any call
      operators.  */
-  if (any_strictly_viable (*candidates))
+  if (*candidates)
     return NULL;
 
   return
@@ -3390,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))
@@ -3424,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
@@ -3500,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 "
@@ -3538,7 +3694,7 @@ print_z_candidate (location_t loc, const char *msgstr,
                               r->u.template_unification.return_type,
                               r->u.template_unification.strict,
                               r->u.template_unification.flags,
-                              true, false);
+                              NULL, true, false);
          break;
        case rr_invalid_copy:
          inform (cloc,
@@ -3639,6 +3795,12 @@ merge_conversion_sequences (conversion *user_seq, conversion *std_seq)
        (*t)->bad_p = true;
     }
 
+  if ((*t)->rvaluedness_matches_p)
+    /* We're binding a reference directly to the result of the conversion.
+       build_user_type_conversion_1 stripped the REFERENCE_TYPE from the return
+       type, but we want it back.  */
+    user_seq->type = TREE_TYPE (TREE_TYPE (user_seq->cand->fn));
+
   /* Replace the identity conversion with the user conversion
      sequence.  */
   *t = user_seq;
@@ -3745,14 +3907,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
        creating a garbage BASELINK; constructors can't be inherited.  */
     ctors = get_class_binding (totype, complete_ctor_identifier);
 
-  /* FIXME P0135 doesn't say what to do in C++17 about list-initialization from
-     a single element.  For now, let's handle constructors as before and also
-     consider conversion operators from the element.  */
-  if (cxx_dialect >= cxx17
-      && BRACE_ENCLOSED_INITIALIZER_P (expr)
-      && CONSTRUCTOR_NELTS (expr) == 1)
-    fromtype = TREE_TYPE (CONSTRUCTOR_ELT (expr, 0)->value);
-
   if (MAYBE_CLASS_TYPE_P (fromtype))
     {
       tree to_nonref = non_reference (totype);
@@ -3819,7 +3973,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
 
             We represent this in the conversion sequence with an
             rvalue conversion, which means a constructor call.  */
-         if (TREE_CODE (totype) != REFERENCE_TYPE
+         if (!TYPE_REF_P (totype)
              && !(convflags & LOOKUP_NO_TEMP_BIND))
            cand->second_conv
              = build_conv (ck_rvalue, totype, cand->second_conv);
@@ -3829,7 +3983,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
   if (conv_fns)
     {
       if (BRACE_ENCLOSED_INITIALIZER_P (expr))
-       /* FIXME see above about C++17.  */
        first_arg = CONSTRUCTOR_ELT (expr, 0)->value;
       else
        first_arg = expr;
@@ -3844,7 +3997,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
         find a direct binding, so don't even consider temporaries.  If
         we don't find a direct binding, the caller will try again to
         look for a temporary binding.  */
-      if (TREE_CODE (totype) == REFERENCE_TYPE)
+      if (TYPE_REF_P (totype))
        convflags |= LOOKUP_NO_TEMP_BIND;
 
       old_candidates = candidates;
@@ -3883,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)
@@ -3903,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)
@@ -3927,10 +4082,11 @@ 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)
        {
+         auto_diagnostic_group d;
          error ("conversion from %qH to %qI is ambiguous",
                 fromtype, totype);
          print_z_candidates (location_of (expr), candidates);
@@ -3941,6 +4097,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
       cand->second_conv->user_conv_p = true;
       if (!any_strictly_viable (candidates))
        cand->second_conv->bad_p = true;
+      if (flags & LOOKUP_ONLYCONVERTING)
+       cand->second_conv->need_temporary_p = true;
       /* If there are viable candidates, don't set ICS_BAD_FLAG; an
         ambiguous conversion is no worse than another user-defined
         conversion.  */
@@ -3967,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;
@@ -4023,7 +4189,7 @@ build_converted_constant_expr (tree type, tree expr, tsubst_flags_t complain)
   conversion *conv;
   void *p;
   tree t;
-  location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+  location_t loc = cp_expr_loc_or_loc (expr, input_location);
 
   if (error_operand_p (expr))
     return error_mark_node;
@@ -4117,9 +4283,18 @@ build_converted_constant_expr (tree type, tree expr, tsubst_flags_t complain)
     }
 
   if (conv)
-    expr = convert_like (conv, expr, complain);
+    {
+      conv->check_narrowing = true;
+      conv->check_narrowing_const_only = true;
+      expr = convert_like (conv, expr, complain);
+    }
   else
-    expr = error_mark_node;
+    {
+      if (complain & tf_error)
+       error_at (loc, "could not convert %qE from %qH to %qI", expr,
+                 TREE_TYPE (expr), type);
+      expr = error_mark_node;
+    }
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -4145,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 (input_location, arg, complain))
+      else if (invalid_nonstatic_memfn_p (EXPR_LOCATION (arg), arg, complain))
        return NULL;
     }
   return args;
@@ -4232,6 +4407,7 @@ print_error_for_call_failure (tree fn, vec<tree, va_gc> *args,
   if (targs)
     name = lookup_template_function (name, targs);
 
+  auto_diagnostic_group d;
   if (!any_strictly_viable (candidates))
     error_at (loc, "no matching function for call to %<%D(%A)%>",
              name, build_tree_list_vec (args));
@@ -4514,7 +4690,7 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
 
       if (TYPE_PTRFN_P (totype)
          || TYPE_REFFN_P (totype)
-         || (TREE_CODE (totype) == REFERENCE_TYPE
+         || (TYPE_REF_P (totype)
              && TYPE_PTRFN_P (TREE_TYPE (totype))))
        for (ovl_iterator iter (TREE_VALUE (convs)); iter; ++iter)
          {
@@ -4542,6 +4718,7 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
     {
       if (complain & tf_error)
         {
+          auto_diagnostic_group d;
           error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj),
                 build_tree_list_vec (*args));
           print_z_candidates (location_of (TREE_TYPE (obj)), candidates);
@@ -4555,6 +4732,7 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
        {
           if (complain & tf_error)
             {
+              auto_diagnostic_group d;
               error ("call of %<(%T) (%A)%> is ambiguous", 
                      TREE_TYPE (obj), build_tree_list_vec (*args));
               print_z_candidates (location_of (TREE_TYPE (obj)), candidates);
@@ -4621,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;
@@ -4675,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),
@@ -4775,14 +4958,15 @@ 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;
   tree arg3_type;
   tree result = NULL_TREE;
   tree result_type = NULL_TREE;
-  bool is_lvalue = true;
+  bool is_glvalue = true;
   struct z_candidate *candidates = 0;
   struct z_candidate *cand;
   void *p;
@@ -4969,67 +5153,57 @@ 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))
     {
-      /* Do the conversions.  We don't these for `void' type arguments
-        since it can't have any effect and since decay_conversion
-        does not handle that case gracefully.  */
-      if (!VOID_TYPE_P (arg2_type))
-       arg2 = decay_conversion (arg2, complain);
-      if (!VOID_TYPE_P (arg3_type))
-       arg3 = decay_conversion (arg3, complain);
-      arg2_type = TREE_TYPE (arg2);
-      arg3_type = TREE_TYPE (arg3);
+      /* '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:
 
         --The second or the third operand (but not both) is a
-          throw-expression (_except.throw_); the result is of the
-          type of the other and is an rvalue.
+          throw-expression (_except.throw_); the result is of the type
+          and value category of the other.
 
         --Both the second and the third operands have type void; the
-          result is of type void and is an rvalue.
-
-        We must avoid calling force_rvalue for expressions of type
-        "void" because it will complain that their value is being
-        used.  */
+          result is of type void and is a prvalue.  */
       if (TREE_CODE (arg2) == THROW_EXPR
          && TREE_CODE (arg3) != THROW_EXPR)
        {
-         if (!VOID_TYPE_P (arg3_type))
-           {
-             arg3 = force_rvalue (arg3, complain);
-             if (arg3 == error_mark_node)
-               return error_mark_node;
-           }
-         arg3_type = TREE_TYPE (arg3);
          result_type = arg3_type;
+         is_glvalue = glvalue_p (arg3);
        }
       else if (TREE_CODE (arg2) != THROW_EXPR
               && TREE_CODE (arg3) == THROW_EXPR)
        {
-         if (!VOID_TYPE_P (arg2_type))
-           {
-             arg2 = force_rvalue (arg2, complain);
-             if (arg2 == error_mark_node)
-               return error_mark_node;
-           }
-         arg2_type = TREE_TYPE (arg2);
          result_type = arg2_type;
+         is_glvalue = glvalue_p (arg2);
        }
       else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
-       result_type = void_type_node;
+       {
+         result_type = void_type_node;
+         is_glvalue = false;
+       }
       else
        {
           if (complain & tf_error)
             {
               if (VOID_TYPE_P (arg2_type))
-                error_at (EXPR_LOC_OR_LOC (arg3, loc),
+                error_at (cp_expr_loc_or_loc (arg3, loc),
                          "second operand to the conditional operator "
                          "is of type %<void%>, but the third operand is "
                          "neither a throw-expression nor of type %<void%>");
               else
-                error_at (EXPR_LOC_OR_LOC (arg2, loc),
+                error_at (cp_expr_loc_or_loc (arg2, loc),
                          "third operand to the conditional operator "
                          "is of type %<void%>, but the second operand is "
                          "neither a throw-expression nor of type %<void%>");
@@ -5037,7 +5211,6 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
          return error_mark_node;
        }
 
-      is_lvalue = false;
       goto valid_operands;
     }
   /* [expr.cond]
@@ -5167,7 +5340,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
      cv-qualified) class type, overload resolution is used to
      determine the conversions (if any) to be applied to the operands
      (_over.match.oper_, _over.built_).  */
-  is_lvalue = false;
+  is_glvalue = false;
   if (!same_type_p (arg2_type, arg3_type)
       && (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type)))
     {
@@ -5205,6 +5378,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
        {
           if (complain & tf_error)
             {
+              auto_diagnostic_group d;
               op_error (loc, COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
               print_z_candidates (loc, candidates);
             }
@@ -5278,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)
@@ -5348,6 +5525,13 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
     return error_mark_node;
 
  valid_operands:
+  if (processing_template_decl && is_glvalue)
+    {
+      /* Let lvalue_kind know this was a glvalue.  */
+      tree arg = (result_type == arg2_type ? arg2 : arg3);
+      result_type = cp_build_reference_type (result_type, xvalue_p (arg));
+    }
+
   result = build3_loc (loc, COND_EXPR, result_type, arg1, arg2, arg3);
 
   /* If the ARG2 and ARG3 are the same and don't have side-effects,
@@ -5361,7 +5545,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
   /* We can't use result_type below, as fold might have returned a
      throw_expr.  */
 
-  if (!is_lvalue)
+  if (!is_glvalue)
     {
       /* Expand both sides into the same slot, hopefully the target of
         the ?: expression.  We used to check for TARGET_EXPRs here,
@@ -5382,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;
@@ -5532,6 +5717,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
                                access_path,
                                conversion_path,
                                flags,
+                               NULL,
                                complain);
     }
 }
@@ -5570,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;
@@ -5729,7 +5916,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
            {
              parmtype = TREE_VALUE (parmlist);
 
-             if (TREE_CODE (parmtype) == REFERENCE_TYPE)
+             if (TYPE_REF_P (parmtype))
                parmtype = TREE_TYPE (parmtype);
              if (TREE_CODE (TREE_TYPE (args[i])) == ENUMERAL_TYPE
                  && (same_type_ignoring_top_level_qualifiers_p
@@ -5828,6 +6015,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
                  {
                    /* ... Otherwise, report the more generic
                       "no matching operator found" error */
+                   auto_diagnostic_group d;
                    op_error (loc, code, code2, arg1, arg2, arg3, FALSE);
                    print_z_candidates (loc, candidates);
                  }
@@ -5843,6 +6031,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
        {
          if (complain & tf_error)
            {
+             auto_diagnostic_group d;
              op_error (loc, code, code2, arg1, arg2, arg3, TRUE);
              print_z_candidates (loc, candidates);
            }
@@ -6048,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)
 {
@@ -6111,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.  */
@@ -6128,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;
@@ -6163,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)))
@@ -6228,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)
@@ -6279,14 +6498,18 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
             -Wc++14-compat.  */
          else if (!flag_sized_deallocation)
            {
-             if ((complain & tf_warning)
-                 && warning (OPT_Wc__14_compat, msg1))
-               inform (DECL_SOURCE_LOCATION (fn), msg2, fn);
+             if (complain & tf_warning)
+               {
+                 auto_diagnostic_group d;
+                 if (warning (OPT_Wc__14_compat, msg1))
+                   inform (DECL_SOURCE_LOCATION (fn), msg2, fn);
+               }
              goto ok;
            }
 
          if (complain & tf_warning_or_error)
            {
+             auto_diagnostic_group d;
              if (permerror (input_location, msg1))
                {
                  /* Only mention C++14 for namespace-scope delete.  */
@@ -6319,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
@@ -6401,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))
@@ -6437,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
@@ -6461,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;
     }
 
@@ -6531,7 +6792,24 @@ 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.
    FN and ARGNUM are used for diagnostics.  */
 
@@ -6542,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);
@@ -6558,14 +6839,28 @@ 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
+     than EQ_EXPR and NE_EXPR */
+  else if (null_ptr_cst_p (expr) &&
+          (TYPE_PTR_OR_PTRMEM_P (totype) || NULLPTR_TYPE_P (totype)))
+    {
+      location_t loc = get_location_for_expr_unwinding_for_system_header (expr);
+      maybe_warn_zero_as_null_pointer_constant (expr, loc);
+    }
 }
 
 /* We gave a diagnostic during a conversion.  If this was in the second
@@ -6589,9 +6884,14 @@ maybe_print_user_conv_context (conversion *convs)
    ARGNUM is zero based, -1 indicates the `this' argument of a method.
    Return the location of the FNDECL itself if there are problems.  */
 
-static location_t
+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;
 
@@ -6609,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
@@ -6627,7 +6939,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
   tree totype = convs->type;
   diagnostic_t diag_kind;
   int flags;
-  location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+  location_t loc = cp_expr_loc_or_loc (expr, input_location);
 
   if (convs->bad_p && !(complain & tf_error))
     return error_mark_node;
@@ -6670,6 +6982,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        {
          if (t->kind == ck_user && t->cand->reason)
            {
+             auto_diagnostic_group d;
              complained = permerror (loc, "invalid user-defined conversion "
                                      "from %qH to %qI", TREE_TYPE (expr),
                                      totype);
@@ -6685,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)
@@ -6707,11 +7019,15 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            break;
        }
       if (!complained)
-       complained = permerror (loc, "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);
+       {
+         range_label_for_type_mismatch label (TREE_TYPE (expr), totype);
+         gcc_rich_location richloc (loc, &label);
+         complained = permerror (&richloc,
+                                 "invalid conversion from %qH to %qI",
+                                 TREE_TYPE (expr), totype);
+       }
+      if (complained)
+       maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
 
       return cp_convert (totype, expr, complain);
     }
@@ -6738,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)
          {
@@ -6748,6 +7064,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            if (CONSTRUCTOR_NELTS (expr) == 0
                && FUNCTION_FIRST_USER_PARMTYPE (convfn) != void_list_node)
              {
+               auto_diagnostic_group d;
                if (pedwarn (loc, 0, "converting to %qT from initializer list "
                             "would use explicit constructor %qD",
                             totype, convfn))
@@ -6762,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))
@@ -6777,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.  */
@@ -6828,11 +7148,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       if (complain & tf_error)
        {
          /* Call build_user_type_conversion again for the error.  */
-         build_user_type_conversion (totype, convs->u.expr, LOOKUP_IMPLICIT,
-                                     complain);
-         if (fn)
-           inform (DECL_SOURCE_LOCATION (fn),
-                   "  initializing argument %P of %qD", argnum, fn);
+         int flags = (convs->need_temporary_p
+                      ? LOOKUP_IMPLICIT : LOOKUP_NORMAL);
+         build_user_type_conversion (totype, convs->u.expr, flags, complain);
+         gcc_assert (seen_error ());
+         maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
        }
       return error_mark_node;
 
@@ -6840,45 +7160,58 @@ 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;
 
-       /* Build up the initializer_list object.  */
-       totype = complete_type (totype);
-       field = next_initializable_field (TYPE_FIELDS (totype));
+       /* Build up the initializer_list object.  Note: fail gracefully
+          if the object cannot be completed because, for example, no
+          definition is provided (c++/80956).  */
+       totype = complete_type_or_maybe_complain (totype, NULL_TREE, complain);
+       if (!totype)
+         return error_mark_node;
+       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);
       }
 
@@ -6920,10 +7253,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        {
          if (complain & tf_error)
            {
+             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;
        }
@@ -6938,6 +7270,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
          && DECL_INHERITED_CTOR (current_function_decl))
        return expr;
 
+      if (TREE_CODE (expr) == TARGET_EXPR
+         && TARGET_EXPR_LIST_INIT_P (expr))
+       /* Copy-list-initialization doesn't actually involve a copy.  */
+       return expr;
+
       /* Fall through.  */
     case ck_base:
       if (convs->kind == ck_base && !convs->need_temporary_p)
@@ -6964,17 +7301,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       if (convs->rvaluedness_matches_p)
        /* standard_conversion got LOOKUP_PREFER_RVALUE.  */
        flags |= LOOKUP_PREFER_RVALUE;
-      if (TREE_CODE (expr) == TARGET_EXPR
-         && TARGET_EXPR_LIST_INIT_P (expr))
-       /* Copy-list-initialization doesn't actually involve a copy.  */
-       return expr;
       expr = build_temp (expr, totype, flags, &diag_kind, complain);
       if (diag_kind && complain)
        {
+         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);
@@ -6986,6 +7318,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        if (convs->bad_p && !next_conversion (convs)->bad_p)
          {
            tree extype = TREE_TYPE (expr);
+           auto_diagnostic_group d;
            if (TYPE_REF_IS_RVALUE (ref_type)
                && lvalue_p (expr))
              error_at (loc, "cannot bind rvalue reference of type %qH to "
@@ -7000,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;
          }
 
@@ -7106,9 +7438,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     }
 
   if (convs->check_narrowing
-      && !check_narrowing (totype, expr, complain))
+      && !check_narrowing (totype, expr, complain,
+                          convs->check_narrowing_const_only))
     return error_mark_node;
 
+  warning_sentinel w (warn_zero_as_null_pointer_constant);
   if (issue_conversion_warnings)
     expr = cp_convert_and_check (totype, expr, complain);
   else
@@ -7124,7 +7458,7 @@ tree
 convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
 {
   tree arg_type;
-  location_t loc = EXPR_LOC_OR_LOC (arg, input_location);
+  location_t loc = cp_expr_loc_or_loc (arg, input_location);
 
   /* [expr.call]
 
@@ -7165,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;
@@ -7204,7 +7538,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
                     "passing objects of non-trivially-copyable "
                     "type %q#T through %<...%> is conditionally supported",
                     arg_type);
-         return cp_build_addr_expr (arg, complain);
+         return build1 (ADDR_EXPR, build_reference_type (arg_type), arg);
        }
       /* Build up a real lvalue-to-rvalue conversion in case the
         copy constructor is trivial but not callable.  */
@@ -7219,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)
     {
@@ -7235,7 +7569,7 @@ build_x_va_arg (source_location loc, tree expr, tree type)
 
   expr = mark_lvalue_use (expr);
 
-  if (TREE_CODE (type) == REFERENCE_TYPE)
+  if (TYPE_REF_P (type))
     {
       error ("cannot receive reference type %qT through %<...%>", type);
       return error_mark_node;
@@ -7346,7 +7680,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum,
   push_deferring_access_checks (dk_no_check);
   /* We must make a copy of ARG, in case subsequent processing
      alters any part of it.  */
-  arg = break_out_target_exprs (arg);
+  arg = break_out_target_exprs (arg, /*clear location*/true);
+
   arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
                                    ICR_DEFAULT_ARGUMENT, fn, parmnum,
                                    complain);
@@ -7430,8 +7765,12 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
                     "argument of function call might be a candidate "
                     "for a format attribute");
        }
-      maybe_warn_parm_abi (type, EXPR_LOC_OR_LOC (val, input_location));
+      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;
 }
 
@@ -7579,10 +7918,69 @@ unsafe_copy_elision_p (tree target, tree exp)
   /* build_compound_expr pushes COMPOUND_EXPR inside TARGET_EXPR.  */
   while (TREE_CODE (init) == COMPOUND_EXPR)
     init = TREE_OPERAND (init, 1);
+  if (TREE_CODE (init) == COND_EXPR)
+    {
+      /* We'll end up copying from each of the arms of the COND_EXPR directly
+        into the target, so look at them. */
+      if (tree op = TREE_OPERAND (init, 1))
+       if (unsafe_copy_elision_p (target, op))
+         return true;
+      return unsafe_copy_elision_p (target, TREE_OPERAND (init, 2));
+    }
   return (TREE_CODE (init) == AGGR_INIT_EXPR
          && !AGGR_INIT_VIA_CTOR_P (init));
 }
 
+/* True iff C is a conversion that binds a reference to a prvalue.  */
+
+static bool
+conv_binds_ref_to_prvalue (conversion *c)
+{
+  if (c->kind != ck_ref_bind)
+    return false;
+  if (c->need_temporary_p)
+    return true;
+
+  c = next_conversion (c);
+
+  if (c->kind == ck_rvalue)
+    return true;
+  if (c->kind == ck_user && !TYPE_REF_P (c->type))
+    return true;
+  if (c->kind == ck_identity && c->u.expr
+      && TREE_CODE (c->u.expr) == TARGET_EXPR)
+    return true;
+
+  return false;
+}
+
+/* Call the trivial destructor for INSTANCE, which can be either an lvalue of
+   class type or a pointer to class type.  */
+
+tree
+build_trivial_dtor_call (tree instance)
+{
+  gcc_assert (!is_dummy_object (instance));
+
+  if (!flag_lifetime_dse)
+    {
+    no_clobber:
+      return fold_convert (void_type_node, instance);
+    }
+
+  if (INDIRECT_TYPE_P (TREE_TYPE (instance)))
+    {
+      if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (instance))))
+       goto no_clobber;
+      instance = cp_build_fold_indirect_ref (instance);
+    }
+
+  /* A trivial destructor should still clobber the object.  */
+  tree clobber = build_clobber (TREE_TYPE (instance));
+  return build2 (MODIFY_EXPR, void_type_node,
+                instance, clobber);
+}
+
 /* Subroutine of the various build_*_call functions.  Overload resolution
    has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
    ARGS is a TREE_LIST of the unconverted arguments to the call.  FLAGS is a
@@ -7620,6 +8018,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 
       if (undeduced_auto_decl (fn))
        mark_used (fn, complain);
+      else
+       /* Otherwise set TREE_USED for the benefit of -Wunused-function.
+          See PR80598.  */
+       TREE_USED (fn) = 1;
 
       return_type = TREE_TYPE (TREE_TYPE (fn));
       nargs = vec_safe_length (args);
@@ -7657,6 +8059,22 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        joust (cand, w->loser, 1, complain);
     }
 
+  /* Core issue 2327: P0135 doesn't say how to handle the case where the
+     argument to the copy constructor ends up being a prvalue after
+     conversion.  Let's do the normal processing, but pretend we aren't
+     actually using the copy constructor.  */
+  bool force_elide = false;
+  if (cxx_dialect >= cxx17
+      && cand->num_convs == 1
+      && DECL_COMPLETE_CONSTRUCTOR_P (fn)
+      && (DECL_COPY_CONSTRUCTOR_P (fn)
+         || DECL_MOVE_CONSTRUCTOR_P (fn))
+      && conv_binds_ref_to_prvalue (convs[0]))
+    {
+      force_elide = true;
+      goto not_really_used;
+    }
+
   /* OK, we're actually calling this inherited constructor; set its deletedness
      appropriately.  We can get away with doing this here because calling is
      the only way to refer to a constructor.  */
@@ -7664,8 +8082,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
     deduce_inheriting_ctor (fn);
 
   /* Make =delete work with SFINAE.  */
-  if (DECL_DELETED_FN (fn) && !(complain & tf_error))
-    return error_mark_node;
+  if (DECL_DELETED_FN (fn))
+    {
+      if (complain & tf_error)
+       mark_used (fn);
+      return error_mark_node;
+    }
 
   if (DECL_FUNCTION_MEMBER_P (fn))
     {
@@ -7709,12 +8131,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
      conversions.  */
   if (flags & LOOKUP_SPECULATIVE)
     {
-      if (DECL_DELETED_FN (fn))
-       {
-         if (complain & tf_error)
-           mark_used (fn);
-         return error_mark_node;
-       }
       if (cand->viable == 1)
        return fn;
       else if (!(complain & tf_error))
@@ -7723,6 +8139,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       /* else continue to get conversion error.  */
     }
 
+ not_really_used:
+
   /* N3276 magic doesn't apply to nested calls.  */
   tsubst_flags_t decltype_flag = (complain & tf_decltype);
   complain &= ~tf_decltype;
@@ -7768,10 +8186,10 @@ 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 object’s type (possibly cv-qualified)...." */
+            reference to the object's type (possibly cv-qualified)...." */
          gcc_assert (!(complain & tf_error));
          tree ptype = convs[0]->type;
-         if (TREE_CODE (ptype) != REFERENCE_TYPE
+         if (!TYPE_REF_P (ptype)
              || !TYPE_REF_IS_RVALUE (ptype)
              || CONVERSION_RANK (convs[0]) > cr_exact)
            return error_mark_node;
@@ -7795,6 +8213,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        {
          if (complain & tf_error)
            {
+             auto_diagnostic_group d;
              if (permerror (input_location, "passing %qT as %<this%> "
                             "argument discards qualifiers",
                             TREE_TYPE (argtype)))
@@ -7916,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%>)");
            }
        }
 
@@ -8002,7 +8422,15 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       tree *fargs = (!nargs ? argarray
                            : (tree *) alloca (nargs * sizeof (tree)));
       for (j = 0; j < nargs; j++)
-       fargs[j] = maybe_constant_value (argarray[j]);
+       {
+         /* For -Wformat undo the implicit passing by hidden reference
+            done by convert_arg_to_ellipsis.  */
+         if (TREE_CODE (argarray[j]) == ADDR_EXPR
+             && TYPE_REF_P (TREE_TYPE (argarray[j])))
+           fargs[j] = TREE_OPERAND (argarray[j], 0);
+         else
+           fargs[j] = argarray[j];
+       }
 
       warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn),
                                           nargs, fargs, NULL);
@@ -8035,7 +8463,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
   /* Avoid actually calling copy constructors and copy assignment operators,
      if possible.  */
 
-  if (! flag_elide_constructors)
+  if (! flag_elide_constructors && !force_elide)
     /* Do things the hard way.  */;
   else if (cand->num_convs == 1 
            && (DECL_COPY_CONSTRUCTOR_P (fn) 
@@ -8043,7 +8471,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
           /* It's unsafe to elide the constructor when handling
              a noexcept-expression, it may evaluate to the wrong
              value (c++/53025).  */
-          && cp_noexcept_operand == 0)
+          && (force_elide || cp_noexcept_operand == 0))
     {
       tree targ;
       tree arg = argarray[num_artificial_parms_for (fn)];
@@ -8054,12 +8482,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       targ = arg;
       /* Strip the reference binding for the constructor parameter.  */
       if (CONVERT_EXPR_P (targ)
-         && TREE_CODE (TREE_TYPE (targ)) == REFERENCE_TYPE)
+         && TYPE_REF_P (TREE_TYPE (targ)))
        targ = TREE_OPERAND (targ, 0);
       /* But don't strip any other reference bindings; binding a temporary to a
         reference prevents copy elision.  */
       while ((CONVERT_EXPR_P (targ)
-             && TREE_CODE (TREE_TYPE (targ)) != REFERENCE_TYPE)
+             && !TYPE_REF_P (TREE_TYPE (targ)))
             || TREE_CODE (targ) == NON_LVALUE_EXPR)
        targ = TREE_OPERAND (targ, 0);
       if (TREE_CODE (targ) == ADDR_EXPR)
@@ -8081,27 +8509,37 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
         subobject.  */
       if (CHECKING_P && cxx_dialect >= cxx17)
        gcc_assert (TREE_CODE (arg) != TARGET_EXPR
+                   || force_elide
                    /* It's from binding the ref parm to a packed field. */
                    || convs[0]->need_temporary_p
                    || seen_error ()
                    /* See unsafe_copy_elision_p.  */
                    || DECL_BASE_CONSTRUCTOR_P (fn));
 
-      /* [class.copy]: the copy constructor is implicitly defined even if
-        the implementation elided its use.  */
-      if (!trivial || DECL_DELETED_FN (fn))
+      fa = argarray[0];
+      bool unsafe = unsafe_copy_elision_p (fa, arg);
+      bool eliding_temp = (TREE_CODE (arg) == TARGET_EXPR && !unsafe);
+
+      /* [class.copy]: the copy constructor is implicitly defined even if the
+        implementation elided its use.  But don't warn about deprecation when
+        eliding a temporary, as then no copy is actually performed.  */
+      warning_sentinel s (warn_deprecated_copy, eliding_temp);
+      if (force_elide)
+       /* The language says this isn't called.  */;
+      else if (!trivial)
        {
          if (!mark_used (fn, complain) && !(complain & tf_error))
            return error_mark_node;
          already_used = true;
        }
+      else
+       cp_warn_deprecated_use (fn, complain);
 
       /* If we're creating a temp and we already have one, don't create a
         new one.  If we're not creating a temp but we get one, use
         INIT_EXPR to collapse the temp into our target.  Otherwise, if the
         ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
         temp or an INIT_EXPR otherwise.  */
-      fa = argarray[0];
       if (is_dummy_object (fa))
        {
          if (TREE_CODE (arg) == TARGET_EXPR)
@@ -8110,7 +8548,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
            return force_target_expr (DECL_CONTEXT (fn), arg, complain);
        }
       else if ((trivial || TREE_CODE (arg) == TARGET_EXPR)
-              && !unsafe_copy_elision_p (fa, arg))
+              && !unsafe)
        {
          tree to = cp_stabilize_reference (cp_build_fold_indirect_ref (fa));
 
@@ -8120,16 +8558,16 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
     }
   else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
           && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR)
-          && trivial_fn_p (fn)
-          && !DECL_DELETED_FN (fn))
+          && trivial_fn_p (fn))
     {
       tree to = cp_stabilize_reference
        (cp_build_fold_indirect_ref (argarray[0]));
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
       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);
@@ -8137,10 +8575,13 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        }
       else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
        {
+         if (is_std_init_list (type)
+             && conv_binds_ref_to_prvalue (convs[1]))
+           warning_at (loc, OPT_Winit_list_lifetime,
+                       "assignment from temporary initializer_list does not "
+                       "extend the lifetime of the underlying array");
          arg = cp_build_fold_indirect_ref (arg);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
-         /* Handle NSDMI that refer to the object being initialized.  */
-         replace_placeholders (arg, to);
        }
       else
        {
@@ -8163,13 +8604,14 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
           TREE_NO_WARNING (val) = 1;
        }
 
+      cp_warn_deprecated_use (fn, complain);
+
       return val;
     }
-  else if (!DECL_DELETED_FN (fn)
-          && trivial_fn_p (fn))
+  else if (trivial_fn_p (fn))
     {
       if (DECL_DESTRUCTOR_P (fn))
-       return fold_convert (void_type_node, argarray[0]);
+       return build_trivial_dtor_call (argarray[0]);
       else if (default_ctor_p (fn))
        {
          if (is_dummy_object (argarray[0]))
@@ -8180,22 +8622,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        }
     }
 
-  /* For calls to a multi-versioned function, overload resolution
-     returns the function with the highest target priority, that is,
-     the version that will checked for dispatching first.  If this
-     version is inlinable, a direct call to this version can be made
-     otherwise the call should go through the dispatcher.  */
-
-  if (DECL_FUNCTION_VERSIONED (fn)
-      && (current_function_decl == NULL
-         || !targetm.target_option.can_inline_p (current_function_decl, fn)))
-    {
-      fn = get_function_version_dispatcher (fn);
-      if (fn == NULL)
-       return NULL;
-      if (!already_used)
-       mark_versions_used (fn);
-    }
+  gcc_assert (!force_elide);
 
   if (!already_used
       && !mark_used (fn, complain))
@@ -8207,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])),
@@ -8251,13 +8675,17 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
   return call;
 }
 
-/* Return the DECL of the first non-public data member of class TYPE
-   or null if none can be found.  */
+namespace
+{
 
-static tree
-first_non_public_field (tree type)
+/* Return the DECL of the first non-static subobject of class TYPE
+   that satisfies the predicate PRED or null if none can be found.  */
+
+template <class Predicate>
+tree
+first_non_static_field (tree type, Predicate pred)
 {
-  if (!CLASS_TYPE_P (type))
+  if (!type || !CLASS_TYPE_P (type))
     return NULL_TREE;
 
   for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
@@ -8266,7 +8694,7 @@ first_non_public_field (tree type)
        continue;
       if (TREE_STATIC (field))
        continue;
-      if (TREE_PRIVATE (field) || TREE_PROTECTED (field))
+      if (pred (field))
        return field;
     }
 
@@ -8276,14 +8704,51 @@ first_non_public_field (tree type)
        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
     {
       tree base = TREE_TYPE (base_binfo);
-
-      if (tree field = first_non_public_field (base))
+      if (pred (base))
+       return base;
+      if (tree field = first_non_static_field (base, pred))
        return field;
     }
 
   return NULL_TREE;
 }
 
+struct NonPublicField
+{
+  bool operator() (const_tree t)
+  {
+    return DECL_P (t) && (TREE_PRIVATE (t) || TREE_PROTECTED (t));
+  }
+};
+
+/* Return the DECL of the first non-public subobject of class TYPE
+   or null if none can be found.  */
+
+static inline tree
+first_non_public_field (tree type)
+{
+  return first_non_static_field (type, NonPublicField ());
+}
+
+struct NonTrivialField
+{
+  bool operator() (const_tree t)
+  {
+    return !trivial_type_p (DECL_P (t) ? TREE_TYPE (t) : t);
+  }
+};
+
+/* Return the DECL of the first non-trivial subobject of class TYPE
+   or null if none can be found.  */
+
+static inline tree
+first_non_trivial_field (tree type)
+{
+  return first_non_static_field (type, NonTrivialField ());
+}
+
+}   /* unnamed namespace */
+
 /* Return true if all copy and move assignment operator overloads for
    class TYPE are trivial and at least one of them is not deleted and,
    when ACCESS is set, accessible.  Return false otherwise.  Set
@@ -8397,7 +8862,7 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl,
   unsigned srcidx = !dstidx;
 
   tree dest = (*args)[dstidx];
-  if (!TREE_TYPE (dest) || !POINTER_TYPE_P (TREE_TYPE (dest)))
+  if (!TREE_TYPE (dest) || !INDIRECT_TYPE_P (TREE_TYPE (dest)))
     return;
 
   tree srctype = NULL_TREE;
@@ -8409,22 +8874,21 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl,
   if (!desttype || !COMPLETE_TYPE_P (desttype) || !CLASS_TYPE_P (desttype))
     return;
 
-  /* Check to see if the raw memory call is made by a ctor or dtor
-     with this as the destination argument for the destination type.
-     If so, be more permissive.  */
+  /* Check to see if the raw memory call is made by a non-static member
+     function with THIS as the destination argument for the destination
+     type.  If so, and if the class has no non-trivial bases or members,
+     be more permissive.  */
   if (current_function_decl
-      && (DECL_CONSTRUCTOR_P (current_function_decl)
-         || DECL_DESTRUCTOR_P (current_function_decl))
+      && DECL_NONSTATIC_MEMBER_FUNCTION_P (current_function_decl)
       && is_this_parameter (tree_strip_nop_conversions (dest)))
     {
       tree ctx = DECL_CONTEXT (current_function_decl);
       bool special = same_type_ignoring_top_level_qualifiers_p (ctx, desttype);
-
       tree binfo = TYPE_BINFO (ctx);
 
-      /* A ctor and dtor for a class with no bases and no virtual functions
-        can do whatever they want.  Bail early with no further checking.  */
-      if (special && !BINFO_VTABLE (binfo) && !BINFO_N_BASE_BINFOS (binfo))
+      if (special
+         && !BINFO_VTABLE (binfo)
+         && !first_non_trivial_field (desttype))
        return;
     }
 
@@ -8521,7 +8985,7 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl,
     case BUILT_IN_MEMPCPY:
       /* Determine the type of the source object.  */
       srctype = TREE_TYPE ((*args)[srcidx]);
-      if (!srctype || !POINTER_TYPE_P (srctype))
+      if (!srctype || !INDIRECT_TYPE_P (srctype))
        srctype = void_type_node;
       else
        srctype = TREE_TYPE (srctype);
@@ -8649,7 +9113,7 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
   tree fndecl;
 
   /* Remember roughly where this call is.  */
-  location_t loc = EXPR_LOC_OR_LOC (fn, input_location);
+  location_t loc = cp_expr_loc_or_loc (fn, input_location);
   fn = build_call_a (fn, nargs, argarray);
   SET_EXPR_LOCATION (fn, loc);
 
@@ -8657,15 +9121,15 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
 
   /* Check that arguments to builtin functions match the expectations.  */
   if (fndecl
-      && DECL_BUILT_IN (fndecl)
-      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+      && !processing_template_decl
+      && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     {
       int i;
 
       /* We need to take care that values to BUILT_IN_NORMAL
          are reduced.  */
       for (i = 0; i < nargs; i++)
-       argarray[i] = fold_non_dependent_expr (argarray[i]);
+       argarray[i] = maybe_constant_value (argarray[i]);
 
       if (!check_builtin_function_arguments (EXPR_LOCATION (fn), vNULL, fndecl,
                                             nargs, argarray))
@@ -8729,7 +9193,7 @@ check_self_delegation (tree ret)
 {
   if (TREE_CODE (ret) == TARGET_EXPR)
     ret = TARGET_EXPR_INITIAL (ret);
-  tree fn = cp_get_callee_fndecl (ret);
+  tree fn = cp_get_callee_fndecl_nofold (ret);
   if (fn && DECL_ABSTRACT_ORIGIN (fn) == current_function_decl)
     error ("constructor delegates to itself");
 }
@@ -8758,6 +9222,18 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
   tree ret;
 
   gcc_assert (IDENTIFIER_CDTOR_P (name) || name == assign_op_identifier);
+
+  if (error_operand_p (instance))
+    return error_mark_node;
+
+  if (IDENTIFIER_DTOR_P (name))
+    {
+      gcc_assert (args == NULL || vec_safe_is_empty (*args));
+      if (!type_build_dtor_call (TREE_TYPE (instance)))
+       /* Shortcut to avoid lazy destructor declaration.  */
+       return build_trivial_dtor_call (instance);
+    }
+
   if (TYPE_P (binfo))
     {
       /* Resolve the name.  */
@@ -8776,9 +9252,6 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
     instance = build_dummy_object (class_type);
   else
     {
-      if (IDENTIFIER_DTOR_P (name))
-       gcc_assert (args == NULL || vec_safe_is_empty (*args));
-
       /* Convert to the base class, if necessary.  */
       if (!same_type_ignoring_top_level_qualifiers_p
          (TREE_TYPE (instance), BINFO_TYPE (binfo)))
@@ -8814,18 +9287,11 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
     {
       tree arg = (**args)[0];
 
-      /* FIXME P0135 doesn't say how to handle direct initialization from a
-        type with a suitable conversion operator.  Let's handle it like
-        copy-initialization, but allowing explict conversions.  */
-      tsubst_flags_t sub_complain = tf_warning;
-      if (!is_dummy_object (instance))
-       /* If we're using this to initialize a non-temporary object, don't
-          require the destructor to be accessible.  */
-       sub_complain |= tf_no_cleanup;
-      if (!reference_related_p (class_type, TREE_TYPE (arg)))
-       arg = perform_implicit_conversion_flags (class_type, arg,
-                                                sub_complain,
-                                                flags);
+      if (BRACE_ENCLOSED_INITIALIZER_P (arg)
+         && !TYPE_HAS_LIST_CTOR (class_type)
+         && CONSTRUCTOR_NELTS (arg) == 1)
+       arg = CONSTRUCTOR_ELT (arg, 0)->value;
+
       if ((TREE_CODE (arg) == TARGET_EXPR
           || TREE_CODE (arg) == CONSTRUCTOR)
          && (same_type_ignoring_top_level_qualifiers_p
@@ -8833,6 +9299,9 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
        {
          if (is_dummy_object (instance))
            return arg;
+         else if (TREE_CODE (arg) == TARGET_EXPR)
+           TARGET_EXPR_DIRECT_INIT_P (arg) = true;
+
          if ((complain & tf_error)
              && (flags & LOOKUP_DELEGATING_CONS))
            check_self_delegation (arg);
@@ -8935,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.  */
@@ -9004,14 +9596,6 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
   gcc_assert (CLASS_TYPE_P (basetype));
 
-  if (processing_template_decl)
-    {
-      orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
-      instance = build_non_dependent_expr (instance);
-      if (args != NULL)
-       make_args_non_dependent (*args);
-    }
-
   user_args = args == NULL ? NULL : *args;
   /* Under DR 147 A::A() is an invalid constructor call,
      not a functional cast.  */
@@ -9022,6 +9606,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
 
       basetype = DECL_CONTEXT (fn);
       name = constructor_name (basetype);
+      auto_diagnostic_group d;
       if (permerror (input_location,
                     "cannot call constructor %<%T::%D%> directly",
                     basetype, name))
@@ -9032,12 +9617,21 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
       return call;
     }
 
+  if (processing_template_decl)
+    {
+      orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
+      instance = build_non_dependent_expr (instance);
+      if (args != NULL)
+       make_args_non_dependent (*args);
+    }
+
   /* Process the argument list.  */
   if (args != NULL && *args != NULL)
     {
       *args = resolve_args (*args, complain);
       if (*args == NULL)
        return error_mark_node;
+      user_args = *args;
     }
 
   /* Consider the object argument to be used even if we end up selecting a
@@ -9150,33 +9744,11 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
   if (!any_viable_p)
     {
       if (complain & tf_error)
-       {
-         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
@@ -9194,6 +9766,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
              arglist = build_tree_list_vec (user_args);
              if (skip_first_for_error)
                arglist = TREE_CHAIN (arglist);
+             auto_diagnostic_group d;
              if (!any_strictly_viable (candidates))
                error ("no matching function for call to %<%s(%A)%>",
                       pretty_name, arglist);
@@ -9280,8 +9853,14 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
              if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
                  && !is_dummy_object (instance)
                  && TREE_SIDE_EFFECTS (instance))
-               call = build2 (COMPOUND_EXPR, TREE_TYPE (call),
-                              instance, call);
+               {
+                 /* But avoid the implicit lvalue-rvalue conversion when 'a'
+                    is volatile.  */
+                 tree a = instance;
+                 if (TREE_THIS_VOLATILE (a))
+                   a = build_this (a);
+                 call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call);
+               }
              else if (call != error_mark_node
                       && DECL_DESTRUCTOR_P (cand->fn)
                       && !VOID_TYPE_P (TREE_TYPE (call)))
@@ -9555,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)
        {
@@ -10076,7 +10656,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
          tree t = TREE_TYPE (TREE_TYPE (l->fn));
          tree f = TREE_TYPE (TREE_TYPE (w->fn));
 
-         if (TREE_CODE (t) == TREE_CODE (f) && POINTER_TYPE_P (t))
+         if (TREE_CODE (t) == TREE_CODE (f) && INDIRECT_TYPE_P (t))
            {
              t = TREE_TYPE (t);
              f = TREE_TYPE (f);
@@ -10092,8 +10672,9 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
       else if (warn)
        {
          tree source = source_type (w->convs[0]);
-         if (POINTER_TYPE_P (source))
+         if (INDIRECT_TYPE_P (source))
            source = TREE_TYPE (source);
+         auto_diagnostic_group d;
          if (warning (OPT_Wconversion, "choosing %qD over %qD", w->fn, l->fn)
              && warning (OPT_Wconversion, "  for conversion from %qH to %qI",
                          source, w->second_conv->type)) 
@@ -10321,6 +10902,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
                {
                  if (complain & tf_error)
                    {
+                     auto_diagnostic_group d;
                      if (permerror (input_location,
                                     "default argument mismatch in "
                                     "overload resolution"))
@@ -10347,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))
     {
@@ -10372,12 +10954,15 @@ tweak:
            return 0;
          if (warn)
            {
-             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);
+             auto_diagnostic_group d;
+             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);
@@ -10528,9 +11113,9 @@ perform_implicit_conversion_flags (tree type, tree expr,
 {
   conversion *conv;
   void *p;
-  location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+  location_t loc = cp_expr_loc_or_loc (expr, input_location);
 
-  if (TREE_CODE (type) == REFERENCE_TYPE)
+  if (TYPE_REF_P (type))
     expr = mark_lvalue_use (expr);
   else
     expr = mark_rvalue_use (expr);
@@ -10556,8 +11141,12 @@ perform_implicit_conversion_flags (tree type, tree expr,
          else if (invalid_nonstatic_memfn_p (loc, expr, complain))
            /* We gave an error.  */;
          else
-           error_at (loc, "could not convert %qE from %qH to %qI", expr,
-                     TREE_TYPE (expr), type);
+           {
+             range_label_for_type_mismatch label (TREE_TYPE (expr), type);
+             gcc_rich_location rich_loc (loc, &label);
+             error_at (&rich_loc, "could not convert %qE from %qH to %qI",
+                       expr, TREE_TYPE (expr), type);
+           }
        }
       expr = error_mark_node;
     }
@@ -10571,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);
@@ -10707,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
@@ -10773,6 +11374,8 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
   /* If the initializer is constant, put it in DECL_INITIAL so we get
      static initialization and use in constant expressions.  */
   init = maybe_constant_init (expr);
+  /* As in store_init_value.  */
+  init = cp_fully_fold (init);
   if (TREE_CONSTANT (init))
     {
       if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))
@@ -10781,13 +11384,11 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
             lvalue-rvalue conversion applied to "a glvalue of literal type
             that refers to a non-volatile temporary object initialized
             with a constant expression".  Rather than try to communicate
-            that this VAR_DECL is a temporary, just mark it constexpr.
-
-            Currently this is only useful for initializer_list temporaries,
-            since reference vars can't appear in constant expressions.  */
+            that this VAR_DECL is a temporary, just mark it constexpr.  */
          DECL_DECLARED_CONSTEXPR_P (var) = true;
          DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = true;
          TREE_CONSTANT (var) = true;
+         TREE_READONLY (var) = true;
        }
       DECL_INITIAL (var) = init;
       init = NULL_TREE;
@@ -10862,7 +11463,7 @@ initialize_reference (tree type, tree expr,
 {
   conversion *conv;
   void *p;
-  location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+  location_t loc = cp_expr_loc_or_loc (expr, input_location);
 
   if (type == error_mark_node || error_operand_p (expr))
     return error_mark_node;
@@ -10925,7 +11526,9 @@ extend_ref_init_temps_1 (tree decl, tree init, vec<tree, va_gc> **cleanups)
   if (TREE_CODE (sub) != ADDR_EXPR)
     return init;
   /* Deal with binding to a subobject.  */
-  for (p = &TREE_OPERAND (sub, 0); TREE_CODE (*p) == COMPONENT_REF; )
+  for (p = &TREE_OPERAND (sub, 0);
+       (TREE_CODE (*p) == COMPONENT_REF
+       || TREE_CODE (*p) == ARRAY_REF); )
     p = &TREE_OPERAND (*p, 0);
   if (TREE_CODE (*p) == TARGET_EXPR)
     {
@@ -10950,7 +11553,7 @@ extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **cleanups)
   tree type = TREE_TYPE (init);
   if (processing_template_decl)
     return init;
-  if (TREE_CODE (type) == REFERENCE_TYPE)
+  if (TYPE_REF_P (type))
     init = extend_ref_init_temps_1 (decl, init, cleanups);
   else
     {
@@ -10992,7 +11595,7 @@ bool
 type_has_extended_temps (tree type)
 {
   type = strip_array_types (type);
-  if (TREE_CODE (type) == REFERENCE_TYPE)
+  if (TYPE_REF_P (type))
     return true;
   if (CLASS_TYPE_P (type))
     {