OSDN Git Service

2009-08-14 Douglas B Rupp <rupp@gnat.com>
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 79b8cd5..f6a083b 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions related to invoking methods and overloaded functions.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) and
    modified by Brendan Kehoe (brendan@cygnus.com).
@@ -54,6 +54,8 @@ typedef enum conversion_kind {
   ck_ref_bind,
   ck_user,
   ck_ambig,
+  ck_list,
+  ck_aggr,
   ck_rvalue
 } conversion_kind;
 
@@ -89,10 +91,6 @@ struct conversion {
      temporary should be created to hold the result of the
      conversion.  */
   BOOL_BITFIELD need_temporary_p : 1;
-  /* If KIND is ck_identity or ck_base_conv, true to indicate that the
-     copy constructor must be accessible, even though it is not being
-     used.  */
-  BOOL_BITFIELD check_copy_constructor_p : 1;
   /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion
      from a pointer-to-derived to pointer-to-base is being performed.  */
   BOOL_BITFIELD base_p : 1;
@@ -100,6 +98,7 @@ struct conversion {
      being bound to an lvalue expression or an rvalue reference is
      being bound to an rvalue expression. */
   BOOL_BITFIELD rvaluedness_matches_p: 1;
+  BOOL_BITFIELD check_narrowing: 1;
   /* The type of the expression resulting from the conversion.  */
   tree type;
   union {
@@ -111,6 +110,8 @@ struct conversion {
     /* The expression at the beginning of the conversion chain.  This
        variant is used only if KIND is ck_identity or ck_ambig.  */
     tree expr;
+    /* The array of conversions for an initializer_list.  */
+    conversion **list;
   } u;
   /* The function candidate corresponding to this conversion
      sequence.  This field is only used if KIND is ck_user.  */
@@ -130,22 +131,21 @@ static struct z_candidate * tourney (struct z_candidate *);
 static int equal_functions (tree, tree);
 static int joust (struct z_candidate *, struct z_candidate *, bool);
 static int compare_ics (conversion *, conversion *);
-static tree build_over_call (struct z_candidate *, int);
+static tree build_over_call (struct z_candidate *, int, tsubst_flags_t);
 static tree build_java_interface_fn_ref (tree, tree);
-#define convert_like(CONV, EXPR)                               \
+#define convert_like(CONV, EXPR, COMPLAIN)                     \
   convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0,          \
                     /*issue_conversion_warnings=*/true,        \
-                    /*c_cast_p=*/false)
-#define convert_like_with_context(CONV, EXPR, FN, ARGNO)       \
-  convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0,         \
-                    /*issue_conversion_warnings=*/true,        \
-                    /*c_cast_p=*/false)
+                    /*c_cast_p=*/false, (COMPLAIN))
+#define convert_like_with_context(CONV, EXPR, FN, ARGNO, COMPLAIN )    \
+  convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0,                 \
+                    /*issue_conversion_warnings=*/true,                \
+                    /*c_cast_p=*/false, (COMPLAIN))
 static tree convert_like_real (conversion *, tree, tree, int, int, bool,
-                              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);
-static tree resolve_args (tree);
+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 *);
@@ -153,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);
@@ -171,37 +172,36 @@ 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);
 static conversion *build_conv (conversion_kind, tree, conversion *);
+static conversion *build_list_conv (tree, tree, int);
 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);
+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,
+static void add_candidates (tree, const VEC(tree,gc) *, tree, bool, tree, tree,
                            int, struct z_candidate **);
 static conversion *merge_conversion_sequences (conversion *, conversion *);
 static bool magic_varargs_p (tree);
-typedef void (*diagnostic_fn_t) (const char *, ...) ATTRIBUTE_GCC_CXXDIAG(1,2);
-static tree build_temp (tree, tree, int, diagnostic_fn_t *);
-static void check_constructor_callable (tree, tree);
+static tree build_temp (tree, tree, int, diagnostic_t *);
 
 /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE.
    NAME can take many forms...  */
@@ -219,7 +219,8 @@ check_dtor_name (tree basetype, tree name)
     /* OK */;
   else if (TREE_CODE (name) == IDENTIFIER_NODE)
     {
-      if ((IS_AGGR_TYPE (basetype) && name == constructor_name (basetype))
+      if ((MAYBE_CLASS_TYPE_P (basetype)
+          && name == constructor_name (basetype))
          || (TREE_CODE (basetype) == ENUMERAL_TYPE
              && name == TYPE_IDENTIFIER (basetype)))
        return true;
@@ -239,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));
 }
@@ -337,11 +338,11 @@ build_call_a (tree function, int n, tree *argarray)
   nothrow = ((decl && TREE_NOTHROW (decl))
             || TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (function))));
 
-  if (decl && TREE_THIS_VOLATILE (decl) && cfun)
+  if (decl && TREE_THIS_VOLATILE (decl) && cfun && cp_function_chain)
     current_function_returns_abnormally = 1;
 
   if (decl && TREE_DEPRECATED (decl))
-    warn_deprecated_use (decl);
+    warn_deprecated_use (decl, NULL_TREE);
   require_complete_eh_spec_types (fntype, decl);
 
   if (decl && DECL_CONSTRUCTOR_P (decl))
@@ -360,7 +361,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;
 
@@ -412,8 +414,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;
@@ -467,7 +474,7 @@ null_ptr_cst_p (tree t)
    ellipsis.  */
 
 bool
-sufficient_parms_p (tree parmlist)
+sufficient_parms_p (const_tree parmlist)
 {
   for (; parmlist && parmlist != void_list_node;
        parmlist = TREE_CHAIN (parmlist))
@@ -533,9 +540,8 @@ build_conv (conversion_kind code, tree type, conversion *from)
   conversion *t;
   conversion_rank rank = CONVERSION_RANK (from);
 
-  /* We can't use buildl1 here because CODE could be USER_CONV, which
-     takes two arguments.  In that case, the caller is responsible for
-     filling in the second argument.  */
+  /* Note that the caller is responsible for filling in t->cand for
+     user-defined conversions.  */
   t = alloc_conversion (code);
   t->type = type;
   t->u.next = from;
@@ -565,6 +571,83 @@ build_conv (conversion_kind code, tree type, conversion *from)
   return t;
 }
 
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, a
+   specialization of std::initializer_list<T>, if such a conversion is
+   possible.  */
+
+static conversion *
+build_list_conv (tree type, tree ctor, int flags)
+{
+  tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type), 0);
+  unsigned len = CONSTRUCTOR_NELTS (ctor);
+  conversion **subconvs = alloc_conversions (len);
+  conversion *t;
+  unsigned i;
+  tree val;
+
+  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
+    {
+      conversion *sub
+       = implicit_conversion (elttype, TREE_TYPE (val), val,
+                              false, flags);
+      if (sub == NULL)
+       return NULL;
+
+      subconvs[i] = sub;
+    }
+
+  t = alloc_conversion (ck_list);
+  t->type = type;
+  t->u.list = subconvs;
+  t->rank = cr_exact;
+
+  for (i = 0; i < len; ++i)
+    {
+      conversion *sub = subconvs[i];
+      if (sub->rank > t->rank)
+       t->rank = sub->rank;
+      if (sub->user_conv_p)
+       t->user_conv_p = true;
+      if (sub->bad_p)
+       t->bad_p = true;
+    }
+
+  return t;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
+   aggregate class, if such a conversion is possible.  */
+
+static conversion *
+build_aggr_conv (tree type, tree ctor, int flags)
+{
+  unsigned HOST_WIDE_INT i = 0;
+  conversion *c;
+  tree field = TYPE_FIELDS (type);
+
+  for (; field; field = TREE_CHAIN (field), ++i)
+    {
+      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;
+       }
+      else if (build_value_init (TREE_TYPE (field)) == error_mark_node)
+       return NULL;
+    }
+
+  c = alloc_conversion (ck_aggr);
+  c->type = type;
+  c->rank = cr_exact;
+  c->user_conv_p = true;
+  c->u.next = NULL;
+  return c;
+}
+
 /* Build a representation of the identity conversion from EXPR to
    itself.  The TYPE should match the type of EXPR, if EXPR is non-NULL.  */
 
@@ -629,7 +712,10 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
       && expr && type_unknown_p (expr))
     {
-      expr = instantiate_type (to, expr, tf_conv);
+      tsubst_flags_t tflags = tf_conv;
+      if (!(flags & LOOKUP_PROTECT))
+       tflags |= tf_no_access_control;
+      expr = instantiate_type (to, expr, tflags);
       if (expr == error_mark_node)
        return NULL;
       from = TREE_TYPE (expr);
@@ -694,7 +780,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
       conv = build_conv (ck_std, to, conv);
       conv->bad_p = true;
     }
-  else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE)
+  else if (UNSCOPED_ENUM_P (to) && fcode == INTEGER_TYPE)
     {
       /* For backwards brain damage compatibility, allow interconversion of
         enums and integers with a pedwarn.  */
@@ -737,8 +823,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
          else if (!same_type_p (fbase, tbase))
            return NULL;
        }
-      else if (IS_AGGR_TYPE (TREE_TYPE (from))
-              && IS_AGGR_TYPE (TREE_TYPE (to))
+      else if (CLASS_TYPE_P (TREE_TYPE (from))
+              && CLASS_TYPE_P (TREE_TYPE (to))
               /* [conv.ptr]
 
                  An rvalue of type "pointer to cv D," where D is a
@@ -750,19 +836,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
                  that necessitates this conversion is ill-formed.
                  Therefore, we use DERIVED_FROM_P, and do not check
                  access or uniqueness.  */
-              && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from))
-              /* If FROM is not yet complete, then we must be parsing
-                 the body of a class.  We know what's derived from
-                 what, but we can't actually perform a
-                 derived-to-base conversion.  For example, in:
-
-                    struct D : public B { 
-                       static const int i = sizeof((B*)(D*)0);
-                     };
-
-                  the D*-to-B* conversion is a reinterpret_cast, not a
-                 static_cast.  */
-              && COMPLETE_TYPE_P (TREE_TYPE (from)))
+              && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
        {
          from =
            cp_build_qualified_type (TREE_TYPE (to),
@@ -831,10 +905,11 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
     {
       /* [conv.bool]
 
-         An rvalue of arithmetic, enumeration, pointer, or pointer to
-         member type can be converted to an rvalue of type bool.  */
+         An rvalue of arithmetic, unscoped enumeration, pointer, or
+         pointer to member type can be converted to an rvalue of type
+         bool.  */
       if (ARITHMETIC_TYPE_P (from)
-         || fcode == ENUMERAL_TYPE
+         || UNSCOPED_ENUM_P (from)
          || fcode == POINTER_TYPE
          || TYPE_PTR_TO_MEMBER_P (from))
        {
@@ -851,10 +926,11 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
     }
   /* We don't check for ENUMERAL_TYPE here because there are no standard
      conversions to enum type.  */
-  else if (tcode == INTEGER_TYPE || tcode == BOOLEAN_TYPE
-          || tcode == REAL_TYPE)
+  /* As an extension, allow conversion to complex type.  */
+  else if (ARITHMETIC_TYPE_P (to))
     {
-      if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE))
+      if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE)
+          || SCOPED_ENUM_P (from))
        return NULL;
       conv = build_conv (ck_std, to, conv);
 
@@ -866,8 +942,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
           && vector_types_convertible_p (from, to, false))
     return build_conv (ck_std, to, conv);
-  else if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE)
-          && IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
+  else if (MAYBE_CLASS_TYPE_P (to) && MAYBE_CLASS_TYPE_P (from)
           && is_properly_derived_from (from, to))
     {
       if (conv->kind == ck_rvalue)
@@ -876,18 +951,21 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
       /* The derived-to-base conversion indicates the initialization
         of a parameter with base type from an object of a derived
         type.  A temporary object is created to hold the result of
-        the conversion.  */
-      conv->need_temporary_p = true;
+        the conversion unless we're binding directly to a reference.  */
+      conv->need_temporary_p = !(flags & LOOKUP_NO_TEMP_BIND);
     }
   else
     return NULL;
 
+  if (flags & LOOKUP_NO_NARROWING)
+    conv->check_narrowing = true;
+
   return conv;
 }
 
 /* Returns nonzero if T1 is reference-related to T2.  */
 
-static bool
+bool
 reference_related_p (tree t1, tree t2)
 {
   t1 = TYPE_MAIN_VARIANT (t1);
@@ -921,10 +999,10 @@ reference_compatible_p (tree t1, tree t2)
    converted to T as in [over.match.ref].  */
 
 static conversion *
-convert_class_to_reference (tree reference_type, tree s, tree expr)
+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;
@@ -957,12 +1035,11 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
      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);
 
-  while (conversions)
+  for (; conversions; conversions = TREE_CHAIN (conversions))
     {
       tree fns = TREE_VALUE (conversions);
 
@@ -971,6 +1048,10 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
          tree f = OVL_CURRENT (fns);
          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
@@ -980,7 +1061,8 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
              cand = add_template_candidate (&candidates,
                                             f, s,
                                             NULL_TREE,
-                                            arglist,
+                                            first_arg,
+                                            NULL,
                                             reference_type,
                                             TYPE_BINFO (s),
                                             TREE_PURPOSE (conversions),
@@ -1005,8 +1087,8 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
            }
          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),
+           cand = add_function_candidate (&candidates, f, s, first_arg,
+                                          NULL, TYPE_BINFO (s),
                                           TREE_PURPOSE (conversions),
                                           LOOKUP_NORMAL);
 
@@ -1027,9 +1109,13 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
                = 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;
            }
        }
-      conversions = TREE_CHAIN (conversions);
     }
 
   candidates = splice_viable (candidates, pedantic, &any_viable_p);
@@ -1044,9 +1130,9 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
 
   /* 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.  */
@@ -1055,13 +1141,13 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
                     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;
 }
 
@@ -1120,9 +1206,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   conversion *conv = NULL;
   tree to = TREE_TYPE (rto);
   tree from = rfrom;
+  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))
     {
@@ -1135,33 +1222,53 @@ 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 ("extended 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;
+         from = TREE_TYPE (expr);
+       }
+    }
+
+  if (is_lvalue == clk_none && expr)
+    is_lvalue = real_lvalue_p (expr);
+
+  tfrom = from;
+  if ((is_lvalue & clk_bitfield) != 0)
+    tfrom = unlowered_expr_type (expr);
 
   /* Figure out whether or not the types are reference-related and
      reference compatible.  We have do do this after stripping
      references from FROM.  */
-  related_p = reference_related_p (to, from);
+  related_p = reference_related_p (to, tfrom);
   /* If this is a C cast, first convert to an appropriately qualified
      type, so that we can later do a const_cast to the desired type.  */
   if (related_p && c_cast_p
-      && !at_least_as_qualified_p (to, from))
-    to = build_qualified_type (to, cp_type_quals (from));
-  compatible_p = reference_compatible_p (to, from);
+      && !at_least_as_qualified_p (to, tfrom))
+    to = build_qualified_type (to, cp_type_quals (tfrom));
+  compatible_p = reference_compatible_p (to, tfrom);
 
   /* Directly bind reference when target expression's type is compatible with
-     the reference and expression is an lvalue. In C++0x, the wording in
-     [8.5.3/5 dcl.init.ref] is changed to also allow direct bindings for const
-     and rvalue references to rvalues of compatible class type, as part of
-     DR391. */
+     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.
+     We should also do direct bindings for non-class "rvalues" derived from
+     rvalue references.  */
   if (compatible_p
-      && (lvalue_p
-         || ((cxx_dialect != cxx98)
-             && (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]
 
@@ -1171,8 +1278,15 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
            is reference-compatible with "cv2 T2,"
 
         the reference is bound directly to the initializer expression
-        lvalue.  */
-      conv = build_identity_conv (from, expr);
+        lvalue.
+
+        [...]
+        If the initializer expression is an rvalue, with T2 a class type,
+        and "cv1 T1" is reference-compatible with "cv2 T2", the reference
+        is bound to the object represented by the rvalue or to a sub-object
+        within that object.  */
+
+      conv = build_identity_conv (tfrom, expr);
       conv = direct_reference_binding (rto, conv);
 
       if (flags & LOOKUP_PREFER_RVALUE)
@@ -1181,10 +1295,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
@@ -1198,9 +1312,19 @@ 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;
     }
-  else if (CLASS_TYPE_P (from) && !(flags & LOOKUP_NO_CONVERSION))
+  /* [class.conv.fct] A conversion function is never used to convert a
+     (possibly cv-qualified) object to the (possibly cv-qualified) same
+     object type (or a reference to it), to a (possibly cv-qualified) base
+     class of that type (or a reference to it).... */
+  else if (CLASS_TYPE_P (from) && !related_p
+          && !(flags & LOOKUP_NO_CONVERSION))
     {
       /* [dcl.init.ref]
 
@@ -1215,7 +1339,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
 
        the reference is bound to the lvalue result of the conversion
        in the second case.  */
-      conv = convert_class_to_reference (rto, from, expr);
+      conv = convert_class_to_reference (rto, from, expr, flags);
       if (conv)
        return conv;
     }
@@ -1246,32 +1370,6 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
 
   /* [dcl.init.ref]
 
-     If the initializer expression is an rvalue, with T2 a class type,
-     and "cv1 T1" is reference-compatible with "cv2 T2", the reference
-     is bound in one of the following ways:
-
-     -- The reference is bound to the object represented by the rvalue
-       or to a sub-object within that object.
-
-     -- ...
-
-     We use the first alternative.  The implicit conversion sequence
-     is supposed to be same as we would obtain by generating a
-     temporary.  Fortunately, if the types are reference compatible,
-     then this is either an identity conversion or the derived-to-base
-     conversion, just as for direct binding.  */
-  if (CLASS_TYPE_P (from) && compatible_p)
-    {
-      conv = build_identity_conv (from, expr);
-      conv = direct_reference_binding (rto, conv);
-      conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
-      if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE))
-       conv->u.next->check_copy_constructor_p = true;
-      return conv;
-    }
-
-  /* [dcl.init.ref]
-
      Otherwise, a temporary of type "cv1 T1" is created and
      initialized from the initializer expression using the rules for a
      non-reference copy initialization.  If T1 is reference-related to
@@ -1280,8 +1378,20 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   if (related_p && !at_least_as_qualified_p (to, from))
     return NULL;
 
-  conv = implicit_conversion (to, from, expr, c_cast_p,
-                             flags);
+  /* We're generating a temporary now, but don't bind any more in the
+     conversion (specifically, don't slice the temporary returned by a
+     conversion operator).  */
+  flags |= LOOKUP_NO_TEMP_BIND;
+
+  /* Temporaries are copy-initialized, except for this hack to allow
+     explicit conversion ops to the copy ctor.  See also
+     add_function_candidate.  */
+  if (!(flags & LOOKUP_COPY_PARM))
+    flags |= LOOKUP_ONLYCONVERTING;
+
+  if (!conv)
+    conv = implicit_conversion (to, from, expr, c_cast_p,
+                               flags);
   if (!conv)
     return NULL;
 
@@ -1296,9 +1406,8 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
 
 /* Returns the implicit conversion sequence (see [over.ics]) from type
    FROM to type TO.  The optional expression EXPR may affect the
-   conversion.  FLAGS are the usual overloading flags.  Only
-   LOOKUP_NO_CONVERSION is significant.  If C_CAST_P is true, this
-   conversion is coming from a C-style cast.  */
+   conversion.  FLAGS are the usual overloading flags.  If C_CAST_P is
+   true, this conversion is coming from a C-style cast.  */
 
 static conversion *
 implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
@@ -1318,15 +1427,52 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
   if (conv)
     return conv;
 
+  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
-      && (IS_AGGR_TYPE (from)
-         || IS_AGGR_TYPE (to))
+      && (MAYBE_CLASS_TYPE_P (from)
+         || MAYBE_CLASS_TYPE_P (to))
       && (flags & LOOKUP_NO_CONVERSION) == 0)
     {
       struct z_candidate *cand;
+      int convflags = (flags & (LOOKUP_NO_TEMP_BIND|LOOKUP_ONLYCONVERTING));
 
-      cand = build_user_type_conversion_1
-       (to, expr, LOOKUP_ONLYCONVERTING);
+      if (CLASS_TYPE_P (to)
+         && !CLASSTYPE_NON_AGGREGATE (complete_type (to))
+         && BRACE_ENCLOSED_INITIALIZER_P (expr))
+       return build_aggr_conv (to, expr, flags);
+
+      cand = build_user_type_conversion_1 (to, expr, convflags);
       if (cand)
        conv = cand->second_conv;
 
@@ -1340,11 +1486,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)
@@ -1353,6 +1500,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;
@@ -1365,24 +1513,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
@@ -1395,13 +1546,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]
@@ -1434,24 +1589,30 @@ 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));
 
       if (parmnode)
        {
          tree parmtype = TREE_VALUE (parmnode);
+         int lflags = flags;
 
          /* The type of the implicit object parameter ('this') for
             overload resolution is not always the same as for the
@@ -1470,8 +1631,20 @@ add_function_candidate (struct z_candidate **candidates,
              parmtype = build_pointer_type (parmtype);
            }
 
+         if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn))
+           {
+             /* Hack: Direct-initialize copy parm (i.e. suppress
+                LOOKUP_ONLYCONVERTING) to make explicit conversion ops
+                work.  See also reference_binding.  */
+             lflags |= LOOKUP_COPY_PARM;
+             if (flags & LOOKUP_NO_COPY_CTOR_CONVERSION)
+               lflags |= LOOKUP_NO_CONVERSION;
+           }
+         else
+           lflags |= LOOKUP_ONLYCONVERTING;
+
          t = implicit_conversion (parmtype, argtype, arg,
-                                  /*c_cast_p=*/false, flags);
+                                  /*c_cast_p=*/false, lflags);
        }
       else
        {
@@ -1494,18 +1667,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
@@ -1515,23 +1688,23 @@ 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_NORMAL;
+  flags = LOOKUP_IMPLICIT;
 
   /* Don't bother looking up the same type twice.  */
   if (*candidates && (*candidates)->fn == totype)
@@ -1539,11 +1712,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)
@@ -1569,7 +1750,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)
@@ -1578,7 +1758,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);
 }
 
@@ -1598,6 +1778,7 @@ 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;
 
   for (i = 0; i < 2; ++i)
     {
@@ -1630,7 +1811,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,
@@ -1655,7 +1836,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);
 }
@@ -1757,7 +1938,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;
 
@@ -1775,7 +1956,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
          tree c1 = TREE_TYPE (type1);
          tree c2 = TYPE_PTRMEM_CLASS_TYPE (type2);
 
-         if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1)
+         if (MAYBE_CLASS_TYPE_P (c1) && DERIVED_FROM_P (c2, c1)
              && (TYPE_PTRMEMFUNC_P (type2)
                  || is_complete (TYPE_PTRMEM_POINTED_TO_TYPE (type2))))
            break;
@@ -1827,7 +2008,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;
@@ -1887,12 +2069,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;
@@ -1916,7 +2098,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;
 
@@ -1961,7 +2143,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;
@@ -1978,7 +2160,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;
 
@@ -2046,7 +2228,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
          || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
          || (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2))
          || TYPE_PTRMEMFUNC_P (type1)
-         || IS_AGGR_TYPE (type1)
+         || MAYBE_CLASS_TYPE_P (type1)
          || TREE_CODE (type1) == ENUMERAL_TYPE))
     {
       build_builtin_candidate
@@ -2100,7 +2282,7 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
   for (i = 0; i < 3; ++i)
     {
       if (args[i])
-       argtypes[i]  = lvalue_type (args[i]);
+       argtypes[i] = unlowered_expr_type (args[i]);
       else
        argtypes[i] = NULL_TREE;
     }
@@ -2163,7 +2345,7 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
     {
       if (! args[i])
        ;
-      else if (IS_AGGR_TYPE (argtypes[i]))
+      else if (MAYBE_CLASS_TYPE_P (argtypes[i]))
        {
          tree convs;
 
@@ -2187,7 +2369,7 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
 
          for (; convs; convs = TREE_CHAIN (convs))
            {
-             type = TREE_TYPE (TREE_TYPE (OVL_CURRENT (TREE_VALUE (convs))));
+             type = TREE_TYPE (convs);
 
              if (i == 0 && ref1
                  && (TREE_CODE (type) != REFERENCE_TYPE
@@ -2203,7 +2385,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);
                }
 
@@ -2220,9 +2402,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]);
@@ -2251,37 +2433,79 @@ 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 nargs;
+  int skip_without_in_chrg;
+  tree first_arg_without_in_chrg;
+  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;
 
+  nargs = (first_arg == NULL_TREE ? 0 : 1) + VEC_length (tree, arglist);
+
+  skip_without_in_chrg = 0;
+
+  first_arg_without_in_chrg = first_arg;
+
   /* 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;
+    }
+
+  nargs_without_in_chrg = ((first_arg_without_in_chrg != NULL_TREE ? 1 : 0)
+                          + (VEC_length (tree, arglist)
+                             - 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)
@@ -2313,7 +2537,7 @@ 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)),
@@ -2323,11 +2547,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
 
   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
@@ -2357,26 +2581,29 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
 
 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);
 }
 
@@ -2439,7 +2666,7 @@ build_this (tree obj)
   if (processing_template_decl)
     return build_address (obj);
 
-  return build_unary_op (ADDR_EXPR, obj, 0);
+  return cp_build_unary_op (ADDR_EXPR, obj, 0, tf_warning_or_error);
 }
 
 /* Returns true iff functions are equivalent. Equivalent functions are
@@ -2468,24 +2695,24 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
   if (TREE_CODE (candidate->fn) == IDENTIFIER_NODE)
     {
       if (candidate->num_convs == 3)
-       inform ("%s %D(%T, %T, %T) <built-in>", msgstr, candidate->fn,
+       inform (input_location, "%s %D(%T, %T, %T) <built-in>", msgstr, candidate->fn,
                candidate->convs[0]->type,
                candidate->convs[1]->type,
                candidate->convs[2]->type);
       else if (candidate->num_convs == 2)
-       inform ("%s %D(%T, %T) <built-in>", msgstr, candidate->fn,
+       inform (input_location, "%s %D(%T, %T) <built-in>", msgstr, candidate->fn,
                candidate->convs[0]->type,
                candidate->convs[1]->type);
       else
-       inform ("%s %D(%T) <built-in>", msgstr, candidate->fn,
+       inform (input_location, "%s %D(%T) <built-in>", msgstr, candidate->fn,
                candidate->convs[0]->type);
     }
   else if (TYPE_P (candidate->fn))
-    inform ("%s %T <conversion>", msgstr, candidate->fn);
+    inform (input_location, "%s %T <conversion>", msgstr, candidate->fn);
   else if (candidate->viable == -1)
-    inform ("%s %+#D <near match>", msgstr, candidate->fn);
+    inform (input_location, "%s %+#D <near match>", msgstr, candidate->fn);
   else
-    inform ("%s %+#D", msgstr, candidate->fn);
+    inform (input_location, "%s %+#D", msgstr, candidate->fn);
 }
 
 static void
@@ -2583,69 +2810,114 @@ 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;
 
   /* We represent conversion within a hierarchy using RVALUE_CONV and
      BASE_CONV, as specified by [over.best.ics]; these become plain
      constructor calls, as specified in [dcl.init].  */
-  gcc_assert (!IS_AGGR_TYPE (fromtype) || !IS_AGGR_TYPE (totype)
+  gcc_assert (!MAYBE_CLASS_TYPE_P (fromtype) || !MAYBE_CLASS_TYPE_P (totype)
              || !DERIVED_FROM_P (totype, fromtype));
 
-  if (IS_AGGR_TYPE (totype))
+  if (MAYBE_CLASS_TYPE_P (totype))
     ctors = lookup_fnfields (totype, complete_ctor_identifier, 0);
 
-  if (IS_AGGR_TYPE (fromtype))
-    conv_fns = lookup_conversions (fromtype);
+  if (MAYBE_CLASS_TYPE_P (fromtype))
+    {
+      tree to_nonref = non_reference (totype);
+      if (same_type_ignoring_top_level_qualifiers_p (to_nonref, fromtype) ||
+         (CLASS_TYPE_P (to_nonref) && CLASS_TYPE_P (fromtype)
+          && DERIVED_FROM_P (to_nonref, fromtype)))
+       {
+         /* [class.conv.fct] A conversion function is never used to
+            convert a (possibly cv-qualified) object to the (possibly
+            cv-qualified) same object type (or a reference to it), to a
+            (possibly cv-qualified) base class of that type (or a
+            reference to it)...  */
+       }
+      else
+       conv_fns = lookup_conversions (fromtype);
+    }
 
   candidates = 0;
   flags |= LOOKUP_NO_CONVERSION;
 
+  /* It's OK to bind a temporary for converting constructor arguments, but
+     not in converting the return value of a conversion operator.  */
+  convflags = ((flags & LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION);
+  flags &= ~LOOKUP_NO_TEMP_BIND;
+
   if (ctors)
     {
-      tree t;
-
       ctors = BASELINK_FUNCTIONS (ctors);
 
-      t = build_int_cst (build_pointer_type (totype), 0);
-      args = build_tree_list (NULL_TREE, expr);
+      first_arg = build_int_cst (build_pointer_type (totype), 0);
+      if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+         && !TYPE_HAS_LIST_CTOR (totype))
+       {
+         args = ctor_to_vec (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);
+       }
+      else
+       args = make_tree_vector_single (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))
+      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,
+                                      NULL_TREE, first_arg, args, NULL_TREE,
                                       TYPE_BINFO (totype),
                                       TYPE_BINFO (totype),
                                       flags,
                                       DEDUCE_CALL);
       else
        cand = add_function_candidate (&candidates, ctor, totype,
-                                      args, TYPE_BINFO (totype),
+                                      first_arg, args, TYPE_BINFO (totype),
                                       TYPE_BINFO (totype),
                                       flags);
 
       if (cand)
-       cand->second_conv = build_identity_conv (totype, NULL_TREE);
+       {
+         cand->second_conv = build_identity_conv (totype, NULL_TREE);
+
+         /* If totype isn't a reference, and 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.  */
+         if (TREE_CODE (totype) != REFERENCE_TYPE
+             && !(convflags & LOOKUP_NO_TEMP_BIND))
+           cand->second_conv
+             = build_conv (ck_rvalue, totype, cand->second_conv);
+       }
     }
 
   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);
-      int convflags = LOOKUP_NO_CONVERSION;
 
       /* 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
@@ -2658,6 +2930,10 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
        {
          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
@@ -2668,14 +2944,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            cand = add_template_candidate (&candidates, fn, fromtype,
                                           NULL_TREE,
-                                          args, totype,
+                                          first_arg, NULL, totype,
                                           TYPE_BINFO (fromtype),
                                           conversion_path,
                                           flags,
                                           DEDUCE_CONV);
          else
            cand = add_function_candidate (&candidates, fn, fromtype,
-                                          args,
+                                          first_arg, NULL,
                                           TYPE_BINFO (fromtype),
                                           conversion_path,
                                           flags);
@@ -2688,6 +2964,20 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
                                       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)
@@ -2732,6 +3022,10 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
      build_identity_conv (TREE_TYPE (expr), expr));
   conv->cand = cand;
 
+  /* Remember that this was a list-initialization.  */
+  if (flags & LOOKUP_NO_NARROWING)
+    conv->check_narrowing = true;
+
   /* Combine it with the second conversion sequence.  */
   cand->second_conv = merge_conversion_sequences (conv,
                                                  cand->second_conv);
@@ -2752,7 +3046,7 @@ build_user_type_conversion (tree totype, tree expr, int flags)
     {
       if (cand->second_conv->kind == ck_ambig)
        return error_mark_node;
-      expr = convert_like (cand->second_conv, expr);
+      expr = convert_like (cand->second_conv, expr, tf_warning_or_error);
       return convert_from_reference (expr);
     }
   return NULL_TREE;
@@ -2760,23 +3054,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))
-       return error_mark_node;
+      else if (invalid_nonstatic_memfn_p (arg, tf_warning_or_error))
+       return NULL;
     }
   return args;
 }
@@ -2795,7 +3089,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)
 {
@@ -2806,12 +3100,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)
     {
@@ -2836,19 +3129,24 @@ 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;
   bool any_viable_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
@@ -2860,8 +3158,10 @@ build_new_function_call (tree fn, tree args, bool koenig_p)
       fn = remove_hidden_names (fn);
       if (!fn)
        {
-         error ("no matching function for call to %<%D(%A)%>",
-                DECL_NAME (OVL_CURRENT (orig_fn)), args);
+         if (complain & tf_error)
+           error ("no matching function for call to %<%D(%A)%>",
+                  DECL_NAME (OVL_CURRENT (orig_fn)),
+                  build_tree_list_vec (*args));
          return error_mark_node;
        }
     }
@@ -2869,26 +3169,29 @@ 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 (!any_viable_p && candidates && ! candidates->next)
-       return build_function_call (candidates->fn, args);
-      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);
-      else
-       error ("call of overloaded %<%D(%A)%> is ambiguous",
-              DECL_NAME (OVL_CURRENT (fn)), args);
-      if (candidates)
-       print_z_candidates (candidates);
+      if (complain & tf_error)
+       {
+         if (!any_viable_p && candidates && ! candidates->next)
+           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)), build_tree_list_vec (*args));
+         else
+           error ("call of overloaded %<%D(%A)%> is ambiguous",
+                  DECL_NAME (OVL_CURRENT (fn)), build_tree_list_vec (*args));
+         if (candidates)
+           print_z_candidates (candidates);
+       }
       result = error_mark_node;
     }
   else
-    result = build_over_call (cand, LOOKUP_NORMAL);
+    result = build_over_call (cand, LOOKUP_NORMAL, complain);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -2898,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)
 {
@@ -2917,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:
 
@@ -2931,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.  */
@@ -2942,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;
@@ -2959,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;
         }
@@ -2988,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;
@@ -2999,24 +3302,32 @@ build_operator_new_call (tree fnname, tree args,
      *fn = cand->fn;
 
    /* Build the CALL_EXPR.  */
-   return build_over_call (cand, LOOKUP_NORMAL);
+   return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
 }
 
-static tree
-build_object_call (tree obj, tree args)
+/* 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))
     {
-      /* It's no good looking for an overloaded operator() on a
-        pointer-to-member-function.  */
-      error ("pointer-to-member function %E cannot be called without an object; consider using .* or ->*", obj);
+      if (complain & tf_error)
+        /* It's no good looking for an overloaded operator() on a
+           pointer-to-member-function.  */
+        error ("pointer-to-member function %E cannot be called without an object; consider using .* or ->*", obj);
       return error_mark_node;
     }
 
@@ -3029,10 +3340,12 @@ build_object_call (tree obj, tree args)
   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);
@@ -3040,20 +3353,20 @@ build_object_call (tree obj, tree args)
   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,
+                                   first_mem_arg, *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),
+             (&candidates, fn, base, first_mem_arg, *args, TYPE_BINFO (type),
               TYPE_BINFO (type), LOOKUP_NORMAL);
        }
     }
@@ -3063,7 +3376,7 @@ build_object_call (tree obj, tree args)
   for (; convs; convs = TREE_CHAIN (convs))
     {
       tree fns = TREE_VALUE (convs);
-      tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns)));
+      tree totype = TREE_TYPE (convs);
 
       if ((TREE_CODE (totype) == POINTER_TYPE
           && TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
@@ -3075,14 +3388,18 @@ build_object_call (tree obj, tree args)
        for (; fns; fns = OVL_NEXT (fns))
          {
            tree fn = OVL_CURRENT (fns);
+
+           if (DECL_NONCONVERTING_P (fn))
+             continue;
+
            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);
          }
     }
@@ -3090,8 +3407,12 @@ build_object_call (tree obj, tree args)
   candidates = splice_viable (candidates, pedantic, &any_viable_p);
   if (!any_viable_p)
     {
-      error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args);
-      print_z_candidates (candidates);
+      if (complain & tf_error)
+        {
+          error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj),
+                build_tree_list_vec (*args));
+          print_z_candidates (candidates);
+        }
       result = error_mark_node;
     }
   else
@@ -3099,8 +3420,12 @@ build_object_call (tree obj, tree args)
       cand = tourney (candidates);
       if (cand == 0)
        {
-         error ("call of %<(%T) (%A)%> is ambiguous", TREE_TYPE (obj), args);
-         print_z_candidates (candidates);
+          if (complain & tf_error)
+            {
+              error ("call of %<(%T) (%A)%> is ambiguous", 
+                     TREE_TYPE (obj), build_tree_list_vec (*args));
+              print_z_candidates (candidates);
+            }
          result = error_mark_node;
        }
       /* Since cand->fn will be a type, not a function, for a conversion
@@ -3108,12 +3433,13 @@ build_object_call (tree obj, tree args)
         DECL_NAME here.  */
       else if (TREE_CODE (cand->fn) == FUNCTION_DECL
               && DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR)
-       result = build_over_call (cand, LOOKUP_NORMAL);
+       result = build_over_call (cand, LOOKUP_NORMAL, complain);
       else
        {
-         obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1);
+         obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1,
+                                          complain);
          obj = convert_from_reference (obj);
-         result = build_function_call (obj, args);
+         result = cp_build_function_call_vec (obj, args, complain);
        }
     }
 
@@ -3189,7 +3515,7 @@ conditional_conversion (tree e1, tree e2)
                                  t1,
                                  e1,
                                  /*c_cast_p=*/false,
-                                 LOOKUP_NO_TEMP_BIND);
+                                 LOOKUP_NO_TEMP_BIND|LOOKUP_ONLYCONVERTING);
       if (conv)
        return conv;
     }
@@ -3227,14 +3553,15 @@ conditional_conversion (tree e1, tree e2)
        converted to the type that expression E2 would have if E2 were
        converted to an rvalue (or the type it has, if E2 is an rvalue).  */
     return implicit_conversion (t2, t1, e1, /*c_cast_p=*/false,
-                               LOOKUP_NORMAL);
+                               LOOKUP_IMPLICIT);
 }
 
 /* Implement [expr.cond].  ARG1, ARG2, and ARG3 are the three
    arguments to the conditional expression.  */
 
 tree
-build_conditional_expr (tree arg1, tree arg2, tree arg3)
+build_conditional_expr (tree arg1, tree arg2, tree arg3,
+                        tsubst_flags_t complain)
 {
   tree arg2_type;
   tree arg3_type;
@@ -3251,8 +3578,9 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
      calculated only once.  */
   if (!arg2)
     {
-      if (pedantic)
-       pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
+      if (complain & tf_error)
+       pedwarn (input_location, OPT_pedantic, 
+                "ISO C++ forbids omitting the middle term of a ?: expression");
 
       /* Make sure that lvalues remain lvalues.  See g++.oliva/ext1.C.  */
       if (real_lvalue_p (arg1))
@@ -3263,9 +3591,9 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
 
   /* [expr.cond]
 
-     The first expr ession is implicitly converted to bool (clause
+     The first expression is implicitly converted to bool (clause
      _conv_).  */
-  arg1 = perform_implicit_conversion (boolean_type_node, arg1);
+  arg1 = perform_implicit_conversion (boolean_type_node, arg1, complain);
 
   /* If something has already gone wrong, just pass that fact up the
      tree.  */
@@ -3329,16 +3657,19 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
        result_type = void_type_node;
       else
        {
-         if (VOID_TYPE_P (arg2_type))
-            error ("second operand to the conditional operator "
-                   "is of type %<void%>, "
-                   "but the third operand is neither a throw-expression "
-                   "nor of type %<void%>");
-         else
-           error ("third operand to the conditional operator "
-                   "is of type %<void%>, "
-                  "but the second operand is neither a throw-expression "
-                   "nor of type %<void%>");
+          if (complain & tf_error)
+            {
+              if (VOID_TYPE_P (arg2_type))
+                error ("second operand to the conditional operator "
+                       "is of type %<void%>, "
+                       "but the third operand is neither a throw-expression "
+                       "nor of type %<void%>");
+              else
+                error ("third operand to the conditional operator "
+                       "is of type %<void%>, "
+                       "but the second operand is neither a throw-expression "
+                       "nor of type %<void%>");
+            }
          return error_mark_node;
        }
 
@@ -3382,7 +3713,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
        }
       else if (conv2 && (!conv2->bad_p || !conv3))
        {
-         arg2 = convert_like (conv2, arg2);
+         arg2 = convert_like (conv2, arg2, complain);
          arg2 = convert_from_reference (arg2);
          arg2_type = TREE_TYPE (arg2);
          /* Even if CONV2 is a valid conversion, the result of the
@@ -3395,7 +3726,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
        }
       else if (conv3 && (!conv3->bad_p || !conv2))
        {
-         arg3 = convert_like (conv3, arg3);
+         arg3 = convert_like (conv3, arg3, complain);
          arg3 = convert_from_reference (arg3);
          arg3_type = TREE_TYPE (arg3);
          if (error_operand_p (arg3))
@@ -3479,15 +3810,21 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
       candidates = splice_viable (candidates, pedantic, &any_viable_p);
       if (!any_viable_p)
        {
-         op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
-         print_z_candidates (candidates);
+          if (complain & tf_error)
+            {
+              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
+              print_z_candidates (candidates);
+            }
          return error_mark_node;
        }
       cand = tourney (candidates);
       if (!cand)
        {
-         op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
-         print_z_candidates (candidates);
+          if (complain & tf_error)
+            {
+              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
+              print_z_candidates (candidates);
+            }
          return error_mark_node;
        }
 
@@ -3497,11 +3834,11 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
         the converted operands are used in place of the original
         operands for the remainder of this section.  */
       conv = cand->convs[0];
-      arg1 = convert_like (conv, arg1);
+      arg1 = convert_like (conv, arg1, complain);
       conv = cand->convs[1];
-      arg2 = convert_like (conv, arg2);
+      arg2 = convert_like (conv, arg2, complain);
       conv = cand->convs[2];
-      arg3 = convert_like (conv, arg3);
+      arg3 = convert_like (conv, arg3, complain);
     }
 
   /* [expr.cond]
@@ -3540,9 +3877,9 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
        type; the usual arithmetic conversions are performed to bring
        them to a common type, and the result is of that type.  */
   else if ((ARITHMETIC_TYPE_P (arg2_type)
-           || TREE_CODE (arg2_type) == ENUMERAL_TYPE)
+           || UNSCOPED_ENUM_P (arg2_type))
           && (ARITHMETIC_TYPE_P (arg3_type)
-              || TREE_CODE (arg3_type) == ENUMERAL_TYPE))
+              || UNSCOPED_ENUM_P (arg3_type)))
     {
       /* In this case, there is always a common type.  */
       result_type = type_after_usual_arithmetic_conversions (arg2_type,
@@ -3550,17 +3887,25 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
 
       if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
          && TREE_CODE (arg3_type) == ENUMERAL_TYPE)
-        warning (0, "enumeral mismatch in conditional expression: %qT vs %qT",
-                  arg2_type, arg3_type);
+        {
+          if (complain & tf_warning)
+            warning (0, 
+                     "enumeral mismatch in conditional expression: %qT vs %qT",
+                     arg2_type, arg3_type);
+        }
       else if (extra_warnings
               && ((TREE_CODE (arg2_type) == ENUMERAL_TYPE
                    && !same_type_p (arg3_type, type_promotes_to (arg2_type)))
                   || (TREE_CODE (arg3_type) == ENUMERAL_TYPE
                       && !same_type_p (arg2_type, type_promotes_to (arg3_type)))))
-       warning (0, "enumeral and non-enumeral type in conditional expression");
+        {
+          if (complain & tf_warning)
+            warning (0, 
+                     "enumeral and non-enumeral type in conditional expression");
+        }
 
-      arg2 = perform_implicit_conversion (result_type, arg2);
-      arg3 = perform_implicit_conversion (result_type, arg3);
+      arg2 = perform_implicit_conversion (result_type, arg2, complain);
+      arg3 = perform_implicit_conversion (result_type, arg3, complain);
     }
   /* [expr.cond]
 
@@ -3587,17 +3932,19 @@ 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, "conditional expression",
+                                           complain);
       if (result_type == error_mark_node)
        return error_mark_node;
-      arg2 = perform_implicit_conversion (result_type, arg2);
-      arg3 = perform_implicit_conversion (result_type, arg3);
+      arg2 = perform_implicit_conversion (result_type, arg2, complain);
+      arg3 = perform_implicit_conversion (result_type, arg3, complain);
     }
 
   if (!result_type)
     {
-      error ("operands to ?: have different types %qT and %qT",
-            arg2_type, arg3_type);
+      if (complain & tf_error)
+        error ("operands to ?: have different types %qT and %qT",
+               arg2_type, arg3_type);
       return error_mark_node;
     }
 
@@ -3644,29 +3991,33 @@ 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.  */
+   without any implicit object parameter.  This may change ARGS.  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, const VEC(tree,gc) *args,
                tree explicit_targs, bool template_only,
                tree conversion_path, tree access_path,
                int flags,
                struct z_candidate **candidates)
 {
   tree ctype;
-  tree non_static_args;
+  VEC(tree,gc) *non_static_args;
+  tree first_arg;
 
   ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
   /* Delay creating the implicit this parameter until it is needed.  */
-  non_static_args = NULL_TREE;
+  non_static_args = NULL;
+  first_arg = NULL_TREE;
 
   while (fns)
     {
       tree fn;
-      tree fn_args;
+      tree fn_first_arg;
+      const VEC(tree,gc) *fn_args;
 
       fn = OVL_CURRENT (fns);
       /* Figure out which set of arguments to use.  */
@@ -3674,21 +4025,34 @@ add_candidates (tree fns, tree args,
        {
          /* 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 (non_static_args == NULL)
+           {
+             unsigned int ix;
+             tree arg;
+
+             non_static_args = VEC_alloc (tree, gc,
+                                          VEC_length (tree, args) - 1);
+             for (ix = 1; VEC_iterate (tree, args, ix, arg); ++ix)
+               VEC_quick_push (tree, non_static_args, arg);
+           }
+         if (first_arg == NULL_TREE)
+           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,
                                access_path,
@@ -3699,6 +4063,7 @@ add_candidates (tree fns, tree args,
        add_function_candidate (candidates,
                                fn,
                                ctype,
+                               fn_first_arg,
                                fn_args,
                                access_path,
                                conversion_path,
@@ -3707,21 +4072,45 @@ add_candidates (tree fns, tree args,
     }
 }
 
+/* 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)
+             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;
   enum tree_code code2 = NOP_EXPR;
+  enum tree_code code_orig_arg1 = ERROR_MARK;
+  enum tree_code code_orig_arg2 = ERROR_MARK;
   conversion *conv;
   void *p;
   bool strict_p;
   bool any_viable_p;
-  bool expl_eq_arg1 = false;
 
   if (error_operand_p (arg1)
       || error_operand_p (arg2)
@@ -3749,14 +4138,17 @@ 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);
+      /* Use build_op_call instead.  */
+      gcc_unreachable ();
 
     case TRUTH_ORIF_EXPR:
     case TRUTH_ANDIF_EXPR:
     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
-      if (COMPARISON_CLASS_P (arg1))
-       expl_eq_arg1 = true;
+      /* These are saved for the sake of warn_logical_operator.  */
+      code_orig_arg1 = TREE_CODE (arg1);
+      code_orig_arg2 = TREE_CODE (arg2);
+
     default:
       break;
     }
@@ -3780,12 +4172,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);
@@ -3858,19 +4250,34 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
        {
        case POSTINCREMENT_EXPR:
        case POSTDECREMENT_EXPR:
-         /* Look for an `operator++ (int)'.  If they didn't have
-            one, then we fall back to the old way of doing things.  */
+         /* Don't try anything fancy if we're not allowed to produce
+            errors.  */
+         if (!(complain & tf_error))
+           return error_mark_node;
+
+         /* 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)
-           pedwarn ("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
            code = PREDECREMENT_EXPR;
          result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE,
-                                overloaded_p);
+                                overloaded_p, complain);
          break;
 
          /* The caller will deal with these.  */
@@ -3882,10 +4289,22 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          break;
 
        default:
-         if (flags & LOOKUP_COMPLAIN)
+         if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
            {
-             op_error (code, code2, arg1, arg2, arg3, "no match");
-             print_z_candidates (candidates);
+               /* If one of the arguments of the operator represents
+                  an invalid use of member function pointer, try to report
+                  a meaningful error ...  */
+               if (invalid_nonstatic_memfn_p (arg1, tf_error)
+                   || invalid_nonstatic_memfn_p (arg2, tf_error)
+                   || invalid_nonstatic_memfn_p (arg3, tf_error))
+                 /* We displayed the error message.  */;
+               else
+                 {
+                   /* ... Otherwise, report the more generic
+                      "no matching operator found" error */
+                   op_error (code, code2, arg1, arg2, arg3, "no match");
+                   print_z_candidates (candidates);
+                 }
            }
          result = error_mark_node;
          break;
@@ -3896,7 +4315,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       cand = tourney (candidates);
       if (cand == 0)
        {
-         if (flags & LOOKUP_COMPLAIN)
+         if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
            {
              op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
              print_z_candidates (candidates);
@@ -3908,12 +4327,15 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          if (overloaded_p)
            *overloaded_p = true;
 
-         result = build_over_call (cand, LOOKUP_NORMAL);
+         if (resolve_args (arglist) == NULL)
+           result = error_mark_node;
+         else
+           result = build_over_call (cand, LOOKUP_NORMAL, complain);
        }
       else
        {
          /* Give any warnings we noticed during overload resolution.  */
-         if (cand->warnings)
+         if (cand->warnings && (complain & tf_warning))
            {
              struct candidate_warning *w;
              for (w = cand->warnings; w; w = w->next)
@@ -3932,9 +4354,11 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
              if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE
                  && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE
                  && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1))
-                     != TYPE_MAIN_VARIANT (TREE_TYPE (arg2))))
+                     != TYPE_MAIN_VARIANT (TREE_TYPE (arg2)))
+                 && (complain & tf_warning))
                {
-                 warning (0, "comparison between %q#T and %q#T",
+                 warning (OPT_Wenum_compare,
+                          "comparison between %q#T and %q#T",
                           TREE_TYPE (arg1), TREE_TYPE (arg2));
                }
              break;
@@ -3949,27 +4373,30 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          conv = cand->convs[0];
          if (conv->kind == ck_ref_bind)
            conv = conv->u.next;
-         arg1 = convert_like (conv, arg1);
+         arg1 = convert_like (conv, arg1, complain);
+
          if (arg2)
            {
+             /* We need to call warn_logical_operator before
+                converting arg2 to a boolean_type.  */
+             if (complain & tf_warning)
+               warn_logical_operator (input_location, code, boolean_type_node,
+                                      code_orig_arg1, arg1,
+                                      code_orig_arg2, arg2);
+
              conv = cand->convs[1];
              if (conv->kind == ck_ref_bind)
                conv = conv->u.next;
-             arg2 = convert_like (conv, arg2);
+             arg2 = convert_like (conv, arg2, complain);
            }
          if (arg3)
            {
              conv = cand->convs[2];
              if (conv->kind == ck_ref_bind)
                conv = conv->u.next;
-             arg3 = convert_like (conv, arg3);
+             arg3 = convert_like (conv, arg3, complain);
            }
 
-         if (!expl_eq_arg1) 
-           {
-             warn_logical_operator (code, arg1, arg2);
-             expl_eq_arg1 = true;
-           }
        }
     }
 
@@ -3982,20 +4409,25 @@ 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 build_modify_expr (arg1, code2, arg2);
+      return cp_build_modify_expr (arg1, code2, arg2, complain);
 
     case INDIRECT_REF:
-      return build_indirect_ref (arg1, "unary *");
+      return cp_build_indirect_ref (arg1, "unary *", complain);
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
-      if (!expl_eq_arg1)
-       warn_logical_operator (code, arg1, arg2);
+      warn_logical_operator (input_location, code, boolean_type_node,
+                            code_orig_arg1, arg1, code_orig_arg2, arg2);
+      /* Fall through.  */
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
@@ -4014,7 +4446,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
     case BIT_AND_EXPR:
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
-      return cp_build_binary_op (code, arg1, arg2);
+      return cp_build_binary_op (input_location, code, arg1, arg2, complain);
 
     case UNARY_PLUS_EXPR:
     case NEGATE_EXPR:
@@ -4026,16 +4458,18 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
     case POSTDECREMENT_EXPR:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      return build_unary_op (code, arg1, candidates != 0);
+      return cp_build_unary_op (code, arg1, candidates != 0, complain);
 
     case ARRAY_REF:
-      return build_array_ref (arg1, arg2);
+      return build_array_ref (input_location, arg1, arg2);
 
     case COND_EXPR:
-      return build_conditional_expr (arg1, arg2, arg3);
+      return build_conditional_expr (arg1, arg2, arg3, complain);
 
     case MEMBER_REF:
-      return build_m_component_ref (build_indirect_ref (arg1, NULL), arg2);
+      return build_m_component_ref (cp_build_indirect_ref (arg1, NULL, 
+                                                           complain), 
+                                    arg2);
 
       /* The caller will deal with these.  */
     case ADDR_EXPR:
@@ -4183,6 +4617,10 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
       if (DECL_CLASS_SCOPE_P (fn))
        perform_or_defer_access_check (TYPE_BINFO (type), 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)
        {
          /* The placement args might not be suitable for overload
@@ -4198,13 +4636,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 build_function_call (fn, args);
+         tree ret;
+         VEC(tree,gc) *args = VEC_alloc (tree, gc, 2);
+         VEC_quick_push (tree, args, addr);
+         if (pass != 0)
+           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;
        }
     }
 
@@ -4216,7 +4655,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
   if (alloc_fn)
     {
       if (!placement)
-       warning (0, "no corresponding deallocation function for `%D'", 
+       warning (0, "no corresponding deallocation function for %qD",
                 alloc_fn);
       return NULL_TREE;
     }
@@ -4251,21 +4690,6 @@ enforce_access (tree basetype_path, tree decl, tree diag_decl)
   return true;
 }
 
-/* Check that a callable constructor to initialize a temporary of
-   TYPE from an EXPR exists.  */
-
-static void
-check_constructor_callable (tree type, tree expr)
-{
-  build_special_member_call (NULL_TREE,
-                            complete_ctor_identifier,
-                            build_tree_list (NULL_TREE, expr),
-                            type,
-                            LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
-                            | LOOKUP_NO_CONVERSION
-                            | LOOKUP_CONSTRUCTOR_CALLABLE);
-}
-
 /* Initialize a temporary of type TYPE with EXPR.  The FLAGS are a
    bitwise or of LOOKUP_* values.  If any errors are warnings are
    generated, set *DIAGNOSTIC_FN to "error" or "warning",
@@ -4274,21 +4698,22 @@ check_constructor_callable (tree type, tree expr)
 
 static tree
 build_temp (tree expr, tree type, int flags,
-           diagnostic_fn_t *diagnostic_fn)
+           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);
+  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_fn = warning0;
+    *diagnostic_kind = DK_WARNING;
   else if (errorcount > savee)
-    *diagnostic_fn = error;
+    *diagnostic_kind = DK_ERROR;
   else
-    *diagnostic_fn = NULL;
+    *diagnostic_kind = DK_UNSPECIFIED;
   return expr;
 }
 
@@ -4331,40 +4756,60 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
 static tree
 convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
                   int inner, bool issue_conversion_warnings,
-                  bool c_cast_p)
+                  bool c_cast_p, tsubst_flags_t complain)
 {
   tree totype = convs->type;
-  diagnostic_fn_t diagnostic_fn;
+  diagnostic_t diag_kind;
+  int flags;
 
   if (convs->bad_p
       && convs->kind != ck_user
+      && convs->kind != ck_list
       && convs->kind != ck_ambig
-      && convs->kind != ck_ref_bind)
+      && 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)
            {
              expr = convert_like_real (t, expr, fn, argnum, 1,
                                        /*issue_conversion_warnings=*/false,
-                                       /*c_cast_p=*/false);
+                                       /*c_cast_p=*/false,
+                                       complain);
              break;
            }
          else if (t->kind == ck_ambig)
            return convert_like_real (t, expr, fn, argnum, 1,
                                      /*issue_conversion_warnings=*/false,
-                                     /*c_cast_p=*/false);
+                                     /*c_cast_p=*/false,
+                                     complain);
          else if (t->kind == ck_identity)
            break;
        }
-      pedwarn ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
-      if (fn)
-       pedwarn ("  initializing argument %P of %qD", argnum, fn);
+      if (complain & tf_error)
+       {
+         permerror (input_location, "invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
+         if (fn)
+           permerror (input_location, "  initializing argument %P of %qD", argnum, fn);
+       }
+      else
+       return error_mark_node;
+
       return cp_convert (totype, expr);
     }
 
-  if (issue_conversion_warnings)
+  if (issue_conversion_warnings && (complain & tf_warning))
     conversion_null_warnings (totype, expr, fn, argnum);
 
   switch (convs->kind)
@@ -4373,64 +4818,112 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       {
        struct z_candidate *cand = convs->cand;
        tree convfn = cand->fn;
+       unsigned i;
+
+       /* 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))
+         {
+           if (complain & tf_error)
+             error ("converting to %qT from initializer list would use "
+                    "explicit constructor %qD", totype, convfn);
+           else
+             return error_mark_node;
+         }
 
-       expr = build_over_call (cand, LOOKUP_NORMAL);
+       /* Set user_conv_p on the argument conversions, so rvalue/base
+          handling knows not to allow any more UDCs.  */
+       for (i = 0; i < cand->num_convs; ++i)
+         cand->convs[i]->user_conv_p = true;
+
+       expr = build_over_call (cand, LOOKUP_NORMAL, complain);
 
        /* If this is a constructor or a function returning an aggr type,
           we need to build up a TARGET_EXPR.  */
        if (DECL_CONSTRUCTOR_P (convfn))
-         expr = build_cplus_new (totype, expr);
-
-       /* The result of the call is then used to direct-initialize the object
-          that is the destination of the copy-initialization.  [dcl.init]
-
-          Note that this step is not reflected in the conversion sequence;
-          it affects the semantics when we actually perform the
-          conversion, but is not considered during overload resolution.
-
-          If the target is a class, that means call a ctor.  */
-       if (IS_AGGR_TYPE (totype)
-           && (inner >= 0 || !lvalue_p (expr)))
          {
-           expr = (build_temp
-                   (expr, totype,
-                    /* Core issue 84, now a DR, says that we don't
-                       allow UDCs for these args (which deliberately
-                       breaks copy-init of an auto_ptr<Base> from an
-                       auto_ptr<Derived>).  */
-                    LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION,
-                    &diagnostic_fn));
-
-           if (diagnostic_fn)
-             {
-               if (fn)
-                 diagnostic_fn
-                   ("  initializing argument %P of %qD from result of %qD",
-                    argnum, fn, convfn);
-               else
-                diagnostic_fn
-                  ("  initializing temporary from result of %qD",  convfn);
-             }
            expr = build_cplus_new (totype, expr);
+
+           /* Remember that this was list-initialization.  */
+           if (convs->check_narrowing)
+             TARGET_EXPR_LIST_INIT_P (expr) = true;
          }
+
        return expr;
       }
     case ck_identity:
+      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, tf_warning_or_error);
+       expr = instantiate_type (totype, expr, complain);
       /* Convert a constant to its underlying value, unless we are
         about to bind it to a reference, in which case we need to
         leave it as an lvalue.  */
       if (inner >= 0)
-       expr = decl_constant_value (expr);
-      if (convs->check_copy_constructor_p)
-       check_constructor_callable (totype, expr);
+        {   
+          expr = decl_constant_value (expr);
+          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.  */
+            expr = build_int_cst (totype, 0);
+        }
       return expr;
     case ck_ambig:
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
        (totype, convs->u.expr, LOOKUP_NORMAL);
 
+    case ck_list:
+      {
+       /* Conversion to std::initializer_list<T>.  */
+       tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
+       tree new_ctor = build_constructor (init_list_type_node, NULL);
+       unsigned len = CONSTRUCTOR_NELTS (expr);
+       tree array, val;
+       VEC(tree,gc) *parms;
+       unsigned ix;
+
+       /* Convert all the elements.  */
+       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val)
+         {
+           tree sub = convert_like_real (convs->u.list[ix], val, fn, argnum,
+                                         1, false, false, complain);
+           if (sub == error_mark_node)
+             return sub;
+           check_narrowing (TREE_TYPE (sub), val);
+           CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), NULL_TREE, sub);
+         }
+       /* Build up the array.  */
+       elttype = cp_build_qualified_type
+         (elttype, TYPE_QUALS (elttype) | TYPE_QUAL_CONST);
+       array = build_array_of_n_type (elttype, len);
+       array = finish_compound_literal (array, new_ctor);
+
+       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);
+       release_tree_vector (parms);
+       pop_deferring_access_checks ();
+       return build_cplus_new (totype, new_ctor);
+      }
+
+    case ck_aggr:
+      return get_target_expr (digest_init (totype, expr));
+
     default:
       break;
     };
@@ -4438,7 +4931,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
   expr = convert_like_real (convs->u.next, expr, fn, argnum,
                            convs->kind == ck_ref_bind ? -1 : 1,
                            convs->kind == ck_ref_bind ? issue_conversion_warnings : false, 
-                           c_cast_p);
+                           c_cast_p,
+                           complain);
   if (expr == error_mark_node)
     return error_mark_node;
 
@@ -4446,7 +4940,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     {
     case ck_rvalue:
       expr = convert_bitfield_to_declared_type (expr);
-      if (! IS_AGGR_TYPE (totype))
+      if (! MAYBE_CLASS_TYPE_P (totype))
        return expr;
       /* Else fall through.  */
     case ck_base:
@@ -4454,35 +4948,57 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        {
          /* We are going to bind a reference directly to a base-class
             subobject of EXPR.  */
-         if (convs->check_copy_constructor_p)
-           check_constructor_callable (TREE_TYPE (expr), expr);
          /* Build an expression for `*((base*) &expr)'.  */
-         expr = build_unary_op (ADDR_EXPR, expr, 0);
+         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 = build_indirect_ref (expr, "implicit conversion");
+         expr = cp_build_indirect_ref (expr, "implicit conversion", complain);
          return expr;
        }
 
       /* Copy-initialization where the cv-unqualified version of the source
         type is the same class as, or a derived class of, the class of the
         destination [is treated as direct-initialization].  [dcl.init] */
-      expr = build_temp (expr, totype, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
-                        &diagnostic_fn);
-      if (diagnostic_fn && fn)
-       diagnostic_fn ("  initializing argument %P of %qD", argnum, fn);
+      flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
+      if (convs->user_conv_p)
+       /* This conversion is being done in the context of a user-defined
+          conversion (i.e. the second step of copy-initialization), so
+          don't allow any more.  */
+       flags |= LOOKUP_NO_CONVERSION;
+      expr = build_temp (expr, totype, flags, &diag_kind);
+      if (diag_kind && fn)
+       {
+         if ((complain & tf_error))
+           emit_diagnostic (diag_kind, input_location, 0, 
+                            "  initializing argument %P of %qD", argnum, fn);
+         else if (diag_kind == DK_ERROR)
+           return error_mark_node;
+       }
       return build_cplus_new (totype, expr);
 
     case ck_ref_bind:
       {
        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
            that need temporaries, even when their types are reference
            compatible with the type of reference being bound, so the
-           upcoming call to build_unary_op (ADDR_EXPR, expr, ...)
+           upcoming call to cp_build_unary_op (ADDR_EXPR, expr, ...)
            doesn't fail.  */
        if (convs->need_temporary_p
            || TREE_CODE (expr) == CONSTRUCTOR
@@ -4494,16 +5010,19 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type))
                && !TYPE_REF_IS_RVALUE (ref_type))
              {
-               /* If the reference is volatile or non-const, we
-                  cannot create a temporary.  */
-               if (lvalue & clk_bitfield)
-                 error ("cannot bind bitfield %qE to %qT",
-                        expr, ref_type);
-               else if (lvalue & clk_packed)
-                 error ("cannot bind packed field %qE to %qT",
-                        expr, ref_type);
-               else
-                 error ("cannot bind rvalue %qE to %qT", expr, ref_type);
+               if (complain & tf_error)
+                 {
+                   /* If the reference is volatile or non-const, we
+                      cannot create a temporary.  */
+                   if (lvalue & clk_bitfield)
+                     error ("cannot bind bitfield %qE to %qT",
+                            expr, ref_type);
+                   else if (lvalue & clk_packed)
+                     error ("cannot bind packed field %qE to %qT",
+                            expr, ref_type);
+                   else
+                     error ("cannot bind rvalue %qE to %qT", expr, ref_type);
+                 }
                return error_mark_node;
              }
            /* If the source is a packed field, and we must use a copy
@@ -4516,16 +5035,22 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
                && CLASS_TYPE_P (type)
                && !TYPE_HAS_TRIVIAL_INIT_REF (type))
              {
-               error ("cannot bind packed field %qE to %qT",
-                      expr, ref_type);
+               if (complain & tf_error)
+                 error ("cannot bind packed field %qE to %qT",
+                        expr, ref_type);
                return error_mark_node;
              }
+           if (lvalue & clk_bitfield)
+             {
+               expr = convert_bitfield_to_declared_type (expr);
+               expr = fold_convert (type, expr);
+             }
            expr = build_target_expr_with_type (expr, type);
          }
 
        /* Take the address of the thing to which we will bind the
           reference.  */
-       expr = build_unary_op (ADDR_EXPR, expr, 1);
+       expr = cp_build_unary_op (ADDR_EXPR, expr, 1, complain);
        if (expr == error_mark_node)
          return error_mark_node;
 
@@ -4560,7 +5085,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       break;
     }
 
-  if (issue_conversion_warnings)
+  if (convs->check_narrowing)
+    check_narrowing (totype, expr);
+
+  if (issue_conversion_warnings && (complain & tf_warning))
     expr = convert_and_check (totype, expr);
   else
     expr = convert (totype, expr);
@@ -4568,18 +5096,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.  */
 
@@ -4608,20 +5124,23 @@ convert_arg_to_ellipsis (tree 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;
@@ -4640,21 +5159,21 @@ build_x_va_arg (tree expr, tree type)
   if (expr == error_mark_node || !type)
     return error_mark_node;
 
-  if (! pod_type_p (type))
+  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 = build_indirect_ref (expr, NULL);
+      expr = cp_build_indirect_ref (expr, 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
@@ -4681,9 +5200,14 @@ cxx_type_promotes_to (tree type)
    the indicated TYPE, which is a parameter to FN.  Do any required
    conversions.  Return the converted value.  */
 
+static GTY(()) VEC(tree,gc) *default_arg_context;
+
 tree
 convert_default_arg (tree type, tree arg, tree fn, int parmnum)
 {
+  int i;
+  tree t;
+
   /* If the ARG is an unparsed default argument expression, the
      conversion cannot be performed.  */
   if (TREE_CODE (arg) == DEFAULT_ARG)
@@ -4694,16 +5218,35 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
       return error_mark_node;
     }
 
+  /* Detect recursion.  */
+  for (i = 0; VEC_iterate (tree, default_arg_context, i, t); ++i)
+    if (t == fn)
+      {
+       error ("recursive evaluation of default argument for %q#D", fn);
+       return error_mark_node;
+      }
+  VEC_safe_push (tree, gc, default_arg_context, fn);
+
   if (fn && DECL_TEMPLATE_INFO (fn))
     arg = tsubst_default_argument (fn, type, arg);
 
-  arg = break_out_target_exprs (arg);
+  /* Due to:
+
+       [dcl.fct.default]
+
+       The names in the expression are bound, and the semantic
+       constraints are checked, at the point where the default
+       expressions appears.
 
+     we must not perform access checks here.  */
+  push_deferring_access_checks (dk_no_check);
+  arg = break_out_target_exprs (arg);
   if (TREE_CODE (arg) == CONSTRUCTOR)
     {
       arg = digest_init (type, arg);
       arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
-                                       "default argument", fn, parmnum);
+                                       "default argument", fn, parmnum,
+                                        tf_warning_or_error);
     }
   else
     {
@@ -4716,9 +5259,13 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
       if (!CONSTANT_CLASS_P (arg))
        arg = unshare_expr (arg);
       arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
-                                       "default argument", fn, parmnum);
+                                       "default argument", fn, parmnum,
+                                        tf_warning_or_error);
       arg = convert_for_arg_passing (type, arg);
     }
+  pop_deferring_access_checks();
+
+  VEC_pop (tree, default_arg_context);
 
   return arg;
 }
@@ -4810,7 +5357,6 @@ magic_varargs_p (tree fn)
       case BUILT_IN_CLASSIFY_TYPE:
       case BUILT_IN_CONSTANT_P:
       case BUILT_IN_NEXT_ARG:
-      case BUILT_IN_STDARG_START:
       case BUILT_IN_VA_START:
        return true;
 
@@ -4828,20 +5374,23 @@ magic_varargs_p (tree fn)
    bitmask of various LOOKUP_* flags which apply to the call itself.  */
 
 static tree
-build_over_call (struct z_candidate *cand, int flags)
+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;
+  bool already_used = false;
 
   /* In a template, there is no need to perform all of the work that
      is normally done.  We are only interested in the type of the call
@@ -4851,8 +5400,29 @@ build_over_call (struct z_candidate *cand, int flags)
     {
       tree expr;
       tree return_type;
+      const tree *argarray;
+      unsigned int nargs;
+
       return_type = TREE_TYPE (TREE_TYPE (fn));
-      expr = build_call_list (return_type, 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))
@@ -4868,6 +5438,10 @@ build_over_call (struct z_candidate *cand, int flags)
        joust (cand, w->loser, 1);
     }
 
+  /* Make =delete work with SFINAE.  */
+  if (DECL_DELETED_FN (fn) && !(complain & tf_error))
+    return error_mark_node;
+
   if (DECL_FUNCTION_MEMBER_P (fn))
     {
       /* If FN is a template function, two cases must be considered.
@@ -4903,13 +5477,9 @@ build_over_call (struct z_candidate *cand, int flags)
        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));
@@ -4918,16 +5488,24 @@ build_over_call (struct z_candidate *cand, int flags)
      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);
        }
     }
@@ -4935,13 +5513,21 @@ build_over_call (struct z_candidate *cand, int flags)
   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;
 
       if (convs[i]->bad_p)
-       pedwarn ("passing %qT as %<this%> argument of %q#D discards qualifiers",
-                TREE_TYPE (argtype), fn);
+       {
+         if (complain & tf_error)
+           permerror (input_location, "passing %qT as %<this%> argument of %q#D discards qualifiers",
+                      TREE_TYPE (argtype), fn);
+         else
+           return error_mark_node;
+       }
 
       /* [class.mfct.nonstatic]: If a nonstatic member function of a class
         X is called for an object that is not of type X, or of a type
@@ -4953,7 +5539,7 @@ build_over_call (struct z_candidate *cand, int flags)
       /* 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.  */
@@ -4972,13 +5558,17 @@ build_over_call (struct z_candidate *cand, int flags)
 
       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);
 
@@ -4986,14 +5576,19 @@ build_over_call (struct z_candidate *cand, int flags)
 
       /* Don't make a copy here if build_call is going to.  */
       if (conv->kind == ck_rvalue
-         && !TREE_ADDRESSABLE (complete_type (type)))
+         && COMPLETE_TYPE_P (complete_type (type))
+         && !TREE_ADDRESSABLE (type))
        conv = conv->u.next;
 
       val = convert_like_with_context
-       (conv, TREE_VALUE (arg), fn, i - is_method);
+       (conv, VEC_index (tree, args, arg_index), fn, i - is_method,
+        complain);
 
       val = convert_for_arg_passing (type, val);
-      argarray[j++] = val;
+      if (val == error_mark_node)
+        return error_mark_node;
+      else
+        argarray[j++] = val;
     }
 
   /* Default arguments */
@@ -5002,9 +5597,9 @@ build_over_call (struct z_candidate *cand, int flags)
                                         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.  */;
       else
@@ -5028,13 +5623,13 @@ build_over_call (struct z_candidate *cand, int flags)
                || 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;
-      while (TREE_CODE (targ) == NOP_EXPR
-            || TREE_CODE (targ) == NON_LVALUE_EXPR
-            || TREE_CODE (targ) == CONVERT_EXPR)
+      while (CONVERT_EXPR_P (targ)
+            || TREE_CODE (targ) == NON_LVALUE_EXPR)
        targ = TREE_OPERAND (targ, 0);
       if (TREE_CODE (targ) == ADDR_EXPR)
        {
@@ -5049,19 +5644,31 @@ build_over_call (struct z_candidate *cand, int flags)
       if (targ)
        arg = targ;
       else
-       arg = build_indirect_ref (arg, 0);
+       arg = cp_build_indirect_ref (arg, 0, complain);
 
+      if (TREE_CODE (arg) == TARGET_EXPR
+         && TARGET_EXPR_LIST_INIT_P (arg))
+       {
+         /* Copy-list-initialization doesn't require the copy constructor
+            to be defined.  */
+       }
       /* [class.copy]: the copy constructor is implicitly defined even if
         the implementation elided its use.  */
-      if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
-       mark_used (fn);
+      else if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
+       {
+         mark_used (fn);
+         already_used = true;
+       }
 
       /* If we're creating a temp and we already have one, don't create a
         new one.  If we're not creating a temp but we get one, use
         INIT_EXPR to collapse the temp into our target.  Otherwise, if the
         ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
         temp or an INIT_EXPR otherwise.  */
-      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;
@@ -5069,10 +5676,11 @@ build_over_call (struct z_candidate *cand, int flags)
            return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
        }
       else if (TREE_CODE (arg) == TARGET_EXPR
-              || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
+              || (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))
+                  && !move_fn_p (fn)))
        {
-         tree to = stabilize_reference
-           (build_indirect_ref (TREE_VALUE (args), 0));
+         tree to = stabilize_reference (cp_build_indirect_ref (fa, 0,
+                                                               complain));
 
          val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
          return val;
@@ -5083,37 +5691,55 @@ build_over_call (struct z_candidate *cand, int flags)
           && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
     {
       tree to = stabilize_reference
-       (build_indirect_ref (argarray[0], 0));
+       (cp_build_indirect_ref (argarray[0], 0, 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)))
        {
-         arg = build_indirect_ref (arg, 0);
+         arg = cp_build_indirect_ref (arg, 0, complain);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
        }
       else
        {
          /* We must only copy the non-tail padding parts.
-            Use __builtin_memcpy for the bitwise copy.  */
+            Use __builtin_memcpy for the bitwise copy.
+            FIXME fix 22488 so we can go back to using MODIFY_EXPR
+            instead of an explicit call to memcpy.  */
        
          tree arg0, arg1, arg2, t;
+         tree test = NULL_TREE;
 
          arg2 = TYPE_SIZE_UNIT (as_base);
          arg1 = arg;
-         arg0 = build_unary_op (ADDR_EXPR, to, 0);
+         arg0 = cp_build_unary_op (ADDR_EXPR, to, 0, complain);
+
+         if (!can_trust_pointer_alignment ())
+           {
+             /* 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.  Otherwise it is
+                expanded as a block move, which should be safe.  */
+             arg0 = save_expr (arg0);
+             arg1 = save_expr (arg1);
+             test = build2 (EQ_EXPR, boolean_type_node, arg0, arg1);
+           }
          t = implicit_built_in_decls[BUILT_IN_MEMCPY];
          t = build_call_n (t, 3, arg0, arg1, arg2);
 
          t = convert (TREE_TYPE (arg0), t);
-         val = build_indirect_ref (t, 0);
+         if (test)
+           t = build3 (COND_EXPR, TREE_TYPE (t), test, arg0, t);
+         val = cp_build_indirect_ref (t, 0, complain);
+          TREE_NO_WARNING (val) = 1;
        }
 
       return val;
     }
 
-  mark_used (fn);
+  if (!already_used)
+    mark_used (fn);
 
   if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
     {
@@ -5123,6 +5749,11 @@ build_over_call (struct z_candidate *cand, int flags)
                                ba_any, NULL);
       gcc_assert (binfo && binfo != error_mark_node);
 
+      /* Warn about deprecated virtual functions now, since we're about
+        to throw away the decl.  */
+      if (TREE_DEPRECATED (fn))
+       warn_deprecated_use (fn, NULL_TREE);
+
       argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1);
       if (TREE_SIDE_EFFECTS (argarray[0]))
        argarray[0] = save_expr (argarray[0]);
@@ -5133,8 +5764,6 @@ build_over_call (struct z_candidate *cand, int flags)
        fn = build_vfn_ref (argarray[0], DECL_VINDEX (fn));
       TREE_TYPE (fn) = t;
     }
-  else if (DECL_INLINE (fn))
-    fn = inline_conversion (fn);
   else
     fn = build_addr_func (fn);
 
@@ -5159,6 +5788,13 @@ build_cxx_call (tree fn, int nargs, tree *argarray)
       && cfun)
     cp_function_chain->can_throw = 1;
 
+  /* Check that arguments to builtin functions match the expectations.  */
+  if (fndecl
+      && DECL_BUILT_IN (fndecl)
+      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+      && !check_builtin_function_arguments (fndecl, nargs, argarray))
+    return error_mark_node;
+
   /* Some built-in function calls will be evaluated at compile-time in
      fold ().  */
   fn = fold_if_not_in_template (fn);
@@ -5170,7 +5806,7 @@ build_cxx_call (tree fn, int nargs, tree *argarray)
   if (fn == error_mark_node)
     return error_mark_node;
 
-  if (IS_AGGR_TYPE (TREE_TYPE (fn)))
+  if (MAYBE_CLASS_TYPE_P (TREE_TYPE (fn)))
     fn = build_cplus_new (TREE_TYPE (fn), fn);
   return convert_from_reference (fn);
 }
@@ -5203,7 +5839,8 @@ 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 (build_indirect_ref (instance, 0),
+  klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, 0, 
+                                                     tf_warning_or_error),
                              integer_zero_node);
 
   /* Get the java.lang.Class pointer for the interface being called.  */
@@ -5264,9 +5901,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.
 
@@ -5275,12 +5913,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,
-                          tree binfo, int flags)
+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
@@ -5312,7 +5952,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
@@ -5361,12 +6001,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);
+  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
@@ -5388,7 +6040,7 @@ name_as_c_string (tree name, tree type, bool *free_p)
   if (IDENTIFIER_CTOR_OR_DTOR_P (name))
     {
       pretty_name
-       = (char *) CONST_CAST (IDENTIFIER_POINTER (constructor_name (type)));
+       = CONST_CAST (char *, identifier_to_locale (IDENTIFIER_POINTER (constructor_name (type))));
       /* For a destructor, add the '~'.  */
       if (name == complete_dtor_identifier
          || name == base_dtor_identifier
@@ -5402,34 +6054,37 @@ name_as_c_string (tree name, tree type, bool *free_p)
   else if (IDENTIFIER_TYPENAME_P (name))
     {
       pretty_name = concat ("operator ",
-                           type_as_string (TREE_TYPE (name),
-                                           TFF_PLAIN_IDENTIFIER),
+                           type_as_string_translate (TREE_TYPE (name),
+                                                     TFF_PLAIN_IDENTIFIER),
                            NULL);
       /* Remember that we need to free the memory allocated.  */
       *free_p = true;
     }
   else
-    pretty_name = (char *) CONST_CAST (IDENTIFIER_POINTER (name));
+    pretty_name = CONST_CAST (char *, identifier_to_locale (IDENTIFIER_POINTER (name)));
 
   return pretty_name;
 }
 
 /* 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)
+                      tree *fn_p, tsubst_flags_t complain)
 {
   struct z_candidate *candidates = 0, *cand;
   tree explicit_targs = NULL_TREE;
   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;
@@ -5437,7 +6092,7 @@ build_new_method_call (tree instance, tree fns, tree args,
   bool any_viable_p;
   tree orig_instance;
   tree orig_fns;
-  tree orig_args;
+  VEC(tree,gc) *orig_args = NULL;
   void *p;
 
   gcc_assert (instance != NULL_TREE);
@@ -5447,19 +6102,18 @@ 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)
+      || error_operand_p (fns))
     return error_mark_node;
 
   if (!BASELINK_P (fns))
     {
-      error ("call to non-function %qD", fns);
+      if (complain & tf_error)
+       error ("call to non-function %qD", fns);
       return error_mark_node;
     }
 
   orig_instance = instance;
   orig_fns = fns;
-  orig_args = args;
 
   /* Dismantle the baselink to collect all the information we need.  */
   if (!conversion_path)
@@ -5484,16 +6138,20 @@ 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);
-    }
-
-  /* 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;
+      if (args != NULL)
+       make_args_non_dependent (*args);
+    }
+
+  /* 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;
+  user_args = args == NULL ? NULL : *args;
   if (IDENTIFIER_CTOR_OR_DTOR_P (name))
     {
       /* Callers should explicitly indicate whether they want to construct
@@ -5504,28 +6162,46 @@ 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);
 
-  /* It's OK to call destructors on cv-qualified objects.  Therefore,
-     convert the INSTANCE_PTR to the unqualified type, if necessary.  */
-  if (DECL_DESTRUCTOR_P (fn))
+  /* It's OK to call destructors and constructors on cv-qualified objects.
+     Therefore, convert the INSTANCE_PTR to the unqualified type, if
+     necessary.  */
+  if (DECL_DESTRUCTOR_P (fn)
+      || DECL_CONSTRUCTOR_P (fn))
     {
       tree type = build_pointer_type (basetype);
       if (!same_type_p (type, TREE_TYPE (instance_ptr)))
        instance_ptr = build_nop (type, instance_ptr);
-      name = complete_dtor_identifier;
+    }
+  if (DECL_DESTRUCTOR_P (fn))
+    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 != NULL && !VEC_empty (tree, *args)
+      && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *args, 0))
+      && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0))
+      && !TYPE_HAS_LIST_CTOR (basetype))
+    {
+      gcc_assert (VEC_length (tree, *args) == 1);
+      *args = ctor_to_vec (VEC_index (tree, *args, 0));
     }
 
   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);
@@ -5533,7 +6209,7 @@ build_new_method_call (tree instance, tree fns, tree args,
   for (fn = fns; fn; fn = OVL_NEXT (fn))
     {
       tree t = OVL_CURRENT (fn);
-      tree this_arglist;
+      tree this_first_arg;
 
       /* We can end up here for copy-init of same or base class.  */
       if ((flags & LOOKUP_ONLYCONVERTING)
@@ -5541,16 +6217,18 @@ build_new_method_call (tree instance, tree fns, tree args,
        continue;
 
       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
-       this_arglist = mem_args;
+       this_first_arg = first_mem_arg;
       else
-       this_arglist = args;
+       this_first_arg = NULL_TREE;
 
       if (TREE_CODE (t) == TEMPLATE_DECL)
        /* A member template.  */
        add_template_candidate (&candidates, t,
                                class_type,
                                explicit_targs,
-                               this_arglist, optype,
+                               this_first_arg,
+                               args == NULL ? NULL : *args,
+                               optype,
                                access_binfo,
                                conversion_path,
                                flags,
@@ -5558,7 +6236,8 @@ build_new_method_call (tree instance, tree fns, tree args,
       else if (! template_only)
        add_function_candidate (&candidates, t,
                                class_type,
-                               this_arglist,
+                               this_first_arg,
+                               args == NULL ? NULL : *args,
                                access_binfo,
                                conversion_path,
                                flags);
@@ -5567,21 +6246,28 @@ build_new_method_call (tree instance, tree fns, tree args,
   candidates = splice_viable (candidates, pedantic, &any_viable_p);
   if (!any_viable_p)
     {
-      if (!COMPLETE_TYPE_P (basetype))
-       cxx_incomplete_type_error (instance_ptr, basetype);
-      else
+      if (complain & tf_error)
        {
-         char *pretty_name;
-         bool free_p;
-
-         pretty_name = name_as_c_string (name, basetype, &free_p);
-         error ("no matching function for call to %<%T::%s(%A)%#V%>",
-                basetype, pretty_name, user_args,
-                TREE_TYPE (TREE_TYPE (instance_ptr)));
-         if (free_p)
-           free (pretty_name);
+         if (!COMPLETE_TYPE_P (basetype))
+           cxx_incomplete_type_error (instance_ptr, basetype);
+         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, arglist,
+                    TREE_TYPE (TREE_TYPE (instance_ptr)));
+             if (free_p)
+               free (pretty_name);
+           }
+         print_z_candidates (candidates);
        }
-      print_z_candidates (candidates);
       call = error_mark_node;
     }
   else
@@ -5591,13 +6277,20 @@ build_new_method_call (tree instance, tree fns, tree args,
        {
          char *pretty_name;
          bool free_p;
+         tree arglist;
 
-         pretty_name = name_as_c_string (name, basetype, &free_p);
-         error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
-                user_args);
-         print_z_candidates (candidates);
-         if (free_p)
-           free (pretty_name);
+         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,
+                    arglist);
+             print_z_candidates (candidates);
+             if (free_p)
+               free (pretty_name);
+           }
          call = error_mark_node;
        }
       else
@@ -5608,7 +6301,8 @@ build_new_method_call (tree instance, tree fns, tree args,
              && DECL_PURE_VIRTUAL_P (fn)
              && instance == current_class_ref
              && (DECL_CONSTRUCTOR_P (current_function_decl)
-                 || DECL_DESTRUCTOR_P (current_function_decl)))
+                 || DECL_DESTRUCTOR_P (current_function_decl))
+             && (complain & tf_warning))
            /* This is not an error, it is runtime undefined
               behavior.  */
            warning (0, (DECL_CONSTRUCTOR_P (current_function_decl) ?
@@ -5619,8 +6313,9 @@ build_new_method_call (tree instance, tree fns, tree args,
          if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
              && is_dummy_object (instance_ptr))
            {
-             error ("cannot call member function %qD without object",
-                    fn);
+             if (complain & tf_error)
+               error ("cannot call member function %qD without object",
+                      fn);
              call = error_mark_node;
            }
          else
@@ -5632,7 +6327,7 @@ build_new_method_call (tree instance, tree fns, tree args,
              if (fn_p)
                *fn_p = fn;
              /* Build the actual CALL_EXPR.  */
-             call = build_over_call (cand, flags);
+             call = build_over_call (cand, flags, complain);
              /* In an expression of the form `a->f()' where `f' turns
                 out to be a static member function, `a' is
                 none-the-less evaluated.  */
@@ -5660,14 +6355,34 @@ build_new_method_call (tree instance, tree fns, tree args,
     }
 
   if (processing_template_decl && call != error_mark_node)
-    call = (build_min_non_dep_call_list
-           (call,
-            build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
-            orig_args));
+    {
+      bool cast_to_void = false;
+
+      if (TREE_CODE (call) == COMPOUND_EXPR)
+       call = TREE_OPERAND (call, 1);
+      else if (TREE_CODE (call) == NOP_EXPR)
+       {
+         cast_to_void = true;
+         call = TREE_OPERAND (call, 0);
+       }
+      if (TREE_CODE (call) == INDIRECT_REF)
+       call = TREE_OPERAND (call, 0);
+      call = (build_min_non_dep_call_vec
+             (call,
+              build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
+                         orig_instance, orig_fns, NULL_TREE),
+              orig_args));
+      call = convert_from_reference (call);
+      if (cast_to_void)
+       call = build_nop (void_type_node, call);
+    }
 
  /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
 
+  if (orig_args != NULL)
+    release_tree_vector (orig_args);
+
   return call;
 }
 
@@ -5716,8 +6431,7 @@ is_subseq (conversion *ics1, conversion *ics2)
 bool
 is_properly_derived_from (tree derived, tree base)
 {
-  if (!IS_AGGR_TYPE_CODE (TREE_CODE (derived))
-      || !IS_AGGR_TYPE_CODE (TREE_CODE (base)))
+  if (!CLASS_TYPE_P (derived) || !CLASS_TYPE_P (base))
     return false;
 
   /* We only allow proper derivation here.  The DERIVED_FROM_P macro
@@ -5759,7 +6473,8 @@ maybe_handle_implicit_object (conversion **ics)
        t = t->u.next;
       t = build_identity_conv (TREE_TYPE (t->type), NULL_TREE);
       t = direct_reference_binding (reference_type, t);
-      t->rvaluedness_matches_p = 1;
+      t->this_p = 1;
+      t->rvaluedness_matches_p = 0;
       *ics = t;
     }
 }
@@ -5776,7 +6491,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;
     }
 
@@ -5817,6 +6531,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
@@ -5868,10 +6590,10 @@ compare_ics (conversion *ics1, conversion *ics2)
       conversion *t2;
 
       for (t1 = ics1; t1->kind != ck_user; t1 = t1->u.next)
-       if (t1->kind == ck_ambig)
+       if (t1->kind == ck_ambig || t1->kind == ck_aggr)
          return 0;
       for (t2 = ics2; t2->kind != ck_user; t2 = t2->u.next)
-       if (t2->kind == ck_ambig)
+       if (t2->kind == ck_ambig || t2->kind == ck_aggr)
          return 0;
 
       if (t1->cand->fn != t2->cand->fn)
@@ -5911,6 +6633,10 @@ compare_ics (conversion *ics1, conversion *ics2)
       from_type2 = t2->type;
     }
 
+  /* One sequence can only be a subsequence of the other if they start with
+     the same type.  They can start with different types when comparing the
+     second standard conversion sequence in two user-defined conversion
+     sequences.  */
   if (same_type_p (from_type1, from_type2))
     {
       if (is_subseq (ics1, ics2))
@@ -5918,10 +6644,6 @@ compare_ics (conversion *ics1, conversion *ics2)
       if (is_subseq (ics2, ics1))
        return -1;
     }
-  /* Otherwise, one sequence cannot be a subsequence of the other; they
-     don't start with the same type.  This can happen when comparing the
-     second standard conversion sequence in two user-defined conversion
-     sequences.  */
 
   /* [over.ics.rank]
 
@@ -5951,6 +6673,21 @@ compare_ics (conversion *ics1, conversion *ics2)
   to_type1 = ics1->type;
   to_type2 = ics2->type;
 
+  /* A conversion from scalar arithmetic type to complex is worse than a
+     conversion between scalar arithmetic types.  */
+  if (same_type_p (from_type1, from_type2)
+      && ARITHMETIC_TYPE_P (from_type1)
+      && ARITHMETIC_TYPE_P (to_type1)
+      && ARITHMETIC_TYPE_P (to_type2)
+      && ((TREE_CODE (to_type1) == COMPLEX_TYPE)
+         != (TREE_CODE (to_type2) == COMPLEX_TYPE)))
+    {
+      if (TREE_CODE (to_type1) == COMPLEX_TYPE)
+       return -1;
+      else
+       return 1;
+    }
+
   if (TYPE_PTR_P (from_type1)
       && TYPE_PTR_P (from_type2)
       && TYPE_PTR_P (to_type1)
@@ -5979,8 +6716,8 @@ compare_ics (conversion *ics1, conversion *ics2)
     }
 
   if (deref_from_type1 != NULL_TREE
-      && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type1))
-      && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type2)))
+      && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_from_type1))
+      && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_from_type2)))
     {
       /* This was one of the pointer or pointer-like conversions.
 
@@ -6017,8 +6754,8 @@ compare_ics (conversion *ics1, conversion *ics2)
                return -1;
            }
        }
-      else if (IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type1))
-              && IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type2)))
+      else if (RECORD_OR_UNION_CODE_P (TREE_CODE (deref_to_type1))
+              && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_to_type2)))
        {
          /* [over.ics.rank]
 
@@ -6102,7 +6839,11 @@ compare_ics (conversion *ics1, conversion *ics2)
   if (ics1->kind == ck_qual
       && ics2->kind == ck_qual
       && same_type_p (from_type1, from_type2))
-    return comp_cv_qual_signature (to_type1, to_type2);
+    {
+      int result = comp_cv_qual_signature (to_type1, to_type2);
+      if (result != 0)
+       return result;
+    }
 
   /* [over.ics.rank]
 
@@ -6118,18 +6859,21 @@ compare_ics (conversion *ics1, conversion *ics2)
      initialized by S2 refers is more cv-qualified than the type to
      which the reference initialized by S1 refers */
 
-  if (ref_conv1 && ref_conv2
-      && same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))
+  if (ref_conv1 && ref_conv2)
     {
-      if (ref_conv1->rvaluedness_matches_p
-         && !ref_conv2->rvaluedness_matches_p)
-       return 1;
-      else if (!ref_conv1->rvaluedness_matches_p
-         && ref_conv2->rvaluedness_matches_p)
-       return -1;
+      if (!ref_conv1->this_p && !ref_conv2->this_p
+         && (TYPE_REF_IS_RVALUE (ref_conv1->type)
+             != TYPE_REF_IS_RVALUE (ref_conv2->type)))
+       {
+         if (ref_conv1->rvaluedness_matches_p)
+           return 1;
+         if (ref_conv2->rvaluedness_matches_p)
+           return -1;
+       }
 
-      return comp_cv_qualification (TREE_TYPE (ref_conv2->type),
-                                   TREE_TYPE (ref_conv1->type));
+      if (same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))
+       return comp_cv_qualification (TREE_TYPE (ref_conv2->type),
+                                     TREE_TYPE (ref_conv1->type));
     }
 
   /* Neither conversion sequence is better than the other.  */
@@ -6314,10 +7058,12 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
          tree source = source_type (w->convs[0]);
          if (! DECL_CONSTRUCTOR_P (w->fn))
            source = TREE_TYPE (source);
-         warning (OPT_Wconversion, "choosing %qD over %qD", w->fn, l->fn);
-         warning (OPT_Wconversion, "  for conversion from %qT to %qT",
-                  source, w->second_conv->type);
-         inform ("  because conversion sequence for the argument is better");
+         if (warning (OPT_Wconversion, "choosing %qD over %qD", w->fn, l->fn)
+             && warning (OPT_Wconversion, "  for conversion from %qT to %qT",
+                         source, w->second_conv->type)) 
+           {
+             inform (input_location, "  because conversion sequence for the argument is better");
+           }
        }
       else
        add_warning (w, l);
@@ -6401,11 +7147,56 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
        }
     }
 
-  /* If the two functions are the same (this can happen with declarations
-     in multiple scopes and arg-dependent lookup), arbitrarily choose one.  */
+  /* If the two function declarations represent the same function (this can
+     happen with declarations in multiple scopes and arg-dependent lookup),
+     arbitrarily choose one.  But first make sure the default args we're
+     using match.  */
   if (DECL_P (cand1->fn) && DECL_P (cand2->fn)
       && equal_functions (cand1->fn, cand2->fn))
-    return 1;
+    {
+      tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (cand1->fn));
+      tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (cand2->fn));
+
+      gcc_assert (!DECL_CONSTRUCTOR_P (cand1->fn));
+
+      for (i = 0; i < len; ++i)
+       {
+         /* Don't crash if the fn is variadic.  */
+         if (!parms1)
+           break;
+         parms1 = TREE_CHAIN (parms1);
+         parms2 = TREE_CHAIN (parms2);
+       }
+
+      if (off1)
+       parms1 = TREE_CHAIN (parms1);
+      else if (off2)
+       parms2 = TREE_CHAIN (parms2);
+
+      for (; parms1; ++i)
+       {
+         if (!cp_tree_equal (TREE_PURPOSE (parms1),
+                             TREE_PURPOSE (parms2)))
+           {
+             if (warn)
+               {
+                 permerror (input_location, "default argument mismatch in "
+                            "overload resolution");
+                 inform (input_location,
+                         " candidate 1: %q+#F", cand1->fn);
+                 inform (input_location,
+                         " candidate 2: %q+#F", cand2->fn);
+               }
+             else
+               add_warning (cand1, cand2);
+             break;
+           }
+         parms1 = TREE_CHAIN (parms1);
+         parms2 = TREE_CHAIN (parms2);
+       }
+
+      return 1;
+    }
 
 tweak:
 
@@ -6431,10 +7222,10 @@ tweak:
        {
          if (warn)
            {
-             pedwarn ("\
-ISO C++ says that these are ambiguous, even \
-though the worst conversion for the first is better than \
-the worst conversion for the second:");
+             pedwarn (input_location, 0,
+             "ISO C++ says that these are ambiguous, even "
+             "though the worst conversion for the first is better than "
+             "the worst conversion for the second:");
              print_z_candidate (_("candidate 1:"), w);
              print_z_candidate (_("candidate 2:"), l);
            }
@@ -6508,7 +7299,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.  */
@@ -6536,7 +7327,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;
@@ -6545,7 +7336,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);
 
@@ -6559,7 +7350,7 @@ can_convert_arg_bad (tree to, tree from, tree arg)
    doing a bad conversion, convert_like will complain.  */
 
 tree
-perform_implicit_conversion (tree type, tree expr)
+perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain, int flags)
 {
   conversion *conv;
   void *p;
@@ -6572,10 +7363,21 @@ perform_implicit_conversion (tree type, tree expr)
 
   conv = implicit_conversion (type, TREE_TYPE (expr), expr,
                              /*c_cast_p=*/false,
-                             LOOKUP_NORMAL);
+                             flags);
+
   if (!conv)
     {
-      error ("could not convert %qE to %qT", expr, type);
+      if (complain & tf_error)
+       {
+         /* If expr has unknown type, then it is an overloaded function.
+            Call instantiate_type to get good error messages.  */
+         if (TREE_TYPE (expr) == unknown_type_node)
+           instantiate_type (type, expr, complain);
+         else if (invalid_nonstatic_memfn_p (expr, complain))
+           /* We gave an error.  */;
+         else
+           error ("could not convert %qE to %qT", expr, type);
+       }
       expr = error_mark_node;
     }
   else if (processing_template_decl)
@@ -6587,7 +7389,7 @@ perform_implicit_conversion (tree type, tree expr)
        expr = build_nop (type, expr);
     }
   else
-    expr = convert_like (conv, expr);
+    expr = convert_like (conv, expr, complain);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -6595,6 +7397,12 @@ perform_implicit_conversion (tree type, tree expr)
   return expr;
 }
 
+tree
+perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
+{
+  return perform_implicit_conversion_flags (type, expr, complain, LOOKUP_IMPLICIT);
+}
+
 /* Convert EXPR to TYPE (as a direct-initialization) if that is
    permitted.  If the conversion is valid, the converted expression is
    returned.  Otherwise, NULL_TREE is returned, except in the case
@@ -6606,7 +7414,8 @@ perform_implicit_conversion (tree type, tree expr)
 tree
 perform_direct_initialization_if_possible (tree type,
                                           tree expr,
-                                          bool c_cast_p)
+                                          bool c_cast_p,
+                                           tsubst_flags_t complain)
 {
   conversion *conv;
   void *p;
@@ -6623,9 +7432,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);
+                                       &args, type, LOOKUP_NORMAL, complain);
+      release_tree_vector (args);
       return build_cplus_new (type, expr);
     }
 
@@ -6640,7 +7450,8 @@ perform_direct_initialization_if_possible (tree type,
   else
     expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
                              /*issue_conversion_warnings=*/false,
-                             c_cast_p);
+                             c_cast_p,
+                             tf_warning_or_error);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -6680,6 +7491,76 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
   return var;
 }
 
+/* EXPR is the initializer for a variable DECL of reference or
+   std::initializer_list type.  Create, push and return a new VAR_DECL
+   for the initializer so that it will live as long as DECL.  Any
+   cleanup for the new variable is returned through CLEANUP, and the
+   code to initialize the new variable is returned through INITP.  */
+
+tree
+set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp)
+{
+  tree init;
+  tree type;
+  tree var;
+
+  /* Create the temporary variable.  */
+  type = TREE_TYPE (expr);
+  var = make_temporary_var_for_ref_to_temp (decl, type);
+  layout_decl (var, 0);
+  /* If the rvalue is the result of a function call it will be
+     a TARGET_EXPR.  If it is some other construct (such as a
+     member access expression where the underlying object is
+     itself the result of a function call), turn it into a
+     TARGET_EXPR here.  It is important that EXPR be a
+     TARGET_EXPR below since otherwise the INIT_EXPR will
+     attempt to make a bitwise copy of EXPR to initialize
+     VAR.  */
+  if (TREE_CODE (expr) != TARGET_EXPR)
+    expr = get_target_expr (expr);
+  /* Create the INIT_EXPR that will initialize the temporary
+     variable.  */
+  init = build2 (INIT_EXPR, type, var, expr);
+  if (at_function_scope_p ())
+    {
+      add_decl_expr (var);
+
+      if (TREE_STATIC (var))
+       init = add_stmt_to_compound (init, register_dtor_fn (var));
+      else
+       *cleanup = cxx_maybe_build_cleanup (var);
+
+      /* We must be careful to destroy the temporary only
+        after its initialization has taken place.  If the
+        initialization throws an exception, then the
+        destructor should not be run.  We cannot simply
+        transform INIT into something like:
+
+        (INIT, ({ CLEANUP_STMT; }))
+
+        because emit_local_var always treats the
+        initializer as a full-expression.  Thus, the
+        destructor would run too early; it would run at the
+        end of initializing the reference variable, rather
+        than at the end of the block enclosing the
+        reference variable.
+
+        The solution is to pass back a cleanup expression
+        which the caller is responsible for attaching to
+        the statement tree.  */
+    }
+  else
+    {
+      rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
+      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+       static_aggregates = tree_cons (NULL_TREE, var,
+                                      static_aggregates);
+    }
+
+  *initp = init;
+  return var;
+}
+
 /* Convert EXPR to the indicated reference TYPE, in a way suitable for
    initializing a variable of that TYPE.  If DECL is non-NULL, it is
    the VAR_DECL being initialized with the EXPR.  (In that case, the
@@ -6708,6 +7589,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
   if (!conv || conv->bad_p)
     {
       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 a temporary of type %qT",
@@ -6765,8 +7647,6 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
         remember that the conversion was required.  */
       if (conv->kind == ck_base)
        {
-         if (conv->check_copy_constructor_p)
-           check_constructor_callable (TREE_TYPE (expr), expr);
          base_conv_type = conv->type;
          conv = conv->u.next;
        }
@@ -6777,64 +7657,16 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
                                /*fn=*/NULL_TREE, /*argnum=*/0,
                                /*inner=*/-1,
                                /*issue_conversion_warnings=*/true,
-                               /*c_cast_p=*/false);
+                               /*c_cast_p=*/false,
+                               tf_warning_or_error);
       if (error_operand_p (expr))
        expr = error_mark_node;
       else
        {
-         if (!real_lvalue_p (expr))
+         if (!lvalue_or_rvalue_with_address_p (expr))
            {
              tree init;
-             tree type;
-
-             /* Create the temporary variable.  */
-             type = TREE_TYPE (expr);
-             var = make_temporary_var_for_ref_to_temp (decl, type);
-             layout_decl (var, 0);
-             /* If the rvalue is the result of a function call it will be
-                a TARGET_EXPR.  If it is some other construct (such as a
-                member access expression where the underlying object is
-                itself the result of a function call), turn it into a
-                TARGET_EXPR here.  It is important that EXPR be a
-                TARGET_EXPR below since otherwise the INIT_EXPR will
-                attempt to make a bitwise copy of EXPR to initialize
-                VAR.  */
-             if (TREE_CODE (expr) != TARGET_EXPR)
-               expr = get_target_expr (expr);
-             /* Create the INIT_EXPR that will initialize the temporary
-                variable.  */
-             init = build2 (INIT_EXPR, type, var, expr);
-             if (at_function_scope_p ())
-               {
-                 add_decl_expr (var);
-                 *cleanup = cxx_maybe_build_cleanup (var);
-
-                 /* We must be careful to destroy the temporary only
-                    after its initialization has taken place.  If the
-                    initialization throws an exception, then the
-                    destructor should not be run.  We cannot simply
-                    transform INIT into something like:
-
-                        (INIT, ({ CLEANUP_STMT; }))
-
-                    because emit_local_var always treats the
-                    initializer as a full-expression.  Thus, the
-                    destructor would run too early; it would run at the
-                    end of initializing the reference variable, rather
-                    than at the end of the block enclosing the
-                    reference variable.
-
-                    The solution is to pass back a cleanup expression
-                    which the caller is responsible for attaching to
-                    the statement tree.  */
-               }
-             else
-               {
-                 rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
-                 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
-                   static_aggregates = tree_cons (NULL_TREE, var,
-                                                  static_aggregates);
-               }
+             var = set_up_extended_ref_temp (decl, expr, cleanup, &init);
              /* Use its address to initialize the reference variable.  */
              expr = build_address (var);
              if (base_conv_type)
@@ -6846,17 +7678,18 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
            }
          else
            /* Take the address of EXPR.  */
-           expr = build_unary_op (ADDR_EXPR, expr, 0);
+           expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error);
          /* If a BASE_CONV was required, perform it now.  */
          if (base_conv_type)
            expr = (perform_implicit_conversion
-                   (build_pointer_type (base_conv_type), expr));
+                   (build_pointer_type (base_conv_type), expr,
+                    tf_warning_or_error));
          expr = build_nop (type, expr);
        }
     }
   else
     /* Perform the conversion.  */
-    expr = convert_like (conv, expr);
+    expr = convert_like (conv, expr, tf_warning_or_error);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -6864,4 +7697,39 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
   return expr;
 }
 
+/* Returns true iff TYPE is some variant of std::initializer_list.  */
+
+bool
+is_std_init_list (tree type)
+{
+  return (CLASS_TYPE_P (type)
+         && CP_TYPE_CONTEXT (type) == std_node
+         && strcmp (TYPE_NAME_STRING (type), "initializer_list") == 0);
+}
+
+/* Returns true iff DECL is a list constructor: i.e. a constructor which
+   will accept an argument list of a single std::initializer_list<T>.  */
+
+bool
+is_list_ctor (tree decl)
+{
+  tree args = FUNCTION_FIRST_USER_PARMTYPE (decl);
+  tree arg;
+
+  if (!args || args == void_list_node)
+    return false;
+
+  arg = non_reference (TREE_VALUE (args));
+  if (!is_std_init_list (arg))
+    return false;
+
+  args = TREE_CHAIN (args);
+
+  if (args && args != void_list_node && !TREE_PURPOSE (args))
+    /* There are more non-defaulted parms.  */
+    return false;
+
+  return true;
+}
+
 #include "gt-cp-call.h"