OSDN Git Service

PR c++/20669
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index b33e903..dccb1d4 100644 (file)
@@ -144,9 +144,8 @@ static tree build_java_interface_fn_ref (tree, tree);
 static tree convert_like_real (conversion *, tree, tree, int, int, bool,
                               bool, tsubst_flags_t);
 static void op_error (enum tree_code, enum tree_code, tree, tree,
-                     tree, const char *);
-static tree build_object_call (tree, tree, tsubst_flags_t);
-static tree resolve_args (tree);
+                     tree, bool);
+static VEC(tree,gc) *resolve_args (VEC(tree,gc) *);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
 static void print_z_candidate (const char *, struct z_candidate *);
 static void print_z_candidates (struct z_candidate *);
@@ -154,13 +153,14 @@ static tree build_this (tree);
 static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
 static bool any_strictly_viable (struct z_candidate *);
 static struct z_candidate *add_template_candidate
-       (struct z_candidate **, tree, tree, tree, tree, tree,
-        tree, tree, int, unification_kind_t);
+       (struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
+        tree, tree, tree, int, unification_kind_t);
 static struct z_candidate *add_template_candidate_real
-       (struct z_candidate **, tree, tree, tree, tree, tree,
-        tree, tree, int, tree, unification_kind_t);
+       (struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
+        tree, tree, tree, int, tree, unification_kind_t);
 static struct z_candidate *add_template_conv_candidate
-       (struct z_candidate **, tree, tree, tree, tree, tree, tree);
+       (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+        tree, tree);
 static void add_builtin_candidates
        (struct z_candidate **, enum tree_code, enum tree_code,
         tree, tree *, int);
@@ -172,9 +172,11 @@ static void build_builtin_candidate
        (struct z_candidate **, tree, tree, tree, tree *, tree *,
         int);
 static struct z_candidate *add_conv_candidate
-       (struct z_candidate **, tree, tree, tree, tree, tree);
+       (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+        tree);
 static struct z_candidate *add_function_candidate
-       (struct z_candidate **, tree, tree, tree, tree, tree, int);
+       (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+        tree, int);
 static conversion *implicit_conversion (tree, tree, tree, bool, int);
 static conversion *standard_conversion (tree, tree, tree, bool, int);
 static conversion *reference_binding (tree, tree, tree, bool, int);
@@ -184,21 +186,19 @@ static bool is_subseq (conversion *, conversion *);
 static conversion *maybe_handle_ref_bind (conversion **);
 static void maybe_handle_implicit_object (conversion **);
 static struct z_candidate *add_candidate
-       (struct z_candidate **, tree, tree, size_t,
+       (struct z_candidate **, tree, tree, const VEC(tree,gc) *, size_t,
         conversion **, tree, tree, int);
 static tree source_type (conversion *);
 static void add_warning (struct z_candidate *, struct z_candidate *);
-static bool reference_related_p (tree, tree);
 static bool reference_compatible_p (tree, tree);
 static conversion *convert_class_to_reference (tree, tree, tree, int);
 static conversion *direct_reference_binding (tree, conversion *);
 static bool promoted_arithmetic_type_p (tree);
 static conversion *conditional_conversion (tree, tree);
 static char *name_as_c_string (tree, tree, bool *);
-static tree call_builtin_trap (void);
 static tree prep_operand (tree);
-static void add_candidates (tree, tree, tree, bool, tree, tree,
-                           int, struct z_candidate **);
+static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool,
+                           tree, tree, int, struct z_candidate **);
 static conversion *merge_conversion_sequences (conversion *, conversion *);
 static bool magic_varargs_p (tree);
 static tree build_temp (tree, tree, int, diagnostic_t *);
@@ -240,7 +240,7 @@ check_dtor_name (tree basetype, tree name)
       return false;
     }
 
-  if (!name)
+  if (!name || name == error_mark_node)
     return false;
   return same_type_p (TYPE_MAIN_VARIANT (basetype), TYPE_MAIN_VARIANT (name));
 }
@@ -313,6 +313,9 @@ build_call_a (tree function, int n, tree *argarray)
   gcc_assert (TREE_CODE (fntype) == FUNCTION_TYPE
              || TREE_CODE (fntype) == METHOD_TYPE);
   result_type = TREE_TYPE (fntype);
+  /* An rvalue has no cv-qualifiers.  */
+  if (SCALAR_TYPE_P (result_type) || VOID_TYPE_P (result_type))
+    result_type = cv_unqualified (result_type);
 
   if (TREE_CODE (function) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
@@ -361,7 +364,8 @@ build_call_a (tree function, int n, tree *argarray)
                                argarray[i], t);
        }
 
-  function = build_call_array (result_type, function, n, argarray);
+  function = build_call_array_loc (input_location,
+                                  result_type, function, n, argarray);
   TREE_HAS_CONSTRUCTOR (function) = is_constructor;
   TREE_NOTHROW (function) = nothrow;
 
@@ -413,8 +417,13 @@ struct z_candidate {
   /* The FUNCTION_DECL that will be called if this candidate is
      selected by overload resolution.  */
   tree fn;
-  /* The arguments to use when calling this function.  */
-  tree args;
+  /* If not NULL_TREE, the first argument to use when calling this
+     function.  */
+  tree first_arg;
+  /* The rest of the arguments to use when calling this function.  If
+     there are no further arguments this may be NULL or it may be an
+     empty vector.  */
+  const VEC(tree,gc) *args;
   /* The implicit conversion sequences for each of the arguments to
      FN.  */
   conversion **convs;
@@ -451,9 +460,11 @@ null_ptr_cst_p (tree t)
   /* [conv.ptr]
 
      A null pointer constant is an integral constant expression
-     (_expr.const_) rvalue of integer type that evaluates to zero.  */
+     (_expr.const_) rvalue of integer type that evaluates to zero or
+     an rvalue of type std::nullptr_t. */
   t = integral_constant_value (t);
-  if (t == null_node)
+  if (t == null_node
+      || TREE_CODE (TREE_TYPE (t)) == NULLPTR_TYPE)
     return true;
   if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t))
     {
@@ -617,23 +628,27 @@ build_aggr_conv (tree type, tree ctor, int flags)
 {
   unsigned HOST_WIDE_INT i = 0;
   conversion *c;
-  tree field = TYPE_FIELDS (type);
+  tree field = next_initializable_field (TYPE_FIELDS (type));
 
-  for (; field; field = TREE_CHAIN (field), ++i)
+  for (; field; field = next_initializable_field (TREE_CHAIN (field)))
     {
-      if (TREE_CODE (field) != FIELD_DECL)
-       continue;
       if (i < CONSTRUCTOR_NELTS (ctor))
        {
          constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i);
          if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value),
                                ce->value, flags))
            return NULL;
+         ++i;
+         if (TREE_CODE (type) == UNION_TYPE)
+           break;
        }
       else if (build_value_init (TREE_TYPE (field)) == error_mark_node)
        return NULL;
     }
 
+  if (i < CONSTRUCTOR_NELTS (ctor))
+    return NULL;
+
   c = alloc_conversion (ck_aggr);
   c->type = type;
   c->rank = cr_exact;
@@ -763,7 +778,12 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   if (same_type_p (from, to))
     return conv;
 
-  if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to))
+  /* [conv.ptr]
+     A null pointer constant can be converted to a pointer type; ... A
+     null pointer constant of integral type can be converted to an
+     rvalue of type std::nullptr_t. */
+  if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to)
+       || tcode == NULLPTR_TYPE)
       && expr && null_ptr_cst_p (expr))
     conv = build_conv (ck_std, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
@@ -887,10 +907,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
          || cp_type_quals (fbase) != cp_type_quals (tbase))
        return NULL;
 
-      from = cp_build_qualified_type (tbase, cp_type_quals (fbase));
-      from = build_method_type_directly (from,
-                                        TREE_TYPE (fromfn),
-                                        TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
+      from = build_memfn_type (fromfn, tbase, cp_type_quals (tbase));
       from = build_ptrmemfunc_type (build_pointer_type (from));
       conv = build_conv (ck_pmem, from, conv);
       conv->base_p = true;
@@ -901,17 +918,20 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
          An rvalue of arithmetic, unscoped enumeration, pointer, or
          pointer to member type can be converted to an rvalue of type
-         bool.  */
+         bool. ... An rvalue of type std::nullptr_t can be converted
+         to an rvalue of type bool;  */
       if (ARITHMETIC_TYPE_P (from)
          || UNSCOPED_ENUM_P (from)
          || fcode == POINTER_TYPE
-         || TYPE_PTR_TO_MEMBER_P (from))
+         || TYPE_PTR_TO_MEMBER_P (from)
+         || fcode == NULLPTR_TYPE)
        {
          conv = build_conv (ck_std, to, conv);
          if (fcode == POINTER_TYPE
              || TYPE_PTRMEM_P (from)
              || (TYPE_PTRMEMFUNC_P (from)
-                 && conv->rank < cr_pbool))
+                 && conv->rank < cr_pbool)
+              || fcode == NULLPTR_TYPE)
            conv->rank = cr_pbool;
          return conv;
        }
@@ -959,7 +979,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
 /* Returns nonzero if T1 is reference-related to T2.  */
 
-static bool
+bool
 reference_related_p (tree t1, tree t2)
 {
   t1 = TYPE_MAIN_VARIANT (t1);
@@ -996,14 +1016,14 @@ static conversion *
 convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
 {
   tree conversions;
-  tree arglist;
+  tree first_arg;
   conversion *conv;
   tree t;
   struct z_candidate *candidates;
   struct z_candidate *cand;
   bool any_viable_p;
 
-  conversions = lookup_conversions (s);
+  conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true);
   if (!conversions)
     return NULL;
 
@@ -1029,64 +1049,39 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
      error messages, which we should not issue now because we are just
      trying to find a conversion operator.  Therefore, we use NULL,
      cast to the appropriate type.  */
-  arglist = build_int_cst (build_pointer_type (s), 0);
-  arglist = build_tree_list (NULL_TREE, arglist);
+  first_arg = build_int_cst (build_pointer_type (s), 0);
 
   t = TREE_TYPE (reference_type);
 
+  /* We're performing a user-defined conversion to a desired type, so set
+     this for the benefit of add_candidates.  */
+  flags |= LOOKUP_NO_CONVERSION;
+
   for (; conversions; conversions = TREE_CHAIN (conversions))
     {
       tree fns = TREE_VALUE (conversions);
+      tree binfo = TREE_PURPOSE (conversions);
+      struct z_candidate *old_candidates = candidates;;
 
-      for (; fns; fns = OVL_NEXT (fns))
+      add_candidates (fns, first_arg, NULL, reference_type,
+                     NULL_TREE, false,
+                     binfo, TYPE_BINFO (s),
+                     flags, &candidates);
+
+      for (cand = candidates; cand != old_candidates; cand = cand->next)
        {
-         tree f = OVL_CURRENT (fns);
+         /* Now, see if the conversion function really returns
+            an lvalue of the appropriate type.  From the
+            point of view of unification, simply returning an
+            rvalue of the right type is good enough.  */
+         tree f = cand->fn;
          tree t2 = TREE_TYPE (TREE_TYPE (f));
-
-         if (DECL_NONCONVERTING_P (f)
-             && (flags & LOOKUP_ONLYCONVERTING))
-           continue;
-
-         cand = NULL;
-
-         /* If this is a template function, try to get an exact
-            match.  */
-         if (TREE_CODE (f) == TEMPLATE_DECL)
+         if (TREE_CODE (t2) != REFERENCE_TYPE
+             || !reference_compatible_p (t, TREE_TYPE (t2)))
            {
-             cand = add_template_candidate (&candidates,
-                                            f, s,
-                                            NULL_TREE,
-                                            arglist,
-                                            reference_type,
-                                            TYPE_BINFO (s),
-                                            TREE_PURPOSE (conversions),
-                                            LOOKUP_NORMAL,
-                                            DEDUCE_CONV);
-
-             if (cand)
-               {
-                 /* Now, see if the conversion function really returns
-                    an lvalue of the appropriate type.  From the
-                    point of view of unification, simply returning an
-                    rvalue of the right type is good enough.  */
-                 f = cand->fn;
-                 t2 = TREE_TYPE (TREE_TYPE (f));
-                 if (TREE_CODE (t2) != REFERENCE_TYPE
-                     || !reference_compatible_p (t, TREE_TYPE (t2)))
-                   {
-                     candidates = candidates->next;
-                     cand = NULL;
-                   }
-               }
+             cand->viable = 0;
            }
-         else if (TREE_CODE (t2) == REFERENCE_TYPE
-                  && reference_compatible_p (t, TREE_TYPE (t2)))
-           cand = add_function_candidate (&candidates, f, s, arglist,
-                                          TYPE_BINFO (s),
-                                          TREE_PURPOSE (conversions),
-                                          LOOKUP_NORMAL);
-
-         if (cand)
+         else
            {
              conversion *identity_conv;
              /* Build a standard conversion sequence indicating the
@@ -1103,6 +1098,11 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
                = TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn)))
                  == TYPE_REF_IS_RVALUE (reference_type);
              cand->second_conv->bad_p |= cand->convs[0]->bad_p;
+
+              /* Don't allow binding of lvalues to rvalue references.  */
+              if (TYPE_REF_IS_RVALUE (reference_type)
+                  && !TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn))))
+                cand->second_conv->bad_p = true;
            }
        }
     }
@@ -1119,9 +1119,9 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
 
   /* Now that we know that this is the function we're going to use fix
      the dummy first argument.  */
-  cand->args = tree_cons (NULL_TREE,
-                         build_this (expr),
-                         TREE_CHAIN (cand->args));
+  gcc_assert (cand->first_arg == NULL_TREE
+             || integer_zerop (cand->first_arg));
+  cand->first_arg = build_this (expr);
 
   /* Build a user-defined conversion sequence representing the
      conversion.  */
@@ -1130,13 +1130,13 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
                     build_identity_conv (TREE_TYPE (expr), expr));
   conv->cand = cand;
 
+  if (cand->viable == -1)
+    conv->bad_p = true;
+
   /* Merge it with the standard conversion sequence from the
      conversion function's return type to the desired type.  */
   cand->second_conv = merge_conversion_sequences (conv, cand->second_conv);
 
-  if (cand->viable == -1)
-    conv->bad_p = true;
-
   return cand->second_conv;
 }
 
@@ -1198,7 +1198,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   tree tfrom;
   bool related_p;
   bool compatible_p;
-  cp_lvalue_kind lvalue_p = clk_none;
+  cp_lvalue_kind is_lvalue = clk_none;
 
   if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
     {
@@ -1211,14 +1211,30 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   if (TREE_CODE (from) == REFERENCE_TYPE)
     {
       /* Anything with reference type is an lvalue.  */
-      lvalue_p = clk_ordinary;
+      is_lvalue = clk_ordinary;
       from = TREE_TYPE (from);
     }
-  else if (expr)
-    lvalue_p = real_lvalue_p (expr);
+
+  if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+    {
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+      conv = implicit_conversion (to, from, expr, c_cast_p,
+                                 flags);
+      if (!CLASS_TYPE_P (to)
+         && CONSTRUCTOR_NELTS (expr) == 1)
+       {
+         expr = CONSTRUCTOR_ELT (expr, 0)->value;
+         if (error_operand_p (expr))
+           return NULL;
+         from = TREE_TYPE (expr);
+       }
+    }
+
+  if (is_lvalue == clk_none && expr)
+    is_lvalue = real_lvalue_p (expr);
 
   tfrom = from;
-  if ((lvalue_p & clk_bitfield) != 0)
+  if ((is_lvalue & clk_bitfield) != 0)
     tfrom = unlowered_expr_type (expr);
 
   /* Figure out whether or not the types are reference-related and
@@ -1235,12 +1251,15 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   /* Directly bind reference when target expression's type is compatible with
      the reference and expression is an lvalue. In DR391, the wording in
      [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
-     const and rvalue references to rvalues of compatible class type. */
+     const and rvalue references to rvalues of compatible class type.
+     We should also do direct bindings for non-class "rvalues" derived from
+     rvalue references.  */
   if (compatible_p
-      && (lvalue_p
-         || (!(flags & LOOKUP_NO_TEMP_BIND)
-             && (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto))
-             && CLASS_TYPE_P (from))))
+      && (is_lvalue
+         || (((CP_TYPE_CONST_NON_VOLATILE_P (to)
+               && !(flags & LOOKUP_NO_TEMP_BIND))
+              || TYPE_REF_IS_RVALUE (rto))
+             && (CLASS_TYPE_P (from) || (expr && lvalue_p (expr))))))
     {
       /* [dcl.init.ref]
 
@@ -1267,10 +1286,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
        conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
       else
        conv->rvaluedness_matches_p 
-          = (TYPE_REF_IS_RVALUE (rto) == !lvalue_p);
+          = (TYPE_REF_IS_RVALUE (rto) == !is_lvalue);
 
-      if ((lvalue_p & clk_bitfield) != 0
-         || ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to)))
+      if ((is_lvalue & clk_bitfield) != 0
+         || ((is_lvalue & clk_packed) != 0 && !TYPE_PACKED (to)))
        /* For the purposes of overload resolution, we ignore the fact
           this expression is a bitfield or packed field. (In particular,
           [over.ics.ref] says specifically that a function with a
@@ -1284,6 +1303,11 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
           actually occurs.  */
        conv->need_temporary_p = true;
 
+      /* Don't allow binding of lvalues to rvalue references.  */
+      if (is_lvalue && TYPE_REF_IS_RVALUE (rto)
+          && !(flags & LOOKUP_PREFER_RVALUE))
+       conv->bad_p = true;
+
       return conv;
     }
   /* [class.conv.fct] A conversion function is never used to convert a
@@ -1356,8 +1380,9 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   if (!(flags & LOOKUP_COPY_PARM))
     flags |= LOOKUP_ONLYCONVERTING;
 
-  conv = implicit_conversion (to, from, expr, c_cast_p,
-                             flags);
+  if (!conv)
+    conv = implicit_conversion (to, from, expr, c_cast_p,
+                               flags);
   if (!conv)
     return NULL;
 
@@ -1393,9 +1418,37 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
   if (conv)
     return conv;
 
-  if (is_std_init_list (to) && expr
-      && BRACE_ENCLOSED_INITIALIZER_P (expr))
-    return build_list_conv (to, expr, flags);
+  if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+    {
+      if (is_std_init_list (to))
+       return build_list_conv (to, expr, flags);
+
+      /* Allow conversion from an initializer-list with one element to a
+        scalar type.  */
+      if (SCALAR_TYPE_P (to))
+       {
+         int nelts = CONSTRUCTOR_NELTS (expr);
+         tree elt;
+
+         if (nelts == 0)
+           elt = integer_zero_node;
+         else if (nelts == 1)
+           elt = CONSTRUCTOR_ELT (expr, 0)->value;
+         else
+           elt = error_mark_node;
+
+         conv = implicit_conversion (to, TREE_TYPE (elt), elt,
+                                     c_cast_p, flags);
+         if (conv)
+           {
+             conv->check_narrowing = true;
+             if (BRACE_ENCLOSED_INITIALIZER_P (elt))
+               /* Too many levels of braces, i.e. '{{1}}'.  */
+               conv->bad_p = true;
+             return conv;
+           }
+       }
+    }
 
   if (expr != NULL_TREE
       && (MAYBE_CLASS_TYPE_P (from)
@@ -1424,11 +1477,12 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
 }
 
 /* Add a new entry to the list of candidates.  Used by the add_*_candidate
-   functions.  */
+   functions.  ARGS will not be changed until a single candidate is
+   selected.  */
 
 static struct z_candidate *
 add_candidate (struct z_candidate **candidates,
-              tree fn, tree args,
+              tree fn, tree first_arg, const VEC(tree,gc) *args,
               size_t num_convs, conversion **convs,
               tree access_path, tree conversion_path,
               int viable)
@@ -1437,6 +1491,7 @@ add_candidate (struct z_candidate **candidates,
     conversion_obstack_alloc (sizeof (struct z_candidate));
 
   cand->fn = fn;
+  cand->first_arg = first_arg;
   cand->args = args;
   cand->convs = convs;
   cand->num_convs = num_convs;
@@ -1449,24 +1504,27 @@ add_candidate (struct z_candidate **candidates,
   return cand;
 }
 
-/* Create an overload candidate for the function or method FN called with
-   the argument list ARGLIST and add it to CANDIDATES.  FLAGS is passed on
-   to implicit_conversion.
+/* 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.
+
+   This does not change ARGS.
 
    CTYPE, if non-NULL, is the type we want to pretend this function
    comes from for purposes of overload resolution.  */
 
 static struct z_candidate *
 add_function_candidate (struct z_candidate **candidates,
-                       tree fn, tree ctype, tree arglist,
-                       tree access_path, tree conversion_path,
-                       int flags)
+                       tree fn, tree ctype, tree first_arg,
+                       const VEC(tree,gc) *args, tree access_path,
+                       tree conversion_path, int flags)
 {
   tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
   int i, len;
   conversion **convs;
-  tree parmnode, argnode;
-  tree orig_arglist;
+  tree parmnode;
+  tree orig_first_arg = first_arg;
+  int skip;
   int viable = 1;
 
   /* At this point we should not see any functions which haven't been
@@ -1479,13 +1537,17 @@ add_function_candidate (struct z_candidate **candidates,
   if (DECL_CONSTRUCTOR_P (fn))
     {
       parmlist = skip_artificial_parms_for (fn, parmlist);
-      orig_arglist = arglist;
-      arglist = skip_artificial_parms_for (fn, arglist);
+      skip = num_artificial_parms_for (fn);
+      if (skip > 0 && first_arg != NULL_TREE)
+       {
+         --skip;
+         first_arg = NULL_TREE;
+       }
     }
   else
-    orig_arglist = arglist;
+    skip = 0;
 
-  len = list_length (arglist);
+  len = VEC_length (tree, args) - skip + (first_arg != NULL_TREE ? 1 : 0);
   convs = alloc_conversions (len);
 
   /* 13.3.2 - Viable functions [over.match.viable]
@@ -1518,18 +1580,23 @@ add_function_candidate (struct z_candidate **candidates,
      to the corresponding parameter of F.  */
 
   parmnode = parmlist;
-  argnode = arglist;
 
   for (i = 0; i < len; ++i)
     {
-      tree arg = TREE_VALUE (argnode);
-      tree argtype = lvalue_type (arg);
+      tree arg, argtype;
       conversion *t;
       int is_this;
 
       if (parmnode == void_list_node)
        break;
 
+      if (i == 0 && first_arg != NULL_TREE)
+       arg = first_arg;
+      else
+       arg = VEC_index (tree, args,
+                        i + skip - (first_arg != NULL_TREE ? 1 : 0));
+      argtype = lvalue_type (arg);
+
       is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
                 && ! DECL_CONSTRUCTOR_P (fn));
 
@@ -1555,7 +1622,8 @@ add_function_candidate (struct z_candidate **candidates,
              parmtype = build_pointer_type (parmtype);
            }
 
-         if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn))
+         if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn)
+             && (len-skip == 1))
            {
              /* Hack: Direct-initialize copy parm (i.e. suppress
                 LOOKUP_ONLYCONVERTING) to make explicit conversion ops
@@ -1591,18 +1659,18 @@ add_function_candidate (struct z_candidate **candidates,
 
       if (parmnode)
        parmnode = TREE_CHAIN (parmnode);
-      argnode = TREE_CHAIN (argnode);
     }
 
  out:
-  return add_candidate (candidates, fn, orig_arglist, len, convs,
+  return add_candidate (candidates, fn, orig_first_arg, args, len, convs,
                        access_path, conversion_path, viable);
 }
 
 /* Create an overload candidate for the conversion function FN which will
    be invoked for expression OBJ, producing a pointer-to-function which
-   will in turn be called with the argument list ARGLIST, and add it to
-   CANDIDATES.  FLAGS is passed on to implicit_conversion.
+   will in turn be called with the argument list FIRST_ARG/ARGLIST,
+   and add it to CANDIDATES.  This does not change ARGLIST.  FLAGS is
+   passed on to implicit_conversion.
 
    Actually, we don't really care about FN; we care about the type it
    converts to.  There may be multiple conversion functions that will
@@ -1612,21 +1680,21 @@ add_function_candidate (struct z_candidate **candidates,
 
 static struct z_candidate *
 add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
-                   tree arglist, tree access_path, tree conversion_path)
+                   tree first_arg, const VEC(tree,gc) *arglist,
+                   tree access_path, tree conversion_path)
 {
   tree totype = TREE_TYPE (TREE_TYPE (fn));
   int i, len, viable, flags;
-  tree parmlist, parmnode, argnode;
+  tree parmlist, parmnode;
   conversion **convs;
 
   for (parmlist = totype; TREE_CODE (parmlist) != FUNCTION_TYPE; )
     parmlist = TREE_TYPE (parmlist);
   parmlist = TYPE_ARG_TYPES (parmlist);
 
-  len = list_length (arglist) + 1;
+  len = VEC_length (tree, arglist) + (first_arg != NULL_TREE ? 1 : 0) + 1;
   convs = alloc_conversions (len);
   parmnode = parmlist;
-  argnode = arglist;
   viable = 1;
   flags = LOOKUP_IMPLICIT;
 
@@ -1636,11 +1704,19 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
 
   for (i = 0; i < len; ++i)
     {
-      tree arg = i == 0 ? obj : TREE_VALUE (argnode);
-      tree argtype = lvalue_type (arg);
+      tree arg, argtype;
       conversion *t;
 
       if (i == 0)
+       arg = obj;
+      else if (i == 1 && first_arg != NULL_TREE)
+       arg = first_arg;
+      else
+       arg = VEC_index (tree, arglist,
+                        i - (first_arg != NULL_TREE ? 1 : 0) - 1);
+      argtype = lvalue_type (arg);
+
+      if (i == 0)
        t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
                                 flags);
       else if (parmnode == void_list_node)
@@ -1666,7 +1742,6 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
 
       if (parmnode)
        parmnode = TREE_CHAIN (parmnode);
-      argnode = TREE_CHAIN (argnode);
     }
 
   if (i < len)
@@ -1675,7 +1750,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
   if (!sufficient_parms_p (parmnode))
     viable = 0;
 
-  return add_candidate (candidates, totype, arglist, len, convs,
+  return add_candidate (candidates, totype, first_arg, arglist, len, convs,
                        access_path, conversion_path, viable);
 }
 
@@ -1695,7 +1770,14 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
 
   num_convs =  args[2] ? 3 : (args[1] ? 2 : 1);
   convs = alloc_conversions (num_convs);
-  flags |= LOOKUP_ONLYCONVERTING;
+
+  /* TRUTH_*_EXPR do "contextual conversion to bool", which means explicit
+     conversion ops are allowed.  We handle that here by just checking for
+     boolean_type_node because other operators don't ask for it.  COND_EXPR
+     also does contextual conversion to bool for the first operand, but we
+     handle that in build_conditional_expr, and type1 here is operand 2.  */
+  if (type1 != boolean_type_node)
+    flags |= LOOKUP_ONLYCONVERTING;
 
   for (i = 0; i < 2; ++i)
     {
@@ -1728,7 +1810,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
        viable = 0;
     }
 
-  add_candidate (candidates, fnname, /*args=*/NULL_TREE,
+  add_candidate (candidates, fnname, /*first_arg=*/NULL_TREE, /*args=*/NULL,
                 num_convs, convs,
                 /*access_path=*/NULL_TREE,
                 /*conversion_path=*/NULL_TREE,
@@ -1753,7 +1835,7 @@ promoted_arithmetic_type_p (tree type)
      (including e.g.  int and long but excluding e.g.  char).
      Similarly, the term promoted arithmetic type refers to promoted
      integral types plus floating types.  */
-  return ((INTEGRAL_TYPE_P (type)
+  return ((CP_INTEGRAL_TYPE_P (type)
           && same_type_p (type_promotes_to (type), type))
          || TREE_CODE (type) == REAL_TYPE);
 }
@@ -1855,7 +1937,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
             T       operator~(T);  */
 
     case BIT_NOT_EXPR:
-      if (INTEGRAL_TYPE_P (type1))
+      if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1))
        break;
       return;
 
@@ -1925,7 +2007,8 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
     case MINUS_EXPR:
       if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2))
        break;
-      if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
+      if (TYPE_PTROB_P (type1)
+         && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
        {
          type2 = ptrdiff_type_node;
          break;
@@ -1985,12 +2068,12 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
       if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
        break;
     case ARRAY_REF:
-      if (INTEGRAL_TYPE_P (type1) && TYPE_PTROB_P (type2))
+      if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && TYPE_PTROB_P (type2))
        {
          type1 = ptrdiff_type_node;
          break;
        }
-      if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
+      if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
        {
          type2 = ptrdiff_type_node;
          break;
@@ -2014,7 +2097,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
     case BIT_XOR_EXPR:
     case LSHIFT_EXPR:
     case RSHIFT_EXPR:
-      if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
+      if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
        break;
       return;
 
@@ -2059,7 +2142,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
        {
        case PLUS_EXPR:
        case MINUS_EXPR:
-         if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
+         if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
            {
              type2 = ptrdiff_type_node;
              break;
@@ -2076,7 +2159,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
        case BIT_XOR_EXPR:
        case LSHIFT_EXPR:
        case RSHIFT_EXPR:
-         if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
+         if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
            break;
          return;
 
@@ -2165,6 +2248,8 @@ type_decays_to (tree type)
     return build_pointer_type (TREE_TYPE (type));
   if (TREE_CODE (type) == FUNCTION_TYPE)
     return build_pointer_type (type);
+  if (!MAYBE_CLASS_TYPE_P (type))
+    type = cv_unqualified (type);
   return type;
 }
 
@@ -2268,7 +2353,8 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
          if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
            return;
 
-         convs = lookup_conversions (argtypes[i]);
+         convs = lookup_conversions (argtypes[i],
+                                     /*lookup_template_convs_p=*/false);
 
          if (code == COND_EXPR)
            {
@@ -2301,7 +2387,7 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
                  type = TYPE_MAIN_VARIANT (type_decays_to (type));
                  if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
                    types[i] = tree_cons (NULL_TREE, type, types[i]);
-                 if (INTEGRAL_TYPE_P (type))
+                 if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
                    type = type_promotes_to (type);
                }
 
@@ -2318,9 +2404,9 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
          if (i != 0 || ! ref1)
            {
              type = TYPE_MAIN_VARIANT (type_decays_to (type));
-             if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
+             if (enum_p && UNSCOPED_ENUM_P (type))
                types[i] = tree_cons (NULL_TREE, type, types[i]);
-             if (INTEGRAL_TYPE_P (type))
+             if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
                type = type_promotes_to (type);
            }
          types[i] = tree_cons (NULL_TREE, type, types[i]);
@@ -2349,21 +2435,28 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
 
    TMPL is the template.  EXPLICIT_TARGS are any explicit template
    arguments.  ARGLIST is the arguments provided at the call-site.
-   The RETURN_TYPE is the desired type for conversion operators.  If
-   OBJ is NULL_TREE, FLAGS and CTYPE are as for add_function_candidate.
-   If an OBJ is supplied, FLAGS and CTYPE are ignored, and OBJ is as for
-   add_conv_candidate.  */
+   This does not change ARGLIST.  The RETURN_TYPE is the desired type
+   for conversion operators.  If OBJ is NULL_TREE, FLAGS and CTYPE are
+   as for add_function_candidate.  If an OBJ is supplied, FLAGS and
+   CTYPE are ignored, and OBJ is as for add_conv_candidate.  */
 
 static struct z_candidate*
 add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
-                            tree ctype, tree explicit_targs, tree arglist,
-                            tree return_type, tree access_path,
-                            tree conversion_path, int flags, tree obj,
-                            unification_kind_t strict)
+                            tree ctype, tree explicit_targs, tree first_arg,
+                            const VEC(tree,gc) *arglist, tree return_type,
+                            tree access_path, tree conversion_path,
+                            int flags, tree obj, unification_kind_t strict)
 {
   int ntparms = DECL_NTPARMS (tmpl);
   tree targs = make_tree_vec (ntparms);
-  tree args_without_in_chrg = arglist;
+  unsigned int len = VEC_length (tree, arglist);
+  unsigned int nargs = (first_arg == NULL_TREE ? 0 : 1) + len;
+  unsigned int skip_without_in_chrg = 0;
+  tree first_arg_without_in_chrg = first_arg;
+  tree *args_without_in_chrg;
+  unsigned int nargs_without_in_chrg;
+  unsigned int ia, ix;
+  tree arg;
   struct z_candidate *cand;
   int i;
   tree fn;
@@ -2371,23 +2464,55 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
   /* We don't do deduction on the in-charge parameter, the VTT
      parameter or 'this'.  */
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
-    args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
+    {
+      if (first_arg_without_in_chrg != NULL_TREE)
+       first_arg_without_in_chrg = NULL_TREE;
+      else
+       ++skip_without_in_chrg;
+    }
 
   if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
        || DECL_BASE_CONSTRUCTOR_P (tmpl))
       && CLASSTYPE_VBASECLASSES (DECL_CONTEXT (tmpl)))
-    args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
+    {
+      if (first_arg_without_in_chrg != NULL_TREE)
+       first_arg_without_in_chrg = NULL_TREE;
+      else
+       ++skip_without_in_chrg;
+    }
+
+  if (len < skip_without_in_chrg)
+    return NULL;
+
+  nargs_without_in_chrg = ((first_arg_without_in_chrg != NULL_TREE ? 1 : 0)
+                          + (len - skip_without_in_chrg));
+  args_without_in_chrg = XALLOCAVEC (tree, nargs_without_in_chrg);
+  ia = 0;
+  if (first_arg_without_in_chrg != NULL_TREE)
+    {
+      args_without_in_chrg[ia] = first_arg_without_in_chrg;
+      ++ia;
+    }
+  for (ix = skip_without_in_chrg;
+       VEC_iterate (tree, arglist, ix, arg);
+       ++ix)
+    {
+      args_without_in_chrg[ia] = arg;
+      ++ia;
+    }
+  gcc_assert (ia == nargs_without_in_chrg);
 
   i = fn_type_unification (tmpl, explicit_targs, targs,
                           args_without_in_chrg,
+                          nargs_without_in_chrg,
                           return_type, strict, flags);
 
   if (i != 0)
-    return NULL;
+    goto fail;
 
   fn = instantiate_template (tmpl, targs, tf_none);
   if (fn == error_mark_node)
-    return NULL;
+    goto fail;
 
   /* In [class.copy]:
 
@@ -2411,21 +2536,21 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
      class type, and a logical interpretation is that the intent was
      to forbid the instantiation of member templates which would then
      have that form.  */
-  if (DECL_CONSTRUCTOR_P (fn) && list_length (arglist) == 2)
+  if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
     {
       tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
       if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
                                    ctype))
-       return NULL;
+       goto fail;
     }
 
   if (obj != NULL_TREE)
     /* Aha, this is a conversion function.  */
-    cand = add_conv_candidate (candidates, fn, obj, access_path,
-                              conversion_path, arglist);
+    cand = add_conv_candidate (candidates, fn, obj, first_arg, arglist,
+                              access_path, conversion_path);
   else
     cand = add_function_candidate (candidates, fn, ctype,
-                                  arglist, access_path,
+                                  first_arg, arglist, access_path,
                                   conversion_path, flags);
   if (DECL_TI_TEMPLATE (fn) != tmpl)
     /* This situation can occur if a member template of a template
@@ -2445,44 +2570,50 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
        for this will point at template <class T> template <> S<T>::f(int),
        so that we can find the definition.  For the purposes of
        overload resolution, however, we want the original TMPL.  */
-    cand->template_decl = tree_cons (tmpl, targs, NULL_TREE);
+    cand->template_decl = build_template_info (tmpl, targs);
   else
     cand->template_decl = DECL_TEMPLATE_INFO (fn);
 
   return cand;
+ fail:
+  return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL,
+                       access_path, conversion_path, 0);
 }
 
 
 static struct z_candidate *
 add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
-                       tree explicit_targs, tree arglist, tree return_type,
+                       tree explicit_targs, tree first_arg,
+                       const VEC(tree,gc) *arglist, tree return_type,
                        tree access_path, tree conversion_path, int flags,
                        unification_kind_t strict)
 {
   return
     add_template_candidate_real (candidates, tmpl, ctype,
-                                explicit_targs, arglist, return_type,
-                                access_path, conversion_path,
+                                explicit_targs, first_arg, arglist,
+                                return_type, access_path, conversion_path,
                                 flags, NULL_TREE, strict);
 }
 
 
 static struct z_candidate *
 add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
-                            tree obj, tree arglist, tree return_type,
-                            tree access_path, tree conversion_path)
+                            tree obj, tree first_arg,
+                            const VEC(tree,gc) *arglist,
+                            tree return_type, tree access_path,
+                            tree conversion_path)
 {
   return
     add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
-                                arglist, return_type, access_path,
+                                first_arg, arglist, return_type, access_path,
                                 conversion_path, 0, obj, DEDUCE_CONV);
 }
 
 /* The CANDS are the set of candidates that were considered for
-   overload resolution.  Return the set of viable candidates.  If none
-   of the candidates were viable, set *ANY_VIABLE_P to true.  STRICT_P
-   is true if a candidate should be considered viable only if it is
-   strictly viable.  */
+   overload resolution.  Return the set of viable candidates, or CANDS
+   if none are viable.  If any of the candidates were viable, set
+   *ANY_VIABLE_P to true.  STRICT_P is true if a candidate should be
+   considered viable only if it is strictly viable.  */
 
 static struct z_candidate*
 splice_viable (struct z_candidate *cands,
@@ -2547,6 +2678,10 @@ build_this (tree obj)
 static inline int
 equal_functions (tree fn1, tree fn2)
 {
+  if (TREE_CODE (fn1) != TREE_CODE (fn2))
+    return 0;
+  if (TREE_CODE (fn1) == TEMPLATE_DECL)
+    return fn1 == fn2;
   if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
       || DECL_EXTERN_C_FUNCTION_P (fn1))
     return decls_match (fn1, fn2);
@@ -2582,6 +2717,8 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
     inform (input_location, "%s %T <conversion>", msgstr, candidate->fn);
   else if (candidate->viable == -1)
     inform (input_location, "%s %+#D <near match>", msgstr, candidate->fn);
+  else if (DECL_DELETED_FN (STRIP_TEMPLATE (candidate->fn)))
+    inform (input_location, "%s %+#D <deleted>", msgstr, candidate->fn);
   else
     inform (input_location, "%s %+#D", msgstr, candidate->fn);
 }
@@ -2592,6 +2729,24 @@ print_z_candidates (struct z_candidate *candidates)
   const char *str;
   struct z_candidate *cand1;
   struct z_candidate **cand2;
+  char *spaces;
+
+  if (!candidates)
+    return;
+
+  /* Remove deleted candidates.  */
+  cand1 = candidates;
+  for (cand2 = &cand1; *cand2; )
+    {
+      if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+         && DECL_DELETED_FN ((*cand2)->fn))
+       *cand2 = (*cand2)->next;
+      else
+       cand2 = &(*cand2)->next;
+    }
+  /* ...if there are any non-deleted ones.  */
+  if (cand1)
+    candidates = cand1;
 
   /* There may be duplicates in the set of candidates.  We put off
      checking this condition as long as possible, since we have no way
@@ -2602,12 +2757,12 @@ print_z_candidates (struct z_candidate *candidates)
     {
       tree fn = cand1->fn;
       /* Skip builtin candidates and conversion functions.  */
-      if (TREE_CODE (fn) != FUNCTION_DECL)
+      if (!DECL_P (fn))
        continue;
       cand2 = &cand1->next;
       while (*cand2)
        {
-         if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+         if (DECL_P ((*cand2)->fn)
              && equal_functions (fn, (*cand2)->fn))
            *cand2 = (*cand2)->next;
          else
@@ -2615,28 +2770,14 @@ print_z_candidates (struct z_candidate *candidates)
        }
     }
 
-  if (!candidates)
-    return;
-
-  str = _("candidates are:");
-  print_z_candidate (str, candidates);
-  if (candidates->next)
+  str = candidates->next ? _("candidates are:") :  _("candidate is:");
+  spaces = NULL;
+  for (; candidates; candidates = candidates->next)
     {
-      /* Indent successive candidates by the width of the translation
-        of the above string.  */
-      size_t len = gcc_gettext_width (str) + 1;
-      char *spaces = (char *) alloca (len);
-      memset (spaces, ' ', len-1);
-      spaces[len - 1] = '\0';
-
-      candidates = candidates->next;
-      do
-       {
-         print_z_candidate (spaces, candidates);
-         candidates = candidates->next;
-       }
-      while (candidates);
+      print_z_candidate (spaces ? spaces : str, candidates);
+      spaces = spaces ? spaces : get_spaces (str);
     }
+  free (spaces);
 }
 
 /* USER_SEQ is a user-defined conversion sequence, beginning with a
@@ -2681,7 +2822,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
   tree ctors = NULL_TREE;
   tree conv_fns = NULL_TREE;
   conversion *conv = NULL;
-  tree args = NULL_TREE;
+  tree first_arg = NULL_TREE;
+  VEC(tree,gc) *args = NULL;
   bool any_viable_p;
   int convflags;
 
@@ -2708,11 +2850,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
             reference to it)...  */
        }
       else
-       conv_fns = lookup_conversions (fromtype);
+       conv_fns = lookup_conversions (fromtype,
+                                      /*lookup_template_convs_p=*/true);
     }
 
   candidates = 0;
   flags |= LOOKUP_NO_CONVERSION;
+  if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+    flags |= LOOKUP_NO_NARROWING;
 
   /* It's OK to bind a temporary for converting constructor arguments, but
      not in converting the return value of a conversion operator.  */
@@ -2721,50 +2866,56 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
 
   if (ctors)
     {
-      tree t;
-
+      int ctorflags = flags;
+      bool try_single_arg = true;
       ctors = BASELINK_FUNCTIONS (ctors);
 
-      t = build_int_cst (build_pointer_type (totype), 0);
-      if (BRACE_ENCLOSED_INITIALIZER_P (expr)
-         && !TYPE_HAS_LIST_CTOR (totype))
+      first_arg = build_int_cst (build_pointer_type (totype), 0);
+      if (BRACE_ENCLOSED_INITIALIZER_P (expr))
        {
-         args = ctor_to_list (expr);
-         /* We still allow more conversions within an init-list.  */
-         flags = ((flags & ~LOOKUP_NO_CONVERSION)
-                  /* But not for the copy ctor.  */
-                  |LOOKUP_NO_COPY_CTOR_CONVERSION
-                  |LOOKUP_NO_NARROWING);
+         /* For list-initialization we consider explicit constructors, but
+            give an error if one is selected.  */
+         ctorflags &= ~LOOKUP_ONLYCONVERTING;
+         /* If the class has a list ctor, try passing the list as a single
+            argument first, but only consider list ctors.  */
+         if (TYPE_HAS_LIST_CTOR (totype))
+           ctorflags |= LOOKUP_LIST_ONLY;
+         else
+           try_single_arg = false;
        }
-      else
-       args = build_tree_list (NULL_TREE, expr);
+
       /* We should never try to call the abstract or base constructor
         from here.  */
       gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
                  && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)));
-      args = tree_cons (NULL_TREE, t, args);
-    }
-  for (; ctors; ctors = OVL_NEXT (ctors))
-    {
-      tree ctor = OVL_CURRENT (ctors);
-      if (DECL_NONCONVERTING_P (ctor)
-         && !BRACE_ENCLOSED_INITIALIZER_P (expr))
-       continue;
 
-      if (TREE_CODE (ctor) == TEMPLATE_DECL)
-       cand = add_template_candidate (&candidates, ctor, totype,
-                                      NULL_TREE, args, NULL_TREE,
-                                      TYPE_BINFO (totype),
-                                      TYPE_BINFO (totype),
-                                      flags,
-                                      DEDUCE_CALL);
-      else
-       cand = add_function_candidate (&candidates, ctor, totype,
-                                      args, TYPE_BINFO (totype),
-                                      TYPE_BINFO (totype),
-                                      flags);
+      /* If EXPR is not an initializer-list, or if totype has a list
+        constructor, try EXPR as a single argument.  */
+      if (try_single_arg)
+       {
+         args = make_tree_vector_single (expr);
+         add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
+                         TYPE_BINFO (totype), TYPE_BINFO (totype),
+                         ctorflags, &candidates);
+       }
 
-      if (cand)
+      /* If we didn't find a suitable list constructor for an initializer-list,
+        try breaking it apart.  */
+      if (!candidates && BRACE_ENCLOSED_INITIALIZER_P (expr))
+       {
+         args = ctor_to_vec (expr);
+         /* We aren't looking for list-ctors anymore.  */
+         ctorflags &= ~LOOKUP_LIST_ONLY;
+         /* We still allow more conversions within an init-list.  */
+         ctorflags &= ~LOOKUP_NO_CONVERSION;
+         /* But not for the copy ctor.  */
+         ctorflags |= LOOKUP_NO_COPY_CTOR_CONVERSION;
+         add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
+                         TYPE_BINFO (totype), TYPE_BINFO (totype),
+                         ctorflags, &candidates);
+       }
+
+      for (cand = candidates; cand; cand = cand->next)
        {
          cand->second_conv = build_identity_conv (totype, NULL_TREE);
 
@@ -2784,12 +2935,12 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
     }
 
   if (conv_fns)
-    args = build_tree_list (NULL_TREE, build_this (expr));
+    first_arg = build_this (expr);
 
   for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
     {
-      tree fns;
       tree conversion_path = TREE_PURPOSE (conv_fns);
+      struct z_candidate *old_candidates;
 
       /* If we are called to convert to a reference type, we are trying to
         find an lvalue binding, so don't even consider temporaries.  If
@@ -2798,65 +2949,40 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
       if (TREE_CODE (totype) == REFERENCE_TYPE)
        convflags |= LOOKUP_NO_TEMP_BIND;
 
-      for (fns = TREE_VALUE (conv_fns); fns; fns = OVL_NEXT (fns))
+      old_candidates = candidates;
+      add_candidates (TREE_VALUE (conv_fns), first_arg, NULL, totype,
+                     NULL_TREE, false,
+                     conversion_path, TYPE_BINFO (fromtype),
+                     flags, &candidates);
+
+      for (cand = candidates; cand != old_candidates; cand = cand->next)
        {
-         tree fn = OVL_CURRENT (fns);
-
-         if (DECL_NONCONVERTING_P (fn)
-             && (flags & LOOKUP_ONLYCONVERTING))
-           continue;
-
-         /* [over.match.funcs] For conversion functions, the function
-            is considered to be a member of the class of the implicit
-            object argument for the purpose of defining the type of
-            the implicit object parameter.
-
-            So we pass fromtype as CTYPE to add_*_candidate.  */
-
-         if (TREE_CODE (fn) == TEMPLATE_DECL)
-           cand = add_template_candidate (&candidates, fn, fromtype,
-                                          NULL_TREE,
-                                          args, totype,
-                                          TYPE_BINFO (fromtype),
-                                          conversion_path,
-                                          flags,
-                                          DEDUCE_CONV);
-         else
-           cand = add_function_candidate (&candidates, fn, fromtype,
-                                          args,
-                                          TYPE_BINFO (fromtype),
-                                          conversion_path,
-                                          flags);
+         conversion *ics
+           = implicit_conversion (totype,
+                                  TREE_TYPE (TREE_TYPE (cand->fn)),
+                                  0,
+                                  /*c_cast_p=*/false, convflags);
 
-         if (cand)
-           {
-             conversion *ics
-               = implicit_conversion (totype,
-                                      TREE_TYPE (TREE_TYPE (cand->fn)),
-                                      0,
-                                      /*c_cast_p=*/false, convflags);
-
-             /* If LOOKUP_NO_TEMP_BIND isn't set, then this is
-                copy-initialization.  In that case, "The result of the
-                call is then used to direct-initialize the object that is
-                the destination of the copy-initialization."  [dcl.init]
-
-                We represent this in the conversion sequence with an
-                rvalue conversion, which means a constructor call.  But
-                don't add a second rvalue conversion if there's already
-                one there.  Which there really shouldn't be, but it's
-                harmless since we'd add it here anyway. */
-             if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue
-                 && !(convflags & LOOKUP_NO_TEMP_BIND))
-               ics = build_conv (ck_rvalue, totype, ics);
-
-             cand->second_conv = ics;
-
-             if (!ics)
-               cand->viable = 0;
-             else if (candidates->viable == 1 && ics->bad_p)
-               cand->viable = -1;
-           }
+         /* If LOOKUP_NO_TEMP_BIND isn't set, then this is
+            copy-initialization.  In that case, "The result of the
+            call is then used to direct-initialize the object that is
+            the destination of the copy-initialization."  [dcl.init]
+
+            We represent this in the conversion sequence with an
+            rvalue conversion, which means a constructor call.  But
+            don't add a second rvalue conversion if there's already
+            one there.  Which there really shouldn't be, but it's
+            harmless since we'd add it here anyway. */
+         if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue
+             && !(convflags & LOOKUP_NO_TEMP_BIND))
+           ics = build_conv (ck_rvalue, totype, ics);
+
+         cand->second_conv = ics;
+
+         if (!ics)
+           cand->viable = 0;
+         else if (cand->viable == 1 && ics->bad_p)
+           cand->viable = -1;
        }
     }
 
@@ -2926,23 +3052,23 @@ build_user_type_conversion (tree totype, tree expr, int flags)
 
 /* Do any initial processing on the arguments to a function call.  */
 
-static tree
-resolve_args (tree args)
+static VEC(tree,gc) *
+resolve_args (VEC(tree,gc) *args)
 {
-  tree t;
-  for (t = args; t; t = TREE_CHAIN (t))
-    {
-      tree arg = TREE_VALUE (t);
+  unsigned int ix;
+  tree arg;
 
+  for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+    {
       if (error_operand_p (arg))
-       return error_mark_node;
+       return NULL;
       else if (VOID_TYPE_P (TREE_TYPE (arg)))
        {
          error ("invalid use of void expression");
-         return error_mark_node;
+         return NULL;
        }
       else if (invalid_nonstatic_memfn_p (arg, tf_warning_or_error))
-       return error_mark_node;
+       return NULL;
     }
   return args;
 }
@@ -2961,7 +3087,7 @@ resolve_args (tree args)
 
 static struct z_candidate *
 perform_overload_resolution (tree fn,
-                            tree args,
+                            const VEC(tree,gc) *args,
                             struct z_candidate **candidates,
                             bool *any_viable_p)
 {
@@ -2972,12 +3098,11 @@ perform_overload_resolution (tree fn,
   *candidates = NULL;
   *any_viable_p = true;
 
-  /* Check FN and ARGS.  */
+  /* Check FN.  */
   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
              || TREE_CODE (fn) == TEMPLATE_DECL
              || TREE_CODE (fn) == OVERLOAD
              || TREE_CODE (fn) == TEMPLATE_ID_EXPR);
-  gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
 
   if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
     {
@@ -2987,7 +3112,8 @@ perform_overload_resolution (tree fn,
     }
 
   /* Add the various candidate functions.  */
-  add_candidates (fn, args, explicit_targs, template_only,
+  add_candidates (fn, NULL_TREE, args, NULL_TREE,
+                 explicit_targs, template_only,
                  /*conversion_path=*/NULL_TREE,
                  /*access_path=*/NULL_TREE,
                  LOOKUP_NORMAL,
@@ -3002,10 +3128,11 @@ perform_overload_resolution (tree fn,
 }
 
 /* Return an expression for a call to FN (a namespace-scope function,
-   or a static member function) with the ARGS.  */
+   or a static member function) with the ARGS.  This may change
+   ARGS.  */
 
 tree
-build_new_function_call (tree fn, tree args, bool koenig_p, 
+build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p, 
                         tsubst_flags_t complain)
 {
   struct z_candidate *candidates, *cand;
@@ -3013,9 +3140,12 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
   void *p;
   tree result;
 
-  args = resolve_args (args);
-  if (args == error_mark_node)
-    return error_mark_node;
+  if (args != NULL && *args != NULL)
+    {
+      *args = resolve_args (*args);
+      if (*args == NULL)
+       return error_mark_node;
+    }
 
   /* If this function was found without using argument dependent
      lookup, then we want to ignore any undeclared friend
@@ -3029,7 +3159,8 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
        {
          if (complain & tf_error)
            error ("no matching function for call to %<%D(%A)%>",
-                  DECL_NAME (OVL_CURRENT (orig_fn)), args);
+                  DECL_NAME (OVL_CURRENT (orig_fn)),
+                  build_tree_list_vec (*args));
          return error_mark_node;
        }
     }
@@ -3037,22 +3168,23 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
-  cand = perform_overload_resolution (fn, args, &candidates, &any_viable_p);
+  cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p);
 
   if (!cand)
     {
       if (complain & tf_error)
        {
-         if (!any_viable_p && candidates && ! candidates->next)
-           return cp_build_function_call (candidates->fn, args, complain);
+         if (!any_viable_p && candidates && ! candidates->next
+             && (TREE_CODE (candidates->fn) == FUNCTION_DECL))
+           return cp_build_function_call_vec (candidates->fn, args, complain);
          if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
            fn = TREE_OPERAND (fn, 0);
          if (!any_viable_p)
            error ("no matching function for call to %<%D(%A)%>",
-                  DECL_NAME (OVL_CURRENT (fn)), args);
+                  DECL_NAME (OVL_CURRENT (fn)), build_tree_list_vec (*args));
          else
            error ("call of overloaded %<%D(%A)%> is ambiguous",
-                  DECL_NAME (OVL_CURRENT (fn)), args);
+                  DECL_NAME (OVL_CURRENT (fn)), build_tree_list_vec (*args));
          if (candidates)
            print_z_candidates (candidates);
        }
@@ -3069,15 +3201,16 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
 
 /* Build a call to a global operator new.  FNNAME is the name of the
    operator (either "operator new" or "operator new[]") and ARGS are
-   the arguments provided.  *SIZE points to the total number of bytes
-   required by the allocation, and is updated if that is changed here.
-   *COOKIE_SIZE is non-NULL if a cookie should be used.  If this
-   function determines that no cookie should be used, after all,
-   *COOKIE_SIZE is set to NULL_TREE.  If FN is non-NULL, it will be
-   set, upon return, to the allocation function called.  */
+   the arguments provided.  This may change ARGS.  *SIZE points to the
+   total number of bytes required by the allocation, and is updated if
+   that is changed here.  *COOKIE_SIZE is non-NULL if a cookie should
+   be used.  If this function determines that no cookie should be
+   used, after all, *COOKIE_SIZE is set to NULL_TREE.  If FN is
+   non-NULL, it will be set, upon return, to the allocation function
+   called.  */
 
 tree
-build_operator_new_call (tree fnname, tree args,
+build_operator_new_call (tree fnname, VEC(tree,gc) **args,
                         tree *size, tree *cookie_size,
                         tree *fn)
 {
@@ -3088,10 +3221,10 @@ build_operator_new_call (tree fnname, tree args,
 
   if (fn)
     *fn = NULL_TREE;
-  args = tree_cons (NULL_TREE, *size, args);
-  args = resolve_args (args);
-  if (args == error_mark_node)
-    return args;
+  VEC_safe_insert (tree, gc, *args, 0, *size);
+  *args = resolve_args (*args);
+  if (*args == NULL)
+    return error_mark_node;
 
   /* Based on:
 
@@ -3102,10 +3235,10 @@ build_operator_new_call (tree fnname, tree args,
        up in the global scope.
 
      we disregard block-scope declarations of "operator new".  */
-  fns = lookup_function_nonclass (fnname, args, /*block_p=*/false);
+  fns = lookup_function_nonclass (fnname, *args, /*block_p=*/false);
 
   /* Figure out what function is being called.  */
-  cand = perform_overload_resolution (fns, args, &candidates, &any_viable_p);
+  cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p);
 
   /* If no suitable function could be found, issue an error message
      and give up.  */
@@ -3113,10 +3246,10 @@ build_operator_new_call (tree fnname, tree args,
     {
       if (!any_viable_p)
        error ("no matching function for call to %<%D(%A)%>",
-              DECL_NAME (OVL_CURRENT (fns)), args);
+              DECL_NAME (OVL_CURRENT (fns)), build_tree_list_vec (*args));
       else
        error ("call of overloaded %<%D(%A)%> is ambiguous",
-              DECL_NAME (OVL_CURRENT (fns)), args);
+              DECL_NAME (OVL_CURRENT (fns)), build_tree_list_vec (*args));
       if (candidates)
        print_z_candidates (candidates);
       return error_mark_node;
@@ -3130,12 +3263,11 @@ build_operator_new_call (tree fnname, tree args,
        bool use_cookie = true;
        if (!abi_version_at_least (2))
         {
-          tree placement = TREE_CHAIN (args);
           /* In G++ 3.2, the check was implemented incorrectly; it
              looked at the placement expression, rather than the
              type of the function.  */
-          if (placement && !TREE_CHAIN (placement)
-              && same_type_p (TREE_TYPE (TREE_VALUE (placement)),
+          if (VEC_length (tree, *args) == 2
+              && same_type_p (TREE_TYPE (VEC_index (tree, *args, 1)),
                               ptr_type_node))
             use_cookie = false;
         }
@@ -3159,7 +3291,7 @@ build_operator_new_call (tree fnname, tree args,
           /* Update the total size.  */
           *size = size_binop (PLUS_EXPR, *size, *cookie_size);
           /* Update the argument list to reflect the adjusted size.  */
-          TREE_VALUE (args) = *size;
+          VEC_replace (tree, *args, 0, *size);
         }
        else
         *cookie_size = NULL_TREE;
@@ -3173,16 +3305,23 @@ build_operator_new_call (tree fnname, tree args,
    return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
 }
 
-static tree
-build_object_call (tree obj, tree args, tsubst_flags_t complain)
+/* Build a new call to operator().  This may change ARGS.  */
+
+tree
+build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
 {
   struct z_candidate *candidates = 0, *cand;
-  tree fns, convs, mem_args = NULL_TREE;
+  tree fns, convs, first_mem_arg = NULL_TREE;
   tree type = TREE_TYPE (obj);
   bool any_viable_p;
   tree result = NULL_TREE;
   void *p;
 
+  if (error_operand_p (obj))
+    return error_mark_node;
+
+  obj = prep_operand (obj);
+
   if (TYPE_PTRMEMFUNC_P (type))
     {
       if (complain & tf_error)
@@ -3201,36 +3340,28 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
   else
     fns = NULL_TREE;
 
-  args = resolve_args (args);
-
-  if (args == error_mark_node)
-    return error_mark_node;
+  if (args != NULL && *args != NULL)
+    {
+      *args = resolve_args (*args);
+      if (*args == NULL)
+       return error_mark_node;
+    }
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
   if (fns)
     {
-      tree base = BINFO_TYPE (BASELINK_BINFO (fns));
-      mem_args = tree_cons (NULL_TREE, build_this (obj), args);
+      first_mem_arg = build_this (obj);
 
-      for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
-       {
-         tree fn = OVL_CURRENT (fns);
-         if (TREE_CODE (fn) == TEMPLATE_DECL)
-           add_template_candidate (&candidates, fn, base, NULL_TREE,
-                                   mem_args, NULL_TREE,
-                                   TYPE_BINFO (type),
-                                   TYPE_BINFO (type),
-                                   LOOKUP_NORMAL, DEDUCE_CALL);
-         else
-           add_function_candidate
-             (&candidates, fn, base, mem_args, TYPE_BINFO (type),
-              TYPE_BINFO (type), LOOKUP_NORMAL);
-       }
+      add_candidates (BASELINK_FUNCTIONS (fns),
+                     first_mem_arg, *args, NULL_TREE,
+                     NULL_TREE, false,
+                     BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns),
+                     LOOKUP_NORMAL, &candidates);
     }
 
-  convs = lookup_conversions (type);
+  convs = lookup_conversions (type, /*lookup_template_convs_p=*/true);
 
   for (; convs; convs = TREE_CHAIN (convs))
     {
@@ -3253,12 +3384,12 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
 
            if (TREE_CODE (fn) == TEMPLATE_DECL)
              add_template_conv_candidate
-               (&candidates, fn, obj, args, totype,
+               (&candidates, fn, obj, NULL_TREE, *args, totype,
                 /*access_path=*/NULL_TREE,
                 /*conversion_path=*/NULL_TREE);
            else
-             add_conv_candidate (&candidates, fn, obj, args,
-                                 /*conversion_path=*/NULL_TREE,
+             add_conv_candidate (&candidates, fn, obj, NULL_TREE,
+                                 *args, /*conversion_path=*/NULL_TREE,
                                  /*access_path=*/NULL_TREE);
          }
     }
@@ -3268,7 +3399,8 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
     {
       if (complain & tf_error)
         {
-          error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args);
+          error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj),
+                build_tree_list_vec (*args));
           print_z_candidates (candidates);
         }
       result = error_mark_node;
@@ -3281,7 +3413,7 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
           if (complain & tf_error)
             {
               error ("call of %<(%T) (%A)%> is ambiguous", 
-                     TREE_TYPE (obj), args);
+                     TREE_TYPE (obj), build_tree_list_vec (*args));
               print_z_candidates (candidates);
             }
          result = error_mark_node;
@@ -3297,7 +3429,7 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
          obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1,
                                           complain);
          obj = convert_from_reference (obj);
-         result = cp_build_function_call (obj, args, complain);
+         result = cp_build_function_call_vec (obj, args, complain);
        }
     }
 
@@ -3309,7 +3441,7 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
 
 static void
 op_error (enum tree_code code, enum tree_code code2,
-         tree arg1, tree arg2, tree arg3, const char *problem)
+         tree arg1, tree arg2, tree arg3, bool match)
 {
   const char *opname;
 
@@ -3321,31 +3453,58 @@ op_error (enum tree_code code, enum tree_code code2,
   switch (code)
     {
     case COND_EXPR:
-      error ("%s for ternary %<operator?:%> in %<%E ? %E : %E%>",
-            problem, arg1, arg2, arg3);
+      if (match)
+        error ("ambiguous overload for ternary %<operator?:%> "
+               "in %<%E ? %E : %E%>", arg1, arg2, arg3);
+      else
+        error ("no match for ternary %<operator?:%> "
+               "in %<%E ? %E : %E%>", arg1, arg2, arg3);
       break;
 
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
-      error ("%s for %<operator%s%> in %<%E%s%>", problem, opname, arg1, opname);
+      if (match)
+        error ("ambiguous overload for %<operator%s%> in %<%E%s%>",
+               opname, arg1, opname);
+      else
+        error ("no match for %<operator%s%> in %<%E%s%>", 
+               opname, arg1, opname);
       break;
 
     case ARRAY_REF:
-      error ("%s for %<operator[]%> in %<%E[%E]%>", problem, arg1, arg2);
+      if (match)
+        error ("ambiguous overload for %<operator[]%> in %<%E[%E]%>", 
+               arg1, arg2);
+      else
+        error ("no match for %<operator[]%> in %<%E[%E]%>", 
+               arg1, arg2);
       break;
 
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      error ("%s for %qs in %<%s %E%>", problem, opname, opname, arg1);
+      if (match)
+        error ("ambiguous overload for %qs in %<%s %E%>", 
+               opname, opname, arg1);
+      else
+        error ("no match for %qs in %<%s %E%>",
+               opname, opname, arg1);
       break;
 
     default:
       if (arg2)
-       error ("%s for %<operator%s%> in %<%E %s %E%>",
-              problem, opname, arg1, opname, arg2);
+        if (match)
+          error ("ambiguous overload for %<operator%s%> in %<%E %s %E%>",
+                  opname, arg1, opname, arg2);
+        else
+          error ("no match for %<operator%s%> in %<%E %s %E%>",
+                 opname, arg1, opname, arg2);
       else
-       error ("%s for %<operator%s%> in %<%s%E%>",
-              problem, opname, opname, arg1);
+        if (match)
+          error ("ambiguous overload for %<operator%s%> in %<%s%E%>",
+                 opname, opname, arg1);
+        else
+          error ("no match for %<operator%s%> in %<%s%E%>",
+                 opname, opname, arg1);
       break;
     }
 }
@@ -3424,6 +3583,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
   tree arg2_type;
   tree arg3_type;
   tree result = NULL_TREE;
+  tree result_save;
   tree result_type = NULL_TREE;
   bool lvalue_p = true;
   struct z_candidate *candidates = 0;
@@ -3451,7 +3611,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
 
      The first expression is implicitly converted to bool (clause
      _conv_).  */
-  arg1 = perform_implicit_conversion (boolean_type_node, arg1, complain);
+  arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
+                                           LOOKUP_NORMAL);
 
   /* If something has already gone wrong, just pass that fact up the
      tree.  */
@@ -3649,7 +3810,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
       bool any_viable_p;
 
       /* Rearrange the arguments so that add_builtin_candidate only has
-        to know about two args.  In build_builtin_candidates, the
+        to know about two args.  In build_builtin_candidate, the
         arguments are unscrambled.  */
       args[0] = arg2;
       args[1] = arg3;
@@ -3670,7 +3831,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
        {
           if (complain & tf_error)
             {
-              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
+              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
               print_z_candidates (candidates);
             }
          return error_mark_node;
@@ -3680,7 +3841,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
        {
           if (complain & tf_error)
             {
-              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
+              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
               print_z_candidates (candidates);
             }
          return error_mark_node;
@@ -3695,8 +3856,10 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
       arg1 = convert_like (conv, arg1, complain);
       conv = cand->convs[1];
       arg2 = convert_like (conv, arg2, complain);
+      arg2_type = TREE_TYPE (arg2);
       conv = cand->convs[2];
       arg3 = convert_like (conv, arg3, complain);
+      arg3_type = TREE_TYPE (arg3);
     }
 
   /* [expr.cond]
@@ -3715,7 +3878,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
     arg2_type = TREE_TYPE (arg2);
 
   arg3 = force_rvalue (arg3);
-  if (!CLASS_TYPE_P (arg2_type))
+  if (!CLASS_TYPE_P (arg3_type))
     arg3_type = TREE_TYPE (arg3);
 
   if (arg2 == error_mark_node || arg3 == error_mark_node)
@@ -3790,7 +3953,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
           || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
     {
       result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
-                                           arg3, "conditional expression",
+                                           arg3, CPO_CONDITIONAL_EXPR,
                                            complain);
       if (result_type == error_mark_node)
        return error_mark_node;
@@ -3807,8 +3970,13 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
     }
 
  valid_operands:
-  result = fold_if_not_in_template (build3 (COND_EXPR, result_type, arg1,
-                                           arg2, arg3));
+  result_save = build3 (COND_EXPR, result_type, arg1, arg2, arg3);
+  result = fold_if_not_in_template (result_save);
+
+  if (cp_unevaluated_operand && TREE_CODE (result) == CALL_EXPR)
+    /* Avoid folding to a CALL_EXPR within decltype (c++/42013).  */
+    result = result_save;
+
   /* We can't use result_type below, as fold might have returned a
      throw_expr.  */
 
@@ -3848,76 +4016,164 @@ prep_operand (tree operand)
 
 /* Add each of the viable functions in FNS (a FUNCTION_DECL or
    OVERLOAD) to the CANDIDATES, returning an updated list of
-   CANDIDATES.  The ARGS are the arguments provided to the call,
-   without any implicit object parameter.  The EXPLICIT_TARGS are
-   explicit template arguments provided.  TEMPLATE_ONLY is true if
-   only template functions should be considered.  CONVERSION_PATH,
-   ACCESS_PATH, and FLAGS are as for add_function_candidate.  */
+   CANDIDATES.  The ARGS are the arguments provided to the call;
+   if FIRST_ARG is non-null it is the implicit object argument,
+   otherwise the first element of ARGS is used if needed.  The
+   EXPLICIT_TARGS are explicit template arguments provided.
+   TEMPLATE_ONLY is true if only template functions should be
+   considered.  CONVERSION_PATH, ACCESS_PATH, and FLAGS are as for
+   add_function_candidate.  */
 
 static void
-add_candidates (tree fns, tree args,
+add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
+               tree return_type,
                tree explicit_targs, bool template_only,
                tree conversion_path, tree access_path,
                int flags,
                struct z_candidate **candidates)
 {
   tree ctype;
-  tree non_static_args;
+  const VEC(tree,gc) *non_static_args;
+  bool check_list_ctor;
+  bool check_converting;
+  unification_kind_t strict;
+  tree fn;
+
+  if (!fns)
+    return;
+
+  /* Precalculate special handling of constructors and conversion ops.  */
+  fn = OVL_CURRENT (fns);
+  if (DECL_CONV_FN_P (fn))
+    {
+      check_list_ctor = false;
+      check_converting = !!(flags & LOOKUP_ONLYCONVERTING);
+      if (flags & LOOKUP_NO_CONVERSION)
+       /* We're doing return_type(x).  */
+       strict = DEDUCE_CONV;
+      else
+       /* We're doing x.operator return_type().  */
+       strict = DEDUCE_EXACT;
+      /* [over.match.funcs] For conversion functions, the function
+        is considered to be a member of the class of the implicit
+        object argument for the purpose of defining the type of
+        the implicit object parameter.  */
+      ctype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (first_arg)));
+    }
+  else
+    {
+      if (DECL_CONSTRUCTOR_P (fn))
+       {
+         check_list_ctor = !!(flags & LOOKUP_LIST_ONLY);
+         check_converting = !!(flags & LOOKUP_ONLYCONVERTING);
+       }
+      else
+       {
+         check_list_ctor = false;
+         check_converting = false;
+       }
+      strict = DEDUCE_CALL;
+      ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
+    }
 
-  ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
-  /* Delay creating the implicit this parameter until it is needed.  */
-  non_static_args = NULL_TREE;
+  if (first_arg)
+    non_static_args = args;
+  else
+    /* Delay creating the implicit this parameter until it is needed.  */
+    non_static_args = NULL;
 
-  while (fns)
+  for (; fns; fns = OVL_NEXT (fns))
     {
-      tree fn;
-      tree fn_args;
+      tree fn_first_arg;
+      const VEC(tree,gc) *fn_args;
 
       fn = OVL_CURRENT (fns);
+
+      if (check_converting && DECL_NONCONVERTING_P (fn))
+       continue;
+      if (check_list_ctor && !is_list_ctor (fn))
+       continue;
+
       /* Figure out which set of arguments to use.  */
       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
        {
-         /* If this function is a non-static member, prepend the implicit
-            object parameter.  */
-         if (!non_static_args)
-           non_static_args = tree_cons (NULL_TREE,
-                                        build_this (TREE_VALUE (args)),
-                                        TREE_CHAIN (args));
+         /* If this function is a non-static member and we didn't get an
+            implicit object argument, move it out of args.  */
+         if (first_arg == NULL_TREE)
+           {
+             unsigned int ix;
+             tree arg;
+             VEC(tree,gc) *tempvec
+               = VEC_alloc (tree, gc, VEC_length (tree, args) - 1);
+             for (ix = 1; VEC_iterate (tree, args, ix, arg); ++ix)
+               VEC_quick_push (tree, tempvec, arg);
+             non_static_args = tempvec;
+             first_arg = build_this (VEC_index (tree, args, 0));
+           }
+
+         fn_first_arg = first_arg;
          fn_args = non_static_args;
        }
       else
-       /* Otherwise, just use the list of arguments provided.  */
-       fn_args = args;
+       {
+         /* Otherwise, just use the list of arguments provided.  */
+         fn_first_arg = NULL_TREE;
+         fn_args = args;
+       }
 
       if (TREE_CODE (fn) == TEMPLATE_DECL)
        add_template_candidate (candidates,
                                fn,
                                ctype,
                                explicit_targs,
+                               fn_first_arg, 
                                fn_args,
-                               NULL_TREE,
+                               return_type,
                                access_path,
                                conversion_path,
                                flags,
-                               DEDUCE_CALL);
+                               strict);
       else if (!template_only)
        add_function_candidate (candidates,
                                fn,
                                ctype,
+                               fn_first_arg,
                                fn_args,
                                access_path,
                                conversion_path,
                                flags);
-      fns = OVL_NEXT (fns);
     }
 }
 
+/* Even unsigned enum types promote to signed int.  We don't want to
+   issue -Wsign-compare warnings for this case.  Here ORIG_ARG is the
+   original argument and ARG is the argument after any conversions
+   have been applied.  We set TREE_NO_WARNING if we have added a cast
+   from an unsigned enum type to a signed integer type.  */
+
+static void
+avoid_sign_compare_warnings (tree orig_arg, tree arg)
+{
+  if (orig_arg != NULL_TREE
+      && arg != NULL_TREE
+      && orig_arg != arg
+      && TREE_CODE (TREE_TYPE (orig_arg)) == ENUMERAL_TYPE
+      && TYPE_UNSIGNED (TREE_TYPE (orig_arg))
+      && INTEGRAL_TYPE_P (TREE_TYPE (arg))
+      && !TYPE_UNSIGNED (TREE_TYPE (arg)))
+    TREE_NO_WARNING (arg) = 1;
+}
+
 tree
 build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
              bool *overloaded_p, tsubst_flags_t complain)
 {
+  tree orig_arg1 = arg1;
+  tree orig_arg2 = arg2;
+  tree orig_arg3 = arg3;
   struct z_candidate *candidates = 0, *cand;
-  tree arglist, fnname;
+  VEC(tree,gc) *arglist;
+  tree fnname;
   tree args[3];
   tree result = NULL_TREE;
   bool result_valid_p = false;
@@ -3955,7 +4211,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       gcc_unreachable ();
 
     case CALL_EXPR:
-      return build_object_call (arg1, arg2, complain);
+      /* Use build_op_call instead.  */
+      gcc_unreachable ();
 
     case TRUTH_ORIF_EXPR:
     case TRUTH_ANDIF_EXPR:
@@ -3973,14 +4230,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
   arg3 = prep_operand (arg3);
 
   if (code == COND_EXPR)
-    {
-      if (arg2 == NULL_TREE
-         || TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE
-         || TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE
-         || (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))
-             && ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
-       goto builtin;
-    }
+    /* Use build_conditional_expr instead.  */
+    gcc_unreachable ();
   else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
           && (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))))
     goto builtin;
@@ -3988,12 +4239,12 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
     arg2 = integer_zero_node;
 
-  arglist = NULL_TREE;
-  if (arg3)
-    arglist = tree_cons (NULL_TREE, arg3, arglist);
-  if (arg2)
-    arglist = tree_cons (NULL_TREE, arg2, arglist);
-  arglist = tree_cons (NULL_TREE, arg1, arglist);
+  arglist = VEC_alloc (tree, gc, 3);
+  VEC_quick_push (tree, arglist, arg1);
+  if (arg2 != NULL_TREE)
+    VEC_quick_push (tree, arglist, arg2);
+  if (arg3 != NULL_TREE)
+    VEC_quick_push (tree, arglist, arg3);
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
@@ -4001,7 +4252,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
   /* Add namespace-scope operators to the list of functions to
      consider.  */
   add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true),
-                 arglist, NULL_TREE, false, NULL_TREE, NULL_TREE,
+                 NULL_TREE, arglist, NULL_TREE,
+                 NULL_TREE, false, NULL_TREE, NULL_TREE,
                  flags, &candidates);
   /* Add class-member operators to the candidate set.  */
   if (CLASS_TYPE_P (TREE_TYPE (arg1)))
@@ -4015,29 +4267,17 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          goto user_defined_result_ready;
        }
       if (fns)
-       add_candidates (BASELINK_FUNCTIONS (fns), arglist,
+       add_candidates (BASELINK_FUNCTIONS (fns),
+                       NULL_TREE, arglist, NULL_TREE,
                        NULL_TREE, false,
                        BASELINK_BINFO (fns),
-                       TYPE_BINFO (TREE_TYPE (arg1)),
+                       BASELINK_ACCESS_BINFO (fns),
                        flags, &candidates);
     }
 
-  /* Rearrange the arguments for ?: so that add_builtin_candidate only has
-     to know about two args; a builtin candidate will always have a first
-     parameter of type bool.  We'll handle that in
-     build_builtin_candidate.  */
-  if (code == COND_EXPR)
-    {
-      args[0] = arg2;
-      args[1] = arg3;
-      args[2] = arg1;
-    }
-  else
-    {
-      args[0] = arg1;
-      args[1] = arg2;
-      args[2] = NULL_TREE;
-    }
+  args[0] = arg1;
+  args[1] = arg2;
+  args[2] = NULL_TREE;
 
   add_builtin_candidates (&candidates, code, code2, fnname, args, flags);
 
@@ -4071,13 +4311,23 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          if (!(complain & tf_error))
            return error_mark_node;
 
-         /* Look for an `operator++ (int)'.  If they didn't have
-            one, then we fall back to the old way of doing things.  */
+         /* Look for an `operator++ (int)'. Pre-1985 C++ didn't
+            distinguish between prefix and postfix ++ and
+            operator++() was used for both, so we allow this with
+            -fpermissive.  */
          if (flags & LOOKUP_COMPLAIN)
-           permerror (input_location, "no %<%D(int)%> declared for postfix %qs, "
-                      "trying prefix operator instead",
-                      fnname,
-                      operator_name_info[code].name);
+           {
+             const char *msg = (flag_permissive) 
+               ? G_("no %<%D(int)%> declared for postfix %qs,"
+                    " trying prefix operator instead")
+               : G_("no %<%D(int)%> declared for postfix %qs");
+             permerror (input_location, msg, fnname,
+                        operator_name_info[code].name);
+           }
+
+         if (!flag_permissive)
+           return error_mark_node;
+
          if (code == POSTINCREMENT_EXPR)
            code = PREINCREMENT_EXPR;
          else
@@ -4108,7 +4358,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
                  {
                    /* ... Otherwise, report the more generic
                       "no matching operator found" error */
-                   op_error (code, code2, arg1, arg2, arg3, "no match");
+                   op_error (code, code2, arg1, arg2, arg3, FALSE);
                    print_z_candidates (candidates);
                  }
            }
@@ -4123,7 +4373,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
        {
          if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
            {
-             op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
+             op_error (code, code2, arg1, arg2, arg3, TRUE);
              print_z_candidates (candidates);
            }
          result = error_mark_node;
@@ -4133,7 +4383,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          if (overloaded_p)
            *overloaded_p = true;
 
-         if (resolve_args (arglist) == error_mark_node)
+         if (resolve_args (arglist) == NULL)
            result = error_mark_node;
          else
            result = build_over_call (cand, LOOKUP_NORMAL, complain);
@@ -4215,13 +4465,17 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
     return result;
 
  builtin:
+  avoid_sign_compare_warnings (orig_arg1, arg1);
+  avoid_sign_compare_warnings (orig_arg2, arg2);
+  avoid_sign_compare_warnings (orig_arg3, arg3);
+
   switch (code)
     {
     case MODIFY_EXPR:
       return cp_build_modify_expr (arg1, code2, arg2, complain);
 
     case INDIRECT_REF:
-      return cp_build_indirect_ref (arg1, "unary *", complain);
+      return cp_build_indirect_ref (arg1, RO_UNARY_STAR, complain);
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
@@ -4263,13 +4517,10 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       return cp_build_unary_op (code, arg1, candidates != 0, complain);
 
     case ARRAY_REF:
-      return build_array_ref (arg1, arg2, input_location);
-
-    case COND_EXPR:
-      return build_conditional_expr (arg1, arg2, arg3, complain);
+      return build_array_ref (input_location, arg1, arg2);
 
     case MEMBER_REF:
-      return build_m_component_ref (cp_build_indirect_ref (arg1, NULL, 
+      return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL, 
                                                            complain), 
                                     arg2);
 
@@ -4285,6 +4536,33 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
   return 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]).  */
+
+static bool
+non_placement_deallocation_fn_p (tree t)
+{
+  /* A template instance is never a usual deallocation function,
+     regardless of its signature.  */
+  if (TREE_CODE (t) == TEMPLATE_DECL
+      || primary_template_instantiation_p (t))
+    return false;
+
+  /* If a class T has a member deallocation function named operator delete
+     with exactly one parameter, then that function is a usual
+     (non-placement) deallocation function. If class T does not declare
+     such an operator delete but does declare a member deallocation
+     function named operator delete with exactly two parameters, the second
+     of which has type std::size_t (18.2), then this function is a usual
+     deallocation function.  */
+  t = FUNCTION_ARG_CHAIN (t);
+  if (t == void_list_node
+      || (t && same_type_p (TREE_VALUE (t), size_type_node)
+         && TREE_CHAIN (t) == void_list_node))
+    return true;
+  return false;
+}
+
 /* Build a call to operator delete.  This has to be handled very specially,
    because the restrictions on what signatures match are different from all
    other call instances.  For a normal delete, only a delete taking (void *)
@@ -4310,8 +4588,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
                      tree alloc_fn)
 {
   tree fn = NULL_TREE;
-  tree fns, fnname, argtypes, type;
-  int pass;
+  tree fns, fnname, type, t;
 
   if (addr == error_mark_node)
     return error_mark_node;
@@ -4346,78 +4623,86 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
 
   if (placement)
     {
-      /* Get the parameter types for the allocation function that is
-        being called.  */
-      gcc_assert (alloc_fn != NULL_TREE);
-      argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
-    }
-  else
-    {
-      /* First try it without the size argument.  */
-      argtypes = void_list_node;
-    }
-
-  /* We make two tries at finding a matching `operator delete'.  On
-     the first pass, we look for a one-operator (or placement)
-     operator delete.  If we're not doing placement delete, then on
-     the second pass we look for a two-argument delete.  */
-  for (pass = 0; pass < (placement ? 1 : 2); ++pass)
-    {
-      /* Go through the `operator delete' functions looking for one
-        with a matching type.  */
-      for (fn = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
-          fn;
-          fn = OVL_NEXT (fn))
+      /* "A declaration of a placement deallocation function matches the
+        declaration of a placement allocation function if it has the same
+        number of parameters and, after parameter transformations (8.3.5),
+        all parameter types except the first are identical."
+
+        So we build up the function type we want and ask instantiate_type
+        to get it for us.  */
+      t = FUNCTION_ARG_CHAIN (alloc_fn);
+      t = tree_cons (NULL_TREE, ptr_type_node, t);
+      t = build_function_type (void_type_node, t);
+
+      fn = instantiate_type (t, fns, tf_none);
+      if (fn == error_mark_node)
+       return NULL_TREE;
+
+      if (BASELINK_P (fn))
+       fn = BASELINK_FUNCTIONS (fn);
+
+      /* "If the lookup finds the two-parameter form of a usual deallocation
+        function (3.7.4.2) and that function, considered as a placement
+        deallocation function, would have been selected as a match for the
+        allocation function, the program is ill-formed."  */
+      if (non_placement_deallocation_fn_p (fn))
        {
-         tree t;
-
-         /* The first argument must be "void *".  */
-         t = TYPE_ARG_TYPES (TREE_TYPE (OVL_CURRENT (fn)));
-         if (!same_type_p (TREE_VALUE (t), ptr_type_node))
-           continue;
-         t = TREE_CHAIN (t);
-         /* On the first pass, check the rest of the arguments.  */
-         if (pass == 0)
+         /* But if the class has an operator delete (void *), then that is
+            the usual deallocation function, so we shouldn't complain
+            about using the operator delete (void *, size_t).  */
+         for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
+              t; t = OVL_NEXT (t))
            {
-             tree a = argtypes;
-             while (a && t)
-               {
-                 if (!same_type_p (TREE_VALUE (a), TREE_VALUE (t)))
-                   break;
-                 a = TREE_CHAIN (a);
-                 t = TREE_CHAIN (t);
-               }
-             if (!a && !t)
-               break;
+             tree elt = OVL_CURRENT (t);
+             if (non_placement_deallocation_fn_p (elt)
+                 && FUNCTION_ARG_CHAIN (elt) == void_list_node)
+               goto ok;
            }
-         /* On the second pass, look for a function with exactly two
-            arguments: "void *" and "size_t".  */
-         else if (pass == 1
-                  /* For "operator delete(void *, ...)" there will be
-                     no second argument, but we will not get an exact
-                     match above.  */
-                  && t
-                  && same_type_p (TREE_VALUE (t), size_type_node)
-                  && TREE_CHAIN (t) == void_list_node)
-           break;
+         permerror (0, "non-placement deallocation function %q+D", fn);
+         permerror (input_location, "selected for placement delete");
+       ok:;
        }
-
-      /* If we found a match, we're done.  */
-      if (fn)
-       break;
     }
+  else
+    /* "Any non-placement deallocation function matches a non-placement
+       allocation function. If the lookup finds a single matching
+       deallocation function, that function will be called; otherwise, no
+       deallocation function will be called."  */
+    for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
+        t; t = OVL_NEXT (t))
+      {
+       tree elt = OVL_CURRENT (t);
+       if (non_placement_deallocation_fn_p (elt))
+         {
+           fn = elt;
+           /* "If a class T has a member deallocation function named
+              operator delete with exactly one parameter, then that
+              function is a usual (non-placement) deallocation
+              function. If class T does not declare such an operator
+              delete but does declare a member deallocation function named
+              operator delete with exactly two parameters, the second of
+              which has type std::size_t (18.2), then this function is a
+              usual deallocation function."
+
+              So (void*) beats (void*, size_t).  */
+           if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
+             break;
+         }
+      }
 
   /* If we have a matching function, call it.  */
   if (fn)
     {
-      /* Make sure we have the actual function, and not an
-        OVERLOAD.  */
-      fn = OVL_CURRENT (fn);
+      gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
 
       /* If the FN is a member function, make sure that it is
         accessible.  */
-      if (DECL_CLASS_SCOPE_P (fn))
-       perform_or_defer_access_check (TYPE_BINFO (type), fn, fn);
+      if (BASELINK_P (fns))
+       perform_or_defer_access_check (BASELINK_BINFO (fns), fn, fn);
+
+      /* Core issue 901: It's ok to new a type with deleted delete.  */
+      if (DECL_DELETED_FN (fn) && alloc_fn)
+       return NULL_TREE;
 
       if (placement)
        {
@@ -4434,13 +4719,14 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
        }
       else
        {
-         tree args;
-         if (pass == 0)
-           args = tree_cons (NULL_TREE, addr, NULL_TREE);
-         else
-           args = tree_cons (NULL_TREE, addr,
-                             build_tree_list (NULL_TREE, size));
-         return cp_build_function_call (fn, args, tf_warning_or_error);
+         tree ret;
+         VEC(tree,gc) *args = VEC_alloc (tree, gc, 2);
+         VEC_quick_push (tree, args, addr);
+         if (FUNCTION_ARG_CHAIN (fn) != void_list_node)
+           VEC_quick_push (tree, args, size);
+         ret = cp_build_function_call_vec (fn, &args, tf_warning_or_error);
+         VEC_free (tree, gc, args);
+         return ret;
        }
     }
 
@@ -4498,12 +4784,13 @@ build_temp (tree expr, tree type, int flags,
            diagnostic_t *diagnostic_kind)
 {
   int savew, savee;
+  VEC(tree,gc) *args;
 
   savew = warningcount, savee = errorcount;
-  expr = build_special_member_call (NULL_TREE,
-                                   complete_ctor_identifier,
-                                   build_tree_list (NULL_TREE, expr),
-                                   type, flags, tf_warning_or_error);
+  args = make_tree_vector_single (expr);
+  expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+                                   &args, type, flags, tf_warning_or_error);
+  release_tree_vector (args);
   if (warningcount > savew)
     *diagnostic_kind = DK_WARNING;
   else if (errorcount > savee)
@@ -4526,17 +4813,19 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
   if (expr == null_node && TREE_CODE (t) != BOOLEAN_TYPE && ARITHMETIC_TYPE_P (t))
     {
       if (fn)
-       warning (OPT_Wconversion, "passing NULL to non-pointer argument %P of %qD",
-                argnum, fn);
+       warning_at (input_location, OPT_Wconversion_null,
+                   "passing NULL to non-pointer argument %P of %qD",
+                   argnum, fn);
       else
-       warning (OPT_Wconversion, "converting to non-pointer type %qT from NULL", t);
+       warning_at (input_location, OPT_Wconversion_null,
+                   "converting to non-pointer type %qT from NULL", t);
     }
 
   /* Issue warnings if "false" is converted to a NULL pointer */
   else if (expr == boolean_false_node && fn && POINTER_TYPE_P (t))
-    warning (OPT_Wconversion,
-            "converting %<false%> to pointer type for argument %P of %qD",
-            argnum, fn);
+    warning_at (input_location, OPT_Wconversion_null,
+               "converting %<false%> to pointer type for argument %P of %qD",
+               argnum, fn);
 }
 
 /* Perform the conversions in CONVS on the expression EXPR.  FN and
@@ -4560,12 +4849,21 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 
   if (convs->bad_p
       && convs->kind != ck_user
+      && convs->kind != ck_list
       && convs->kind != ck_ambig
       && convs->kind != ck_ref_bind
       && convs->kind != ck_rvalue
       && convs->kind != ck_base)
     {
       conversion *t = convs;
+
+      /* Give a helpful error if this is bad because of excess braces.  */
+      if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+         && SCALAR_TYPE_P (totype)
+         && CONSTRUCTOR_NELTS (expr) > 0
+         && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
+       permerror (input_location, "too many braces around initializer for %qT", totype);
+
       for (; t; t = convs->u.next)
        {
          if (t->kind == ck_user || !t->bad_p)
@@ -4607,6 +4905,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        tree convfn = cand->fn;
        unsigned i;
 
+       expr = mark_rvalue_use (expr);
+
        /* When converting from an init list we consider explicit
           constructors, but actually trying to call one is an error.  */
        if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn))
@@ -4639,6 +4939,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        return expr;
       }
     case ck_identity:
+      expr = mark_rvalue_use (expr);
+      if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+       {
+         int nelts = CONSTRUCTOR_NELTS (expr);
+         if (nelts == 0)
+           expr = integer_zero_node;
+         else if (nelts == 1)
+           expr = CONSTRUCTOR_ELT (expr, 0)->value;
+         else
+           gcc_unreachable ();
+       }
+
       if (type_unknown_p (expr))
        expr = instantiate_type (totype, expr, complain);
       /* Convert a constant to its underlying value, unless we are
@@ -4647,7 +4959,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       if (inner >= 0)
         {   
           expr = decl_constant_value (expr);
-          if (expr == null_node && INTEGRAL_TYPE_P (totype))
+          if (expr == null_node && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype))
             /* If __null has been converted to an integer type, we do not
                want to warn about uses of EXPR as an integer, rather than
                as a pointer.  */
@@ -4655,6 +4967,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
         }
       return expr;
     case ck_ambig:
+      if (!(complain & tf_error))
+       return error_mark_node;
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
        (totype, convs->u.expr, LOOKUP_NORMAL);
@@ -4665,7 +4979,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        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, parms, val;
+       tree array, val;
+       VEC(tree,gc) *parms;
        unsigned ix;
 
        /* Convert all the elements.  */
@@ -4684,12 +4999,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        array = build_array_of_n_type (elttype, len);
        array = finish_compound_literal (array, new_ctor);
 
-       parms = build_tree_list (NULL_TREE, size_int (len));
-       parms = tree_cons (NULL_TREE, decay_conversion (array), parms);
+       parms = make_tree_vector ();
+       VEC_safe_push (tree, gc, parms, decay_conversion (array));
+       VEC_safe_push (tree, gc, parms, size_int (len));
        /* Call the private constructor.  */
        push_deferring_access_checks (dk_no_check);
        new_ctor = build_special_member_call
-         (NULL_TREE, complete_ctor_identifier, parms, totype, 0, complain);
+         (NULL_TREE, complete_ctor_identifier, &parms, totype, 0, complain);
+       release_tree_vector (parms);
        pop_deferring_access_checks ();
        return build_cplus_new (totype, new_ctor);
       }
@@ -4712,7 +5029,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
   switch (convs->kind)
     {
     case ck_rvalue:
-      expr = convert_bitfield_to_declared_type (expr);
+      expr = decay_conversion (expr);
       if (! MAYBE_CLASS_TYPE_P (totype))
        return expr;
       /* Else fall through.  */
@@ -4724,8 +5041,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
          /* Build an expression for `*((base*) &expr)'.  */
          expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
          expr = convert_to_base (expr, build_pointer_type (totype),
-                                 !c_cast_p, /*nonnull=*/true);
-         expr = cp_build_indirect_ref (expr, "implicit conversion", complain);
+                                 !c_cast_p, /*nonnull=*/true, complain);
+         expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
          return expr;
        }
 
@@ -4753,6 +5070,19 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       {
        tree ref_type = totype;
 
+       if (convs->bad_p && TYPE_REF_IS_RVALUE (ref_type)
+           && real_lvalue_p (expr))
+         {
+           if (complain & tf_error)
+             {
+               error ("cannot bind %qT lvalue to %qT",
+                      TREE_TYPE (expr), totype);
+               if (fn)
+                 error ("  initializing argument %P of %q+D", argnum, fn);
+             }
+           return error_mark_node;
+         }
+
        /* If necessary, create a temporary. 
 
            VA_ARG_EXPR and CONSTRUCTOR expressions are special cases
@@ -4834,7 +5164,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     case ck_ptr:
       if (convs->base_p)
        expr = convert_to_base (expr, totype, !c_cast_p,
-                               /*nonnull=*/false);
+                               /*nonnull=*/false, complain);
       return build_nop (totype, expr);
 
     case ck_pmem:
@@ -4856,18 +5186,6 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
   return expr;
 }
 
-/* Build a call to __builtin_trap.  */
-
-static tree
-call_builtin_trap (void)
-{
-  tree fn = implicit_built_in_decls[BUILT_IN_TRAP];
-
-  gcc_assert (fn != NULL);
-  fn = build_call_n (fn, 0);
-  return fn;
-}
-
 /* ARG is being passed to a varargs function.  Perform any conversions
    required.  Return the converted value.  */
 
@@ -4888,28 +5206,34 @@ convert_arg_to_ellipsis (tree arg)
      promoted type before the call.  */
   if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
       && (TYPE_PRECISION (TREE_TYPE (arg))
-         < TYPE_PRECISION (double_type_node)))
+         < TYPE_PRECISION (double_type_node))
+      && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (arg))))
     arg = convert_to_real (double_type_node, arg);
+  else if (TREE_CODE (TREE_TYPE (arg)) == NULLPTR_TYPE)
+    arg = null_pointer_node;
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
     arg = perform_integral_promotions (arg);
 
   arg = require_complete_type (arg);
 
   if (arg != error_mark_node
-      && !pod_type_p (TREE_TYPE (arg)))
+      && (type_has_nontrivial_copy_init (TREE_TYPE (arg))
+         || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (arg))))
     {
-      /* Undefined behavior [expr.call] 5.2.2/7.  We used to just warn
-        here and do a bitwise copy, but now cp_expr_size will abort if we
-        try to do that.
+      /* [expr.call] 5.2.2/7:
+        Passing a potentially-evaluated argument of class type (Clause 9)
+        with a non-trivial copy constructor or a non-trivial destructor
+        with no corresponding parameter is conditionally-supported, with
+        implementation-defined semantics.
+
+        We used to just warn here and do a bitwise copy, but now
+        cp_expr_size will abort if we try to do that.
+
         If the call appears in the context of a sizeof expression,
-        there is no need to emit a warning, since the expression won't be
-        evaluated. We keep the builtin_trap just as a safety check.  */
-      if (!skip_evaluation)
-       warning (0, "cannot pass objects of non-POD type %q#T through %<...%>; "
-                "call will abort at runtime", TREE_TYPE (arg));
-      arg = call_builtin_trap ();
-      arg = build2 (COMPOUND_EXPR, integer_type_node, arg,
-                   integer_zero_node);
+        it is not potentially-evaluated.  */
+      if (cp_unevaluated_operand == 0)
+       error ("cannot pass objects of non-trivially-copyable "
+              "type %q#T through %<...%>", TREE_TYPE (arg));
     }
 
   return arg;
@@ -4928,21 +5252,23 @@ build_x_va_arg (tree expr, tree type)
   if (expr == error_mark_node || !type)
     return error_mark_node;
 
-  if (! pod_type_p (type))
+  expr = mark_lvalue_use (expr);
+
+  if (type_has_nontrivial_copy_init (type)
+      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+      || TREE_CODE (type) == REFERENCE_TYPE)
     {
       /* Remove reference types so we don't ICE later on.  */
       tree type1 = non_reference (type);
-      /* Undefined behavior [expr.call] 5.2.2/7.  */
-      warning (0, "cannot receive objects of non-POD type %q#T through %<...%>; "
-              "call will abort at runtime", type);
+      /* conditionally-supported behavior [expr.call] 5.2.2/7.  */
+      error ("cannot receive objects of non-trivially-copyable type %q#T "
+            "through %<...%>; ", type);
       expr = convert (build_pointer_type (type1), null_node);
-      expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr),
-                    call_builtin_trap (), expr);
-      expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
+      expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
       return expr;
     }
 
-  return build_va_arg (expr, type);
+  return build_va_arg (input_location, expr, type);
 }
 
 /* TYPE has been given to va_arg.  Apply the default conversions which
@@ -5146,14 +5472,16 @@ static tree
 build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 {
   tree fn = cand->fn;
-  tree args = cand->args;
+  const VEC(tree,gc) *args = cand->args;
+  tree first_arg = cand->first_arg;
   conversion **convs = cand->convs;
   conversion *conv;
   tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
   int parmlen;
-  tree arg, val;
+  tree val;
   int i = 0;
   int j = 0;
+  unsigned int arg_index = 0;
   int is_method = 0;
   int nargs;
   tree *argarray;
@@ -5167,8 +5495,29 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
     {
       tree expr;
       tree return_type;
+      const tree *argarray;
+      unsigned int nargs;
+
       return_type = TREE_TYPE (TREE_TYPE (fn));
-      expr = build_call_list (return_type, build_addr_func (fn), args);
+      nargs = VEC_length (tree, args);
+      if (first_arg == NULL_TREE)
+       argarray = VEC_address (tree, CONST_CAST (VEC(tree,gc) *, args));
+      else
+       {
+         tree *alcarray;
+         unsigned int ix;
+         tree arg;
+
+         ++nargs;
+         alcarray = XALLOCAVEC (tree, nargs);
+         alcarray[0] = first_arg;
+         for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+           alcarray[ix + 1] = arg;
+         argarray = alcarray;
+       }
+      expr = build_call_array_loc (input_location,
+                                  return_type, build_addr_func (fn), nargs,
+                                  argarray);
       if (TREE_THIS_VOLATILE (fn) && cfun)
        current_function_returns_abnormally = 1;
       if (!VOID_TYPE_P (return_type))
@@ -5223,13 +5572,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        perform_or_defer_access_check (cand->access_path, fn, fn);
     }
 
-  if (args && TREE_CODE (args) != TREE_LIST)
-    args = build_tree_list (NULL_TREE, args);
-  arg = args;
-
   /* Find maximum size of vector to hold converted arguments.  */
   parmlen = list_length (parm);
-  nargs = list_length (args);
+  nargs = VEC_length (tree, args) + (first_arg != NULL_TREE ? 1 : 0);
   if (parmlen > nargs)
     nargs = parmlen;
   argarray = (tree *) alloca (nargs * sizeof (tree));
@@ -5238,16 +5583,24 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
      resolution, and must be of the proper type.  */
   if (DECL_CONSTRUCTOR_P (fn))
     {
-      argarray[j++] = TREE_VALUE (arg);
-      arg = TREE_CHAIN (arg);
+      if (first_arg != NULL_TREE)
+       {
+         argarray[j++] = first_arg;
+         first_arg = NULL_TREE;
+       }
+      else
+       {
+         argarray[j++] = VEC_index (tree, args, arg_index);
+         ++arg_index;
+       }
       parm = TREE_CHAIN (parm);
       /* We should never try to call the abstract constructor.  */
       gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn));
 
       if (DECL_HAS_VTT_PARM_P (fn))
        {
-         argarray[j++] = TREE_VALUE (arg);
-         arg = TREE_CHAIN (arg);
+         argarray[j++] = VEC_index (tree, args, arg_index);
+         ++arg_index;
          parm = TREE_CHAIN (parm);
        }
     }
@@ -5255,7 +5608,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
   else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
     {
       tree parmtype = TREE_VALUE (parm);
-      tree argtype = TREE_TYPE (TREE_VALUE (arg));
+      tree arg = (first_arg != NULL_TREE
+                 ? first_arg
+                 : VEC_index (tree, args, arg_index));
+      tree argtype = TREE_TYPE (arg);
       tree converted_arg;
       tree base_binfo;
 
@@ -5278,7 +5634,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       /* Convert to the base in which the function was declared.  */
       gcc_assert (cand->conversion_path != NULL_TREE);
       converted_arg = build_base_path (PLUS_EXPR,
-                                      TREE_VALUE (arg),
+                                      arg,
                                       cand->conversion_path,
                                       1);
       /* Check that the base class is accessible.  */
@@ -5297,13 +5653,17 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 
       argarray[j++] = converted_arg;
       parm = TREE_CHAIN (parm);
-      arg = TREE_CHAIN (arg);
+      if (first_arg != NULL_TREE)
+       first_arg = NULL_TREE;
+      else
+       ++arg_index;
       ++i;
       is_method = 1;
     }
 
-  for (; arg && parm;
-       parm = TREE_CHAIN (parm), arg = TREE_CHAIN (arg), ++i)
+  gcc_assert (first_arg == NULL_TREE);
+  for (; arg_index < VEC_length (tree, args) && parm;
+       parm = TREE_CHAIN (parm), ++arg_index, ++i)
     {
       tree type = TREE_VALUE (parm);
 
@@ -5315,8 +5675,35 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
          && !TREE_ADDRESSABLE (type))
        conv = conv->u.next;
 
+      /* Warn about initializer_list deduction that isn't currently in the
+        working draft.  */
+      if (cxx_dialect > cxx98
+         && flag_deduce_init_list
+         && cand->template_decl
+         && is_std_init_list (non_reference (type)))
+       {
+         tree tmpl = TI_TEMPLATE (cand->template_decl);
+         tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn));
+         tree patparm = get_pattern_parm (realparm, tmpl);
+         tree pattype = TREE_TYPE (patparm);
+         if (PACK_EXPANSION_P (pattype))
+           pattype = PACK_EXPANSION_PATTERN (pattype);
+         pattype = non_reference (pattype);
+
+         if (!is_std_init_list (pattype))
+           {
+             pedwarn (input_location, 0, "deducing %qT as %qT",
+                      non_reference (TREE_TYPE (patparm)),
+                      non_reference (type));
+             pedwarn (input_location, 0, "  in call to %q+D", cand->fn);
+             pedwarn (input_location, 0,
+                      "  (you can disable this with -fno-deduce-init-list)");
+           }
+       }
+
       val = convert_like_with_context
-       (conv, TREE_VALUE (arg), fn, i - is_method, complain);
+       (conv, VEC_index (tree, args, arg_index), fn, i - is_method,
+        complain);
 
       val = convert_for_arg_passing (type, val);
       if (val == error_mark_node)
@@ -5331,11 +5718,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
                                         TREE_PURPOSE (parm),
                                         fn, i - is_method);
   /* Ellipsis */
-  for (; arg; arg = TREE_CHAIN (arg))
+  for (; arg_index < VEC_length (tree, args); ++arg_index)
     {
-      tree a = TREE_VALUE (arg);
+      tree a = VEC_index (tree, args, arg_index);
       if (magic_varargs_p (fn))
-       /* Do no conversions for magic varargs.  */;
+       /* Do no conversions for magic varargs.  */
+       a = mark_type_use (a);
       else
        a = convert_arg_to_ellipsis (a);
       argarray[j++] = a;
@@ -5357,7 +5745,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
                || DECL_MOVE_CONSTRUCTOR_P (fn)))
     {
       tree targ;
-      arg = argarray[num_artificial_parms_for (fn)];
+      tree arg = argarray[num_artificial_parms_for (fn)];
+      tree fa;
 
       /* Pull out the real argument, disregarding const-correctness.  */
       targ = arg;
@@ -5377,7 +5766,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       if (targ)
        arg = targ;
       else
-       arg = cp_build_indirect_ref (arg, 0, complain);
+       arg = cp_build_indirect_ref (arg, RO_NULL, complain);
 
       if (TREE_CODE (arg) == TARGET_EXPR
          && TARGET_EXPR_LIST_INIT_P (arg))
@@ -5398,7 +5787,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
         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.  */
-      if (integer_zerop (TREE_VALUE (args)))
+      fa = (cand->first_arg != NULL_TREE
+           ? cand->first_arg
+           : VEC_index (tree, args, 0));
+      if (integer_zerop (fa))
        {
          if (TREE_CODE (arg) == TARGET_EXPR)
            return arg;
@@ -5409,8 +5801,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
               || (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))
                   && !move_fn_p (fn)))
        {
-         tree to = stabilize_reference
-           (cp_build_indirect_ref (TREE_VALUE (args), 0, complain));
+         tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL,
+                                                               complain));
 
          val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
          return val;
@@ -5421,14 +5813,22 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
           && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
     {
       tree to = stabilize_reference
-       (cp_build_indirect_ref (argarray[0], 0, complain));
+       (cp_build_indirect_ref (argarray[0], RO_NULL, complain));
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
+      tree arg = argarray[1];
 
-      arg = argarray[1];
-      if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+      if (is_really_empty_class (type))
        {
-         arg = cp_build_indirect_ref (arg, 0, complain);
+         /* Avoid copying empty classes.  */
+         val = build2 (COMPOUND_EXPR, void_type_node, to, arg);
+         TREE_NO_WARNING (val) = 1;
+         val = build2 (COMPOUND_EXPR, type, val, to);
+         TREE_NO_WARNING (val) = 1;
+       }
+      else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+       {
+         arg = cp_build_indirect_ref (arg, RO_NULL, complain);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
        }
       else
@@ -5445,11 +5845,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
          arg1 = arg;
          arg0 = cp_build_unary_op (ADDR_EXPR, to, 0, complain);
 
-         if (!(optimize && flag_tree_ter))
+         if (!can_trust_pointer_alignment ())
            {
-             /* When TER is off get_pointer_alignment returns 0, so a call
+             /* If we can't be sure about pointer alignment, a call
                 to __builtin_memcpy is expanded as a call to memcpy, which
-                is invalid with identical args.  When TER is on it is
+                is invalid with identical args.  Otherwise it is
                 expanded as a block move, which should be safe.  */
              arg0 = save_expr (arg0);
              arg1 = save_expr (arg1);
@@ -5461,7 +5861,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
          t = convert (TREE_TYPE (arg0), t);
          if (test)
            t = build3 (COND_EXPR, TREE_TYPE (t), test, arg0, t);
-         val = cp_build_indirect_ref (t, 0, complain);
+         val = cp_build_indirect_ref (t, RO_NULL, complain);
           TREE_NO_WARNING (val) = 1;
        }
 
@@ -5569,7 +5969,7 @@ build_java_interface_fn_ref (tree fn, tree instance)
 
   /* Look up the pointer to the runtime java.lang.Class object for `instance'.
      This is the first entry in the vtable.  */
-  klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, 0
+  klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, RO_NULL
                                                      tf_warning_or_error),
                              integer_zero_node);
 
@@ -5631,9 +6031,10 @@ in_charge_arg_for_name (tree name)
 
 /* Build a call to a constructor, destructor, or an assignment
    operator for INSTANCE, an expression with class type.  NAME
-   indicates the special member function to call; ARGS are the
-   arguments.  BINFO indicates the base of INSTANCE that is to be
-   passed as the `this' parameter to the member function called.
+   indicates the special member function to call; *ARGS are the
+   arguments.  ARGS may be NULL.  This may change ARGS.  BINFO
+   indicates the base of INSTANCE that is to be passed as the `this'
+   parameter to the member function called.
 
    FLAGS are the LOOKUP_* flags to use when processing the call.
 
@@ -5642,12 +6043,14 @@ in_charge_arg_for_name (tree name)
    store the newly constructed object into a VAR_DECL.  */
 
 tree
-build_special_member_call (tree instance, tree name, tree args,
+build_special_member_call (tree instance, tree name, VEC(tree,gc) **args,
                           tree binfo, int flags, tsubst_flags_t complain)
 {
   tree fns;
   /* The type of the subobject to be constructed or destroyed.  */
   tree class_type;
+  VEC(tree,gc) *allocated = NULL;
+  tree ret;
 
   gcc_assert (name == complete_ctor_identifier
              || name == base_ctor_identifier
@@ -5679,7 +6082,7 @@ build_special_member_call (tree instance, tree name, tree args,
       if (name == complete_dtor_identifier
          || name == base_dtor_identifier
          || name == deleting_dtor_identifier)
-       gcc_assert (args == NULL_TREE);
+       gcc_assert (args == NULL || VEC_empty (tree, *args));
 
       /* Convert to the base class, if necessary.  */
       if (!same_type_ignoring_top_level_qualifiers_p
@@ -5728,13 +6131,24 @@ build_special_member_call (tree instance, tree name, tree args,
       sub_vtt = build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtt), vtt,
                        BINFO_SUBVTT_INDEX (binfo));
 
-      args = tree_cons (NULL_TREE, sub_vtt, args);
+      if (args == NULL)
+       {
+         allocated = make_tree_vector ();
+         args = &allocated;
+       }
+
+      VEC_safe_insert (tree, gc, *args, 0, sub_vtt);
     }
 
-  return build_new_method_call (instance, fns, args,
-                               TYPE_BINFO (BINFO_TYPE (binfo)),
-                               flags, /*fn=*/NULL,
-                               complain);
+  ret = build_new_method_call (instance, fns, args,
+                              TYPE_BINFO (BINFO_TYPE (binfo)),
+                              flags, /*fn=*/NULL,
+                              complain);
+
+  if (allocated != NULL)
+    release_tree_vector (allocated);
+
+  return ret;
 }
 
 /* Return the NAME, as a C string.  The NAME indicates a function that
@@ -5783,10 +6197,11 @@ name_as_c_string (tree name, tree type, bool *free_p)
 }
 
 /* Build a call to "INSTANCE.FN (ARGS)".  If FN_P is non-NULL, it will
-   be set, upon return, to the function called.  */
+   be set, upon return, to the function called.  ARGS may be NULL.
+   This may change ARGS.  */
 
 tree
-build_new_method_call (tree instance, tree fns, tree args,
+build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
                       tree conversion_path, int flags,
                       tree *fn_p, tsubst_flags_t complain)
 {
@@ -5795,18 +6210,21 @@ build_new_method_call (tree instance, tree fns, tree args,
   tree basetype = NULL_TREE;
   tree access_binfo;
   tree optype;
-  tree mem_args = NULL_TREE, instance_ptr;
+  tree first_mem_arg = NULL_TREE;
+  tree instance_ptr;
   tree name;
-  tree user_args;
+  bool skip_first_for_error;
+  VEC(tree,gc) *user_args;
   tree call;
   tree fn;
-  tree class_type;
   int template_only = 0;
   bool any_viable_p;
   tree orig_instance;
   tree orig_fns;
-  tree orig_args;
+  VEC(tree,gc) *orig_args = NULL;
   void *p;
+  tree list = NULL_TREE;
+  bool try_normal;
 
   gcc_assert (instance != NULL_TREE);
 
@@ -5815,8 +6233,7 @@ build_new_method_call (tree instance, tree fns, tree args,
     *fn_p = NULL_TREE;
 
   if (error_operand_p (instance)
-      || error_operand_p (fns)
-      || args == error_mark_node)
+      || !fns || error_operand_p (fns))
     return error_mark_node;
 
   if (!BASELINK_P (fns))
@@ -5828,7 +6245,6 @@ build_new_method_call (tree instance, tree fns, tree args,
 
   orig_instance = instance;
   orig_fns = fns;
-  orig_args = args;
 
   /* Dismantle the baselink to collect all the information we need.  */
   if (!conversion_path)
@@ -5853,16 +6269,37 @@ build_new_method_call (tree instance, tree fns, tree args,
 
   if (processing_template_decl)
     {
+      orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
       instance = build_non_dependent_expr (instance);
-      args = build_non_dependent_args (orig_args);
+      if (args != NULL)
+       make_args_non_dependent (*args);
     }
 
-  /* The USER_ARGS are the arguments we will display to users if an
-     error occurs.  The USER_ARGS should not include any
-     compiler-generated arguments.  The "this" pointer hasn't been
-     added yet.  However, we must remove the VTT pointer if this is a
-     call to a base-class constructor or destructor.  */
-  user_args = args;
+  user_args = args == NULL ? NULL : *args;
+  /* Under DR 147 A::A() is an invalid constructor call,
+     not a functional cast.  */
+  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
+    {
+      if (! (complain & tf_error))
+       return error_mark_node;
+
+      permerror (input_location,
+                "cannot call constructor %<%T::%D%> directly",
+                basetype, name);
+      permerror (input_location, "  for a function-style cast, remove the "
+                "redundant %<::%D%>", name);
+      call = build_functional_cast (basetype, build_tree_list_vec (user_args),
+                                   complain);
+      return call;
+    }
+
+  /* Figure out whether to skip the first argument for the error
+     message we will display to users if an error occurs.  We don't
+     want to display any compiler-generated arguments.  The "this"
+     pointer hasn't been added yet.  However, we must remove the VTT
+     pointer if this is a call to a base-class constructor or
+     destructor.  */
+  skip_first_for_error = false;
   if (IDENTIFIER_CTOR_OR_DTOR_P (name))
     {
       /* Callers should explicitly indicate whether they want to construct
@@ -5873,13 +6310,16 @@ build_new_method_call (tree instance, tree fns, tree args,
       /* Remove the VTT pointer, if present.  */
       if ((name == base_ctor_identifier || name == base_dtor_identifier)
          && CLASSTYPE_VBASECLASSES (basetype))
-       user_args = TREE_CHAIN (user_args);
+       skip_first_for_error = true;
     }
 
   /* Process the argument list.  */
-  args = resolve_args (args);
-  if (args == error_mark_node)
-    return error_mark_node;
+  if (args != NULL && *args != NULL)
+    {
+      *args = resolve_args (*args);
+      if (*args == NULL)
+       return error_mark_node;
+    }
 
   instance_ptr = build_this (instance);
 
@@ -5897,72 +6337,68 @@ build_new_method_call (tree instance, tree fns, tree args,
     name = complete_dtor_identifier;
 
   /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form
-     initializer, not T({ }).  If the type doesn't have a list ctor,
-     break apart the list into separate ctor args.  */
-  if (DECL_CONSTRUCTOR_P (fn) && args
-      && BRACE_ENCLOSED_INITIALIZER_P (TREE_VALUE (args))
-      && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (args))
-      && !TYPE_HAS_LIST_CTOR (basetype))
-    {
-      gcc_assert (TREE_CHAIN (args) == NULL_TREE);
-      args = ctor_to_list (TREE_VALUE (args));
+     initializer, not T({ }).  If the type doesn't have a list ctor (or no
+     viable list ctor), break apart the list into separate ctor args.  */
+  try_normal = true;
+  if (DECL_CONSTRUCTOR_P (fn) && args != NULL && !VEC_empty (tree, *args)
+      && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *args, 0))
+      && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0)))
+    {
+      gcc_assert (VEC_length (tree, *args) == 1);
+      list = VEC_index (tree, *args, 0);
+
+      if (TYPE_HAS_LIST_CTOR (basetype))
+       flags |= LOOKUP_LIST_ONLY;
+      else
+       try_normal = false;
     }
 
-  class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
-  mem_args = tree_cons (NULL_TREE, instance_ptr, args);
+  first_mem_arg = instance_ptr;
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
-  for (fn = fns; fn; fn = OVL_NEXT (fn))
+  any_viable_p = false;
+  if (try_normal)
     {
-      tree t = OVL_CURRENT (fn);
-      tree this_arglist;
-
-      /* We can end up here for copy-init of same or base class.  */
-      if ((flags & LOOKUP_ONLYCONVERTING)
-         && DECL_NONCONVERTING_P (t))
-       continue;
-
-      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
-       this_arglist = mem_args;
-      else
-       this_arglist = args;
+      add_candidates (fns, first_mem_arg, user_args, optype,
+                     explicit_targs, template_only, conversion_path,
+                     access_binfo, flags, &candidates);
+      candidates = splice_viable (candidates, pedantic, &any_viable_p);
+    }
 
-      if (TREE_CODE (t) == TEMPLATE_DECL)
-       /* A member template.  */
-       add_template_candidate (&candidates, t,
-                               class_type,
-                               explicit_targs,
-                               this_arglist, optype,
-                               access_binfo,
-                               conversion_path,
-                               flags,
-                               DEDUCE_CALL);
-      else if (! template_only)
-       add_function_candidate (&candidates, t,
-                               class_type,
-                               this_arglist,
-                               access_binfo,
-                               conversion_path,
-                               flags);
+  if (!any_viable_p && list)
+    {
+      VEC(tree,gc) *list_args = ctor_to_vec (list);
+      flags &= ~LOOKUP_LIST_ONLY;
+      add_candidates (fns, first_mem_arg, list_args, optype,
+                     explicit_targs, template_only, conversion_path,
+                     access_binfo, flags, &candidates);
+      candidates = splice_viable (candidates, pedantic, &any_viable_p);
     }
 
-  candidates = splice_viable (candidates, pedantic, &any_viable_p);
   if (!any_viable_p)
     {
       if (complain & tf_error)
        {
          if (!COMPLETE_TYPE_P (basetype))
            cxx_incomplete_type_error (instance_ptr, 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 (TREE_TYPE (instance_ptr)));
          else
            {
              char *pretty_name;
              bool free_p;
+             tree arglist;
 
              pretty_name = name_as_c_string (name, basetype, &free_p);
+             arglist = build_tree_list_vec (user_args);
+             if (skip_first_for_error)
+               arglist = TREE_CHAIN (arglist);
              error ("no matching function for call to %<%T::%s(%A)%#V%>",
-                    basetype, pretty_name, user_args,
+                    basetype, pretty_name, arglist,
                     TREE_TYPE (TREE_TYPE (instance_ptr)));
              if (free_p)
                free (pretty_name);
@@ -5978,12 +6414,16 @@ build_new_method_call (tree instance, tree fns, tree args,
        {
          char *pretty_name;
          bool free_p;
+         tree arglist;
 
          if (complain & tf_error)
            {
              pretty_name = name_as_c_string (name, basetype, &free_p);
+             arglist = build_tree_list_vec (user_args);
+             if (skip_first_for_error)
+               arglist = TREE_CHAIN (arglist);
              error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
-                    user_args);
+                    arglist);
              print_z_candidates (candidates);
              if (free_p)
                free (pretty_name);
@@ -6064,7 +6504,7 @@ build_new_method_call (tree instance, tree fns, tree args,
        }
       if (TREE_CODE (call) == INDIRECT_REF)
        call = TREE_OPERAND (call, 0);
-      call = (build_min_non_dep_call_list
+      call = (build_min_non_dep_call_vec
              (call,
               build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
                          orig_instance, orig_fns, NULL_TREE),
@@ -6077,6 +6517,9 @@ build_new_method_call (tree instance, tree fns, tree args,
  /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
 
+  if (orig_args != NULL)
+    release_tree_vector (orig_args);
+
   return call;
 }
 
@@ -6185,7 +6628,6 @@ maybe_handle_ref_bind (conversion **ics)
       conversion *old_ics = *ics;
       *ics = old_ics->u.next;
       (*ics)->user_conv_p = old_ics->user_conv_p;
-      (*ics)->bad_p = old_ics->bad_p;
       return old_ics;
     }
 
@@ -6226,6 +6668,14 @@ compare_ics (conversion *ics1, conversion *ics2)
   ref_conv1 = maybe_handle_ref_bind (&ics1);
   ref_conv2 = maybe_handle_ref_bind (&ics2);
 
+  /* List-initialization sequence L1 is a better conversion sequence than
+     list-initialization sequence L2 if L1 converts to
+     std::initializer_list<X> for some X and L2 does not.  */
+  if (ics1->kind == ck_list && ics2->kind != ck_list)
+    return 1;
+  if (ics2->kind == ck_list && ics1->kind != ck_list)
+    return -1;
+
   /* [over.ics.rank]
 
      When  comparing  the  basic forms of implicit conversion sequences (as
@@ -6261,8 +6711,9 @@ compare_ics (conversion *ics1, conversion *ics2)
       /* We couldn't make up our minds; try to figure it out below.  */
     }
 
-  if (ics1->ellipsis_p)
-    /* Both conversions are ellipsis conversions.  */
+  if (ics1->ellipsis_p || ics1->kind == ck_list)
+    /* Both conversions are ellipsis conversions or both are building a
+       std::initializer_list.  */
     return 0;
 
   /* User-defined  conversion sequence U1 is a better conversion sequence
@@ -6276,26 +6727,13 @@ compare_ics (conversion *ics1, conversion *ics2)
       conversion *t1;
       conversion *t2;
 
-      for (t1 = ics1; t1->kind != ck_user && t1->kind != ck_list; t1 = t1->u.next)
+      for (t1 = ics1; t1->kind != ck_user; t1 = t1->u.next)
        if (t1->kind == ck_ambig || t1->kind == ck_aggr)
          return 0;
-      for (t2 = ics2; t2->kind != ck_user && t2->kind != ck_list; t2 = t2->u.next)
+      for (t2 = ics2; t2->kind != ck_user; t2 = t2->u.next)
        if (t2->kind == ck_ambig || t2->kind == ck_aggr)
          return 0;
 
-      /* Conversion to std::initializer_list is better than other
-        user-defined conversions.  */
-      if (t1->kind == ck_list
-         || t2->kind == ck_list)
-       {
-         if (t2->kind != ck_list)
-           return 1;
-         else if (t1->kind != ck_list)
-           return -1;
-         else
-           return 0;
-       }
-
       if (t1->cand->fn != t2->cand->fn)
        return 0;
 
@@ -6359,9 +6797,8 @@ compare_ics (conversion *ics1, conversion *ics2)
     Two conversion sequences with the same rank are indistinguishable
     unless one of the following rules applies:
 
-    --A conversion that is not a conversion of a pointer, or pointer
-      to member, to bool is better than another conversion that is such
-      a conversion.
+    --A conversion that does not a convert a pointer, pointer to member,
+      or std::nullptr_t to bool is better than one that does.
 
     The ICS_STD_RANK automatically handles the pointer-to-bool rule,
     so that we do not have to check it explicitly.  */
@@ -6999,7 +7436,7 @@ tourney (struct z_candidate *candidates)
 bool
 can_convert (tree to, tree from)
 {
-  return can_convert_arg (to, from, NULL_TREE, LOOKUP_NORMAL);
+  return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT);
 }
 
 /* Returns nonzero if ARG (of type FROM) can be converted to TO.  */
@@ -7027,7 +7464,7 @@ can_convert_arg (tree to, tree from, tree arg, int flags)
 /* Like can_convert_arg, but allows dubious conversions as well.  */
 
 bool
-can_convert_arg_bad (tree to, tree from, tree arg)
+can_convert_arg_bad (tree to, tree from, tree arg, int flags)
 {
   conversion *t;
   void *p;
@@ -7036,7 +7473,7 @@ can_convert_arg_bad (tree to, tree from, tree arg)
   p = conversion_obstack_alloc (0);
   /* Try to perform the conversion.  */
   t  = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
-                           LOOKUP_NORMAL);
+                           flags);
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
 
@@ -7132,9 +7569,10 @@ perform_direct_initialization_if_possible (tree type,
      ill-formed.  */
   if (CLASS_TYPE_P (type))
     {
+      VEC(tree,gc) *args = make_tree_vector_single (expr);
       expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
-                                       build_tree_list (NULL_TREE, expr),
-                                       type, LOOKUP_NORMAL, complain);
+                                       &args, type, LOOKUP_NORMAL, complain);
+      release_tree_vector (args);
       return build_cplus_new (type, expr);
     }
 
@@ -7150,7 +7588,7 @@ perform_direct_initialization_if_possible (tree type,
     expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
                              /*issue_conversion_warnings=*/false,
                              c_cast_p,
-                             tf_warning_or_error);
+                             complain);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -7272,7 +7710,8 @@ set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp)
    Return the converted expression.  */
 
 tree
-initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
+initialize_reference (tree type, tree expr, tree decl, tree *cleanup,
+                     tsubst_flags_t complain)
 {
   conversion *conv;
   void *p;
@@ -7287,15 +7726,19 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
                            LOOKUP_NORMAL);
   if (!conv || conv->bad_p)
     {
-      if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
-         && !real_lvalue_p (expr))
-       error ("invalid initialization of non-const reference of "
-              "type %qT from a temporary of type %qT",
-              type, TREE_TYPE (expr));
-      else
-       error ("invalid initialization of reference of type "
-              "%qT from expression of type %qT", type,
-              TREE_TYPE (expr));
+      if (complain & tf_error)
+       {
+         if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
+             && !TYPE_REF_IS_RVALUE (type)
+             && !real_lvalue_p (expr))
+           error ("invalid initialization of non-const reference of "
+                  "type %qT from an rvalue of type %qT",
+                  type, TREE_TYPE (expr));
+         else
+           error ("invalid initialization of reference of type "
+                  "%qT from expression of type %qT", type,
+                  TREE_TYPE (expr));
+       }
       return error_mark_node;
     }
 
@@ -7361,7 +7804,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
        expr = error_mark_node;
       else
        {
-         if (!real_lvalue_p (expr))
+         if (!lvalue_or_rvalue_with_address_p (expr))
            {
              tree init;
              var = set_up_extended_ref_temp (decl, expr, cleanup, &init);
@@ -7371,7 +7814,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
                expr = convert_to_base (expr,
                                        build_pointer_type (base_conv_type),
                                        /*check_access=*/true,
-                                       /*nonnull=*/true);
+                                       /*nonnull=*/true, complain);
              expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
            }
          else