OSDN Git Service

PR c++/44157
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 02fc4b3..46779fa 100644 (file)
@@ -197,8 +197,8 @@ static bool promoted_arithmetic_type_p (tree);
 static conversion *conditional_conversion (tree, tree);
 static char *name_as_c_string (tree, tree, bool *);
 static tree prep_operand (tree);
 static conversion *conditional_conversion (tree, tree);
 static char *name_as_c_string (tree, tree, bool *);
 static tree prep_operand (tree);
-static void add_candidates (tree, const VEC(tree,gc) *, tree, bool, tree, tree,
-                           int, struct z_candidate **);
+static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool,
+                           tree, tree, int, struct z_candidate **);
 static conversion *merge_conversion_sequences (conversion *, conversion *);
 static bool magic_varargs_p (tree);
 static tree build_temp (tree, tree, int, diagnostic_t *);
 static conversion *merge_conversion_sequences (conversion *, conversion *);
 static bool magic_varargs_p (tree);
 static tree build_temp (tree, tree, int, diagnostic_t *);
@@ -460,9 +460,11 @@ null_ptr_cst_p (tree t)
   /* [conv.ptr]
 
      A null pointer constant is an integral constant expression
   /* [conv.ptr]
 
      A null pointer constant is an integral constant expression
-     (_expr.const_) rvalue of integer type that evaluates to zero.  */
+     (_expr.const_) rvalue of integer type that evaluates to zero or
+     an rvalue of type std::nullptr_t. */
   t = integral_constant_value (t);
   t = integral_constant_value (t);
-  if (t == null_node)
+  if (t == null_node
+      || NULLPTR_TYPE_P (TREE_TYPE (t)))
     return true;
   if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t))
     {
     return true;
   if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t))
     {
@@ -626,23 +628,27 @@ build_aggr_conv (tree type, tree ctor, int flags)
 {
   unsigned HOST_WIDE_INT i = 0;
   conversion *c;
 {
   unsigned HOST_WIDE_INT i = 0;
   conversion *c;
-  tree field = TYPE_FIELDS (type);
+  tree field = next_initializable_field (TYPE_FIELDS (type));
 
 
-  for (; field; field = TREE_CHAIN (field), ++i)
+  for (; field; field = next_initializable_field (TREE_CHAIN (field)))
     {
     {
-      if (TREE_CODE (field) != FIELD_DECL)
-       continue;
       if (i < CONSTRUCTOR_NELTS (ctor))
        {
          constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i);
          if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value),
                                ce->value, flags))
            return NULL;
       if (i < CONSTRUCTOR_NELTS (ctor))
        {
          constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i);
          if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value),
                                ce->value, flags))
            return NULL;
+         ++i;
+         if (TREE_CODE (type) == UNION_TYPE)
+           break;
        }
       else if (build_value_init (TREE_TYPE (field)) == error_mark_node)
        return NULL;
     }
 
        }
       else if (build_value_init (TREE_TYPE (field)) == error_mark_node)
        return NULL;
     }
 
+  if (i < CONSTRUCTOR_NELTS (ctor))
+    return NULL;
+
   c = alloc_conversion (ck_aggr);
   c->type = type;
   c->rank = cr_exact;
   c = alloc_conversion (ck_aggr);
   c->type = type;
   c->rank = cr_exact;
@@ -772,7 +778,12 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   if (same_type_p (from, to))
     return conv;
 
   if (same_type_p (from, to))
     return conv;
 
-  if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to))
+  /* [conv.ptr]
+     A null pointer constant can be converted to a pointer type; ... A
+     null pointer constant of integral type can be converted to an
+     rvalue of type std::nullptr_t. */
+  if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to)
+       || NULLPTR_TYPE_P (to))
       && expr && null_ptr_cst_p (expr))
     conv = build_conv (ck_std, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
       && expr && null_ptr_cst_p (expr))
     conv = build_conv (ck_std, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
@@ -907,17 +918,20 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
          An rvalue of arithmetic, unscoped enumeration, pointer, or
          pointer to member type can be converted to an rvalue of type
 
          An rvalue of arithmetic, unscoped enumeration, pointer, or
          pointer to member type can be converted to an rvalue of type
-         bool.  */
+         bool. ... An rvalue of type std::nullptr_t can be converted
+         to an rvalue of type bool;  */
       if (ARITHMETIC_TYPE_P (from)
          || UNSCOPED_ENUM_P (from)
          || fcode == POINTER_TYPE
       if (ARITHMETIC_TYPE_P (from)
          || UNSCOPED_ENUM_P (from)
          || fcode == POINTER_TYPE
-         || TYPE_PTR_TO_MEMBER_P (from))
+         || TYPE_PTR_TO_MEMBER_P (from)
+         || NULLPTR_TYPE_P (from))
        {
          conv = build_conv (ck_std, to, conv);
          if (fcode == POINTER_TYPE
              || TYPE_PTRMEM_P (from)
              || (TYPE_PTRMEMFUNC_P (from)
        {
          conv = build_conv (ck_std, to, conv);
          if (fcode == POINTER_TYPE
              || TYPE_PTRMEM_P (from)
              || (TYPE_PTRMEMFUNC_P (from)
-                 && conv->rank < cr_pbool))
+                 && conv->rank < cr_pbool)
+             || NULLPTR_TYPE_P (from))
            conv->rank = cr_pbool;
          return conv;
        }
            conv->rank = cr_pbool;
          return conv;
        }
@@ -1039,60 +1053,35 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
 
   t = TREE_TYPE (reference_type);
 
 
   t = TREE_TYPE (reference_type);
 
+  /* We're performing a user-defined conversion to a desired type, so set
+     this for the benefit of add_candidates.  */
+  flags |= LOOKUP_NO_CONVERSION;
+
   for (; conversions; conversions = TREE_CHAIN (conversions))
     {
       tree fns = TREE_VALUE (conversions);
   for (; conversions; conversions = TREE_CHAIN (conversions))
     {
       tree fns = TREE_VALUE (conversions);
+      tree binfo = TREE_PURPOSE (conversions);
+      struct z_candidate *old_candidates = candidates;;
 
 
-      for (; fns; fns = OVL_NEXT (fns))
+      add_candidates (fns, first_arg, NULL, reference_type,
+                     NULL_TREE, false,
+                     binfo, TYPE_BINFO (s),
+                     flags, &candidates);
+
+      for (cand = candidates; cand != old_candidates; cand = cand->next)
        {
        {
-         tree f = OVL_CURRENT (fns);
+         /* Now, see if the conversion function really returns
+            an lvalue of the appropriate type.  From the
+            point of view of unification, simply returning an
+            rvalue of the right type is good enough.  */
+         tree f = cand->fn;
          tree t2 = TREE_TYPE (TREE_TYPE (f));
          tree t2 = TREE_TYPE (TREE_TYPE (f));
-
-         if (DECL_NONCONVERTING_P (f)
-             && (flags & LOOKUP_ONLYCONVERTING))
-           continue;
-
-         cand = NULL;
-
-         /* If this is a template function, try to get an exact
-            match.  */
-         if (TREE_CODE (f) == TEMPLATE_DECL)
+         if (TREE_CODE (t2) != REFERENCE_TYPE
+             || !reference_compatible_p (t, TREE_TYPE (t2)))
            {
            {
-             cand = add_template_candidate (&candidates,
-                                            f, s,
-                                            NULL_TREE,
-                                            first_arg,
-                                            NULL,
-                                            reference_type,
-                                            TYPE_BINFO (s),
-                                            TREE_PURPOSE (conversions),
-                                            LOOKUP_NORMAL,
-                                            DEDUCE_CONV);
-
-             if (cand)
-               {
-                 /* Now, see if the conversion function really returns
-                    an lvalue of the appropriate type.  From the
-                    point of view of unification, simply returning an
-                    rvalue of the right type is good enough.  */
-                 f = cand->fn;
-                 t2 = TREE_TYPE (TREE_TYPE (f));
-                 if (TREE_CODE (t2) != REFERENCE_TYPE
-                     || !reference_compatible_p (t, TREE_TYPE (t2)))
-                   {
-                     candidates = candidates->next;
-                     cand = NULL;
-                   }
-               }
+             cand->viable = 0;
            }
            }
-         else if (TREE_CODE (t2) == REFERENCE_TYPE
-                  && reference_compatible_p (t, TREE_TYPE (t2)))
-           cand = add_function_candidate (&candidates, f, s, first_arg,
-                                          NULL, TYPE_BINFO (s),
-                                          TREE_PURPOSE (conversions),
-                                          LOOKUP_NORMAL);
-
-         if (cand)
+         else
            {
              conversion *identity_conv;
              /* Build a standard conversion sequence indicating the
            {
              conversion *identity_conv;
              /* Build a standard conversion sequence indicating the
@@ -2259,6 +2248,8 @@ type_decays_to (tree type)
     return build_pointer_type (TREE_TYPE (type));
   if (TREE_CODE (type) == FUNCTION_TYPE)
     return build_pointer_type (type);
     return build_pointer_type (TREE_TYPE (type));
   if (TREE_CODE (type) == FUNCTION_TYPE)
     return build_pointer_type (type);
+  if (!MAYBE_CLASS_TYPE_P (type))
+    type = cv_unqualified (type);
   return type;
 }
 
   return type;
 }
 
@@ -2517,11 +2508,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
                           return_type, strict, flags);
 
   if (i != 0)
                           return_type, strict, flags);
 
   if (i != 0)
-    return NULL;
+    goto fail;
 
   fn = instantiate_template (tmpl, targs, tf_none);
   if (fn == error_mark_node)
 
   fn = instantiate_template (tmpl, targs, tf_none);
   if (fn == error_mark_node)
-    return NULL;
+    goto fail;
 
   /* In [class.copy]:
 
 
   /* In [class.copy]:
 
@@ -2550,7 +2541,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
       tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
       if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
                                    ctype))
       tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
       if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
                                    ctype))
-       return NULL;
+       goto fail;
     }
 
   if (obj != NULL_TREE)
     }
 
   if (obj != NULL_TREE)
@@ -2584,6 +2575,9 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
     cand->template_decl = DECL_TEMPLATE_INFO (fn);
 
   return cand;
     cand->template_decl = DECL_TEMPLATE_INFO (fn);
 
   return cand;
+ fail:
+  return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL,
+                       access_path, conversion_path, 0);
 }
 
 
 }
 
 
@@ -2616,10 +2610,10 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
 }
 
 /* The CANDS are the set of candidates that were considered for
 }
 
 /* The CANDS are the set of candidates that were considered for
-   overload resolution.  Return the set of viable candidates.  If none
-   of the candidates were viable, set *ANY_VIABLE_P to true.  STRICT_P
-   is true if a candidate should be considered viable only if it is
-   strictly viable.  */
+   overload resolution.  Return the set of viable candidates, or CANDS
+   if none are viable.  If any of the candidates were viable, set
+   *ANY_VIABLE_P to true.  STRICT_P is true if a candidate should be
+   considered viable only if it is strictly viable.  */
 
 static struct z_candidate*
 splice_viable (struct z_candidate *cands,
 
 static struct z_candidate*
 splice_viable (struct z_candidate *cands,
@@ -2684,6 +2678,10 @@ build_this (tree obj)
 static inline int
 equal_functions (tree fn1, tree fn2)
 {
 static inline int
 equal_functions (tree fn1, tree fn2)
 {
+  if (TREE_CODE (fn1) != TREE_CODE (fn2))
+    return 0;
+  if (TREE_CODE (fn1) == TEMPLATE_DECL)
+    return fn1 == fn2;
   if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
       || DECL_EXTERN_C_FUNCTION_P (fn1))
     return decls_match (fn1, fn2);
   if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
       || DECL_EXTERN_C_FUNCTION_P (fn1))
     return decls_match (fn1, fn2);
@@ -2719,7 +2717,7 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
     inform (input_location, "%s %T <conversion>", msgstr, candidate->fn);
   else if (candidate->viable == -1)
     inform (input_location, "%s %+#D <near match>", msgstr, candidate->fn);
     inform (input_location, "%s %T <conversion>", msgstr, candidate->fn);
   else if (candidate->viable == -1)
     inform (input_location, "%s %+#D <near match>", msgstr, candidate->fn);
-  else if (DECL_DELETED_FN (candidate->fn))
+  else if (DECL_DELETED_FN (STRIP_TEMPLATE (candidate->fn)))
     inform (input_location, "%s %+#D <deleted>", msgstr, candidate->fn);
   else
     inform (input_location, "%s %+#D", msgstr, candidate->fn);
     inform (input_location, "%s %+#D <deleted>", msgstr, candidate->fn);
   else
     inform (input_location, "%s %+#D", msgstr, candidate->fn);
@@ -2759,12 +2757,12 @@ print_z_candidates (struct z_candidate *candidates)
     {
       tree fn = cand1->fn;
       /* Skip builtin candidates and conversion functions.  */
     {
       tree fn = cand1->fn;
       /* Skip builtin candidates and conversion functions.  */
-      if (TREE_CODE (fn) != FUNCTION_DECL)
+      if (!DECL_P (fn))
        continue;
       cand2 = &cand1->next;
       while (*cand2)
        {
        continue;
       cand2 = &cand1->next;
       while (*cand2)
        {
-         if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+         if (DECL_P ((*cand2)->fn)
              && equal_functions (fn, (*cand2)->fn))
            *cand2 = (*cand2)->next;
          else
              && equal_functions (fn, (*cand2)->fn))
            *cand2 = (*cand2)->next;
          else
@@ -2858,6 +2856,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
 
   candidates = 0;
   flags |= LOOKUP_NO_CONVERSION;
 
   candidates = 0;
   flags |= LOOKUP_NO_CONVERSION;
+  if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+    flags |= LOOKUP_NO_NARROWING;
 
   /* It's OK to bind a temporary for converting constructor arguments, but
      not in converting the return value of a conversion operator.  */
 
   /* It's OK to bind a temporary for converting constructor arguments, but
      not in converting the return value of a conversion operator.  */
@@ -2866,48 +2866,56 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
 
   if (ctors)
     {
 
   if (ctors)
     {
+      int ctorflags = flags;
+      bool try_single_arg = true;
       ctors = BASELINK_FUNCTIONS (ctors);
 
       first_arg = build_int_cst (build_pointer_type (totype), 0);
       ctors = BASELINK_FUNCTIONS (ctors);
 
       first_arg = build_int_cst (build_pointer_type (totype), 0);
-      if (BRACE_ENCLOSED_INITIALIZER_P (expr)
-         && !TYPE_HAS_LIST_CTOR (totype))
+      if (BRACE_ENCLOSED_INITIALIZER_P (expr))
        {
        {
-         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);
+         /* For list-initialization we consider explicit constructors, but
+            give an error if one is selected.  */
+         ctorflags &= ~LOOKUP_ONLYCONVERTING;
+         /* If the class has a list ctor, try passing the list as a single
+            argument first, but only consider list ctors.  */
+         if (TYPE_HAS_LIST_CTOR (totype))
+           ctorflags |= LOOKUP_LIST_ONLY;
+         else
+           try_single_arg = false;
        }
        }
-      else
-       args = 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)));
 
       /* 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)));
-    }
-  for (; ctors; ctors = OVL_NEXT (ctors))
-    {
-      tree ctor = OVL_CURRENT (ctors);
-      if (DECL_NONCONVERTING_P (ctor)
-         && !BRACE_ENCLOSED_INITIALIZER_P (expr))
-       continue;
 
 
-      if (TREE_CODE (ctor) == TEMPLATE_DECL)
-       cand = add_template_candidate (&candidates, ctor, totype,
-                                      NULL_TREE, first_arg, args, NULL_TREE,
-                                      TYPE_BINFO (totype),
-                                      TYPE_BINFO (totype),
-                                      flags,
-                                      DEDUCE_CALL);
-      else
-       cand = add_function_candidate (&candidates, ctor, totype,
-                                      first_arg, args, TYPE_BINFO (totype),
-                                      TYPE_BINFO (totype),
-                                      flags);
+      /* If EXPR is not an initializer-list, or if totype has a list
+        constructor, try EXPR as a single argument.  */
+      if (try_single_arg)
+       {
+         args = make_tree_vector_single (expr);
+         add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
+                         TYPE_BINFO (totype), TYPE_BINFO (totype),
+                         ctorflags, &candidates);
+       }
 
 
-      if (cand)
+      /* If we didn't find a suitable list constructor for an initializer-list,
+        try breaking it apart.  */
+      if (!candidates && BRACE_ENCLOSED_INITIALIZER_P (expr))
+       {
+         args = ctor_to_vec (expr);
+         /* We aren't looking for list-ctors anymore.  */
+         ctorflags &= ~LOOKUP_LIST_ONLY;
+         /* We still allow more conversions within an init-list.  */
+         ctorflags &= ~LOOKUP_NO_CONVERSION;
+         /* But not for the copy ctor.  */
+         ctorflags |= LOOKUP_NO_COPY_CTOR_CONVERSION;
+         add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
+                         TYPE_BINFO (totype), TYPE_BINFO (totype),
+                         ctorflags, &candidates);
+       }
+
+      for (cand = candidates; cand; cand = cand->next)
        {
          cand->second_conv = build_identity_conv (totype, NULL_TREE);
 
        {
          cand->second_conv = build_identity_conv (totype, NULL_TREE);
 
@@ -2931,8 +2939,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
 
   for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
     {
 
   for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
     {
-      tree fns;
       tree conversion_path = TREE_PURPOSE (conv_fns);
       tree conversion_path = TREE_PURPOSE (conv_fns);
+      struct z_candidate *old_candidates;
 
       /* If we are called to convert to a reference type, we are trying to
         find an lvalue binding, so don't even consider temporaries.  If
 
       /* 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
@@ -2941,70 +2949,40 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
       if (TREE_CODE (totype) == REFERENCE_TYPE)
        convflags |= LOOKUP_NO_TEMP_BIND;
 
       if (TREE_CODE (totype) == REFERENCE_TYPE)
        convflags |= LOOKUP_NO_TEMP_BIND;
 
-      for (fns = TREE_VALUE (conv_fns); fns; fns = OVL_NEXT (fns))
+      old_candidates = candidates;
+      add_candidates (TREE_VALUE (conv_fns), first_arg, NULL, totype,
+                     NULL_TREE, false,
+                     conversion_path, TYPE_BINFO (fromtype),
+                     flags, &candidates);
+
+      for (cand = candidates; cand != old_candidates; cand = cand->next)
        {
        {
-         tree fn = OVL_CURRENT (fns);
-         tree first = first_arg;
-
-         if (DECL_NONCONVERTING_P (fn)
-             && (flags & LOOKUP_ONLYCONVERTING))
-           continue;
-
-         /* Lambdas have a static conversion op.  */
-         if (DECL_STATIC_FUNCTION_P (fn))
-           first = NULL_TREE;
-
-         /* [over.match.funcs] For conversion functions, the function
-            is considered to be a member of the class of the implicit
-            object argument for the purpose of defining the type of
-            the implicit object parameter.
-
-            So we pass fromtype as CTYPE to add_*_candidate.  */
-
-         if (TREE_CODE (fn) == TEMPLATE_DECL)
-           cand = add_template_candidate (&candidates, fn, fromtype,
-                                          NULL_TREE,
-                                          first, NULL, totype,
-                                          TYPE_BINFO (fromtype),
-                                          conversion_path,
-                                          flags,
-                                          DEDUCE_CONV);
-         else
-           cand = add_function_candidate (&candidates, fn, fromtype,
-                                          first, NULL,
-                                          TYPE_BINFO (fromtype),
-                                          conversion_path,
-                                          flags);
+         conversion *ics
+           = implicit_conversion (totype,
+                                  TREE_TYPE (TREE_TYPE (cand->fn)),
+                                  0,
+                                  /*c_cast_p=*/false, convflags);
 
 
-         if (cand)
-           {
-             conversion *ics
-               = implicit_conversion (totype,
-                                      TREE_TYPE (TREE_TYPE (cand->fn)),
-                                      0,
-                                      /*c_cast_p=*/false, convflags);
-
-             /* If LOOKUP_NO_TEMP_BIND isn't set, then this is
-                copy-initialization.  In that case, "The result of the
-                call is then used to direct-initialize the object that is
-                the destination of the copy-initialization."  [dcl.init]
-
-                We represent this in the conversion sequence with an
-                rvalue conversion, which means a constructor call.  But
-                don't add a second rvalue conversion if there's already
-                one there.  Which there really shouldn't be, but it's
-                harmless since we'd add it here anyway. */
-             if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue
-                 && !(convflags & LOOKUP_NO_TEMP_BIND))
-               ics = build_conv (ck_rvalue, totype, ics);
-
-             cand->second_conv = ics;
-
-             if (!ics)
-               cand->viable = 0;
-             else if (candidates->viable == 1 && ics->bad_p)
-               cand->viable = -1;
-           }
+         /* If LOOKUP_NO_TEMP_BIND isn't set, then this is
+            copy-initialization.  In that case, "The result of the
+            call is then used to direct-initialize the object that is
+            the destination of the copy-initialization."  [dcl.init]
+
+            We represent this in the conversion sequence with an
+            rvalue conversion, which means a constructor call.  But
+            don't add a second rvalue conversion if there's already
+            one there.  Which there really shouldn't be, but it's
+            harmless since we'd add it here anyway. */
+         if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue
+             && !(convflags & LOOKUP_NO_TEMP_BIND))
+           ics = build_conv (ck_rvalue, totype, ics);
+
+         cand->second_conv = ics;
+
+         if (!ics)
+           cand->viable = 0;
+         else if (cand->viable == 1 && ics->bad_p)
+           cand->viable = -1;
        }
     }
 
        }
     }
 
@@ -3134,7 +3112,8 @@ perform_overload_resolution (tree fn,
     }
 
   /* Add the various candidate functions.  */
     }
 
   /* Add the various candidate functions.  */
-  add_candidates (fn, args, explicit_targs, template_only,
+  add_candidates (fn, NULL_TREE, args, NULL_TREE,
+                 explicit_targs, template_only,
                  /*conversion_path=*/NULL_TREE,
                  /*access_path=*/NULL_TREE,
                  LOOKUP_NORMAL,
                  /*conversion_path=*/NULL_TREE,
                  /*access_path=*/NULL_TREE,
                  LOOKUP_NORMAL,
@@ -3195,7 +3174,8 @@ build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p,
     {
       if (complain & tf_error)
        {
     {
       if (complain & tf_error)
        {
-         if (!any_viable_p && candidates && ! candidates->next)
+         if (!any_viable_p && candidates && ! candidates->next
+             && (TREE_CODE (candidates->fn) == FUNCTION_DECL))
            return cp_build_function_call_vec (candidates->fn, args, complain);
          if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
            fn = TREE_OPERAND (fn, 0);
            return cp_build_function_call_vec (candidates->fn, args, complain);
          if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
            fn = TREE_OPERAND (fn, 0);
@@ -3372,36 +3352,16 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
 
   if (fns)
     {
 
   if (fns)
     {
-      tree base = BINFO_TYPE (BASELINK_BINFO (fns));
       first_mem_arg = build_this (obj);
 
       first_mem_arg = build_this (obj);
 
-      for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
-       {
-         tree fn = OVL_CURRENT (fns);
-
-         tree lfirst = first_mem_arg;
-         if (DECL_STATIC_FUNCTION_P (fn))
-           lfirst = NULL_TREE;
-
-         if (TREE_CODE (fn) == TEMPLATE_DECL)
-           add_template_candidate (&candidates, fn, base, NULL_TREE,
-                                   lfirst, *args, NULL_TREE,
-                                   TYPE_BINFO (type),
-                                   TYPE_BINFO (type),
-                                   LOOKUP_NORMAL, DEDUCE_CALL);
-         else
-           add_function_candidate
-             (&candidates, fn, base, lfirst, *args, TYPE_BINFO (type),
-              TYPE_BINFO (type), LOOKUP_NORMAL);
-       }
+      add_candidates (BASELINK_FUNCTIONS (fns),
+                     first_mem_arg, *args, NULL_TREE,
+                     NULL_TREE, false,
+                     BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns),
+                     LOOKUP_NORMAL, &candidates);
     }
 
     }
 
-  /* Rather than mess with handling static conversion ops here, just don't
-     look at conversions in lambdas.  */
-  if (LAMBDA_TYPE_P (type))
-    convs = NULL_TREE;
-  else
-    convs = lookup_conversions (type, /*lookup_template_convs_p=*/true);
+  convs = lookup_conversions (type, /*lookup_template_convs_p=*/true);
 
   for (; convs; convs = TREE_CHAIN (convs))
     {
 
   for (; convs; convs = TREE_CHAIN (convs))
     {
@@ -4056,53 +4016,101 @@ 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
 
 /* 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.  This may change ARGS.  The
+   CANDIDATES.  The ARGS are the arguments provided to the call;
+   if FIRST_ARG is non-null it is the implicit object argument,
+   otherwise the first element of ARGS is used if needed.  The
    EXPLICIT_TARGS are explicit template arguments provided.
    TEMPLATE_ONLY is true if only template functions should be
    considered.  CONVERSION_PATH, ACCESS_PATH, and FLAGS are as for
    add_function_candidate.  */
 
 static void
    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, const VEC(tree,gc) *args,
+add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
+               tree return_type,
                tree explicit_targs, bool template_only,
                tree conversion_path, tree access_path,
                int flags,
                struct z_candidate **candidates)
 {
   tree ctype;
                tree explicit_targs, bool template_only,
                tree conversion_path, tree access_path,
                int flags,
                struct z_candidate **candidates)
 {
   tree ctype;
-  VEC(tree,gc) *non_static_args;
-  tree first_arg;
+  const VEC(tree,gc) *non_static_args;
+  bool check_list_ctor;
+  bool check_converting;
+  unification_kind_t strict;
+  tree fn;
+
+  if (!fns)
+    return;
+
+  /* Precalculate special handling of constructors and conversion ops.  */
+  fn = OVL_CURRENT (fns);
+  if (DECL_CONV_FN_P (fn))
+    {
+      check_list_ctor = false;
+      check_converting = !!(flags & LOOKUP_ONLYCONVERTING);
+      if (flags & LOOKUP_NO_CONVERSION)
+       /* We're doing return_type(x).  */
+       strict = DEDUCE_CONV;
+      else
+       /* We're doing x.operator return_type().  */
+       strict = DEDUCE_EXACT;
+      /* [over.match.funcs] For conversion functions, the function
+        is considered to be a member of the class of the implicit
+        object argument for the purpose of defining the type of
+        the implicit object parameter.  */
+      ctype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (first_arg)));
+    }
+  else
+    {
+      if (DECL_CONSTRUCTOR_P (fn))
+       {
+         check_list_ctor = !!(flags & LOOKUP_LIST_ONLY);
+         check_converting = !!(flags & LOOKUP_ONLYCONVERTING);
+       }
+      else
+       {
+         check_list_ctor = false;
+         check_converting = false;
+       }
+      strict = DEDUCE_CALL;
+      ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
+    }
 
 
-  ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
-  /* Delay creating the implicit this parameter until it is needed.  */
-  non_static_args = NULL;
-  first_arg = NULL_TREE;
+  if (first_arg)
+    non_static_args = args;
+  else
+    /* Delay creating the implicit this parameter until it is needed.  */
+    non_static_args = NULL;
 
 
-  while (fns)
+  for (; fns; fns = OVL_NEXT (fns))
     {
     {
-      tree fn;
       tree fn_first_arg;
       const VEC(tree,gc) *fn_args;
 
       fn = OVL_CURRENT (fns);
       tree fn_first_arg;
       const VEC(tree,gc) *fn_args;
 
       fn = OVL_CURRENT (fns);
+
+      if (check_converting && DECL_NONCONVERTING_P (fn))
+       continue;
+      if (check_list_ctor && !is_list_ctor (fn))
+       continue;
+
       /* Figure out which set of arguments to use.  */
       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
        {
       /* Figure out which set of arguments to use.  */
       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
        {
-         /* If this function is a non-static member, prepend the implicit
-            object parameter.  */
-         if (non_static_args == NULL)
+         /* If this function is a non-static member and we didn't get an
+            implicit object argument, move it out of args.  */
+         if (first_arg == NULL_TREE)
            {
              unsigned int ix;
              tree arg;
            {
              unsigned int ix;
              tree arg;
-
-             non_static_args = VEC_alloc (tree, gc,
-                                          VEC_length (tree, args) - 1);
+             VEC(tree,gc) *tempvec
+               = VEC_alloc (tree, gc, VEC_length (tree, args) - 1);
              for (ix = 1; VEC_iterate (tree, args, ix, arg); ++ix)
              for (ix = 1; VEC_iterate (tree, args, ix, arg); ++ix)
-               VEC_quick_push (tree, non_static_args, arg);
+               VEC_quick_push (tree, tempvec, arg);
+             non_static_args = tempvec;
+             first_arg = build_this (VEC_index (tree, args, 0));
            }
            }
-         if (first_arg == NULL_TREE)
-           first_arg = build_this (VEC_index (tree, args, 0));
+
          fn_first_arg = first_arg;
          fn_args = non_static_args;
        }
          fn_first_arg = first_arg;
          fn_args = non_static_args;
        }
@@ -4120,11 +4128,11 @@ add_candidates (tree fns, const VEC(tree,gc) *args,
                                explicit_targs,
                                fn_first_arg, 
                                fn_args,
                                explicit_targs,
                                fn_first_arg, 
                                fn_args,
-                               NULL_TREE,
+                               return_type,
                                access_path,
                                conversion_path,
                                flags,
                                access_path,
                                conversion_path,
                                flags,
-                               DEDUCE_CALL);
+                               strict);
       else if (!template_only)
        add_function_candidate (candidates,
                                fn,
       else if (!template_only)
        add_function_candidate (candidates,
                                fn,
@@ -4134,7 +4142,6 @@ add_candidates (tree fns, const VEC(tree,gc) *args,
                                access_path,
                                conversion_path,
                                flags);
                                access_path,
                                conversion_path,
                                flags);
-      fns = OVL_NEXT (fns);
     }
 }
 
     }
 }
 
@@ -4245,7 +4252,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
   /* Add namespace-scope operators to the list of functions to
      consider.  */
   add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true),
   /* Add namespace-scope operators to the list of functions to
      consider.  */
   add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true),
-                 arglist, NULL_TREE, false, NULL_TREE, NULL_TREE,
+                 NULL_TREE, arglist, NULL_TREE,
+                 NULL_TREE, false, NULL_TREE, NULL_TREE,
                  flags, &candidates);
   /* Add class-member operators to the candidate set.  */
   if (CLASS_TYPE_P (TREE_TYPE (arg1)))
                  flags, &candidates);
   /* Add class-member operators to the candidate set.  */
   if (CLASS_TYPE_P (TREE_TYPE (arg1)))
@@ -4259,10 +4267,11 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          goto user_defined_result_ready;
        }
       if (fns)
          goto user_defined_result_ready;
        }
       if (fns)
-       add_candidates (BASELINK_FUNCTIONS (fns), arglist,
+       add_candidates (BASELINK_FUNCTIONS (fns),
+                       NULL_TREE, arglist, NULL_TREE,
                        NULL_TREE, false,
                        BASELINK_BINFO (fns),
                        NULL_TREE, false,
                        BASELINK_BINFO (fns),
-                       TYPE_BINFO (TREE_TYPE (arg1)),
+                       BASELINK_ACCESS_BINFO (fns),
                        flags, &candidates);
     }
 
                        flags, &candidates);
     }
 
@@ -4508,7 +4517,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       return cp_build_unary_op (code, arg1, candidates != 0, complain);
 
     case ARRAY_REF:
       return cp_build_unary_op (code, arg1, candidates != 0, complain);
 
     case ARRAY_REF:
-      return build_array_ref (input_location, arg1, arg2);
+      return cp_build_array_ref (input_location, arg1, arg2, complain);
 
     case MEMBER_REF:
       return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL, 
 
     case MEMBER_REF:
       return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL, 
@@ -4804,17 +4813,19 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
   if (expr == null_node && TREE_CODE (t) != BOOLEAN_TYPE && ARITHMETIC_TYPE_P (t))
     {
       if (fn)
   if (expr == null_node && TREE_CODE (t) != BOOLEAN_TYPE && ARITHMETIC_TYPE_P (t))
     {
       if (fn)
-       warning (OPT_Wconversion, "passing NULL to non-pointer argument %P of %qD",
-                argnum, fn);
+       warning_at (input_location, OPT_Wconversion_null,
+                   "passing NULL to non-pointer argument %P of %qD",
+                   argnum, fn);
       else
       else
-       warning (OPT_Wconversion, "converting to non-pointer type %qT from NULL", t);
+       warning_at (input_location, OPT_Wconversion_null,
+                   "converting to non-pointer type %qT from NULL", t);
     }
 
   /* Issue warnings if "false" is converted to a NULL pointer */
   else if (expr == boolean_false_node && fn && POINTER_TYPE_P (t))
     }
 
   /* Issue warnings if "false" is converted to a NULL pointer */
   else if (expr == boolean_false_node && fn && POINTER_TYPE_P (t))
-    warning (OPT_Wconversion,
-            "converting %<false%> to pointer type for argument %P of %qD",
-            argnum, fn);
+    warning_at (input_location, OPT_Wconversion_null,
+               "converting %<false%> to pointer type for argument %P of %qD",
+               argnum, fn);
 }
 
 /* Perform the conversions in CONVS on the expression EXPR.  FN and
 }
 
 /* Perform the conversions in CONVS on the expression EXPR.  FN and
@@ -4894,6 +4905,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        tree convfn = cand->fn;
        unsigned i;
 
        tree convfn = cand->fn;
        unsigned i;
 
+       expr = mark_rvalue_use (expr);
+
        /* When converting from an init list we consider explicit
           constructors, but actually trying to call one is an error.  */
        if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn))
        /* 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))
@@ -4926,6 +4939,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        return expr;
       }
     case ck_identity:
        return expr;
       }
     case ck_identity:
+      expr = mark_rvalue_use (expr);
       if (BRACE_ENCLOSED_INITIALIZER_P (expr))
        {
          int nelts = CONSTRUCTOR_NELTS (expr);
       if (BRACE_ENCLOSED_INITIALIZER_P (expr))
        {
          int nelts = CONSTRUCTOR_NELTS (expr);
@@ -4953,6 +4967,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
         }
       return expr;
     case ck_ambig:
         }
       return expr;
     case ck_ambig:
+      if (!(complain & tf_error))
+       return error_mark_node;
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
        (totype, convs->u.expr, LOOKUP_NORMAL);
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
        (totype, convs->u.expr, LOOKUP_NORMAL);
@@ -5013,7 +5029,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
   switch (convs->kind)
     {
     case ck_rvalue:
   switch (convs->kind)
     {
     case ck_rvalue:
-      expr = convert_bitfield_to_declared_type (expr);
+      expr = decay_conversion (expr);
       if (! MAYBE_CLASS_TYPE_P (totype))
        return expr;
       /* Else fall through.  */
       if (! MAYBE_CLASS_TYPE_P (totype))
        return expr;
       /* Else fall through.  */
@@ -5025,7 +5041,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
          /* Build an expression for `*((base*) &expr)'.  */
          expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
          expr = convert_to_base (expr, build_pointer_type (totype),
          /* Build an expression for `*((base*) &expr)'.  */
          expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
          expr = convert_to_base (expr, build_pointer_type (totype),
-                                 !c_cast_p, /*nonnull=*/true);
+                                 !c_cast_p, /*nonnull=*/true, complain);
          expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
          return expr;
        }
          expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
          return expr;
        }
@@ -5148,7 +5164,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     case ck_ptr:
       if (convs->base_p)
        expr = convert_to_base (expr, totype, !c_cast_p,
     case ck_ptr:
       if (convs->base_p)
        expr = convert_to_base (expr, totype, !c_cast_p,
-                               /*nonnull=*/false);
+                               /*nonnull=*/false, complain);
       return build_nop (totype, expr);
 
     case ck_pmem:
       return build_nop (totype, expr);
 
     case ck_pmem:
@@ -5193,6 +5209,8 @@ convert_arg_to_ellipsis (tree arg)
          < TYPE_PRECISION (double_type_node))
       && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (arg))))
     arg = convert_to_real (double_type_node, arg);
          < TYPE_PRECISION (double_type_node))
       && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (arg))))
     arg = convert_to_real (double_type_node, arg);
+  else if (NULLPTR_TYPE_P (TREE_TYPE (arg)))
+    arg = null_pointer_node;
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
     arg = perform_integral_promotions (arg);
 
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
     arg = perform_integral_promotions (arg);
 
@@ -5234,6 +5252,8 @@ build_x_va_arg (tree expr, tree type)
   if (expr == error_mark_node || !type)
     return error_mark_node;
 
   if (expr == error_mark_node || !type)
     return error_mark_node;
 
+  expr = mark_lvalue_use (expr);
+
   if (type_has_nontrivial_copy_init (type)
       || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
       || TREE_CODE (type) == REFERENCE_TYPE)
   if (type_has_nontrivial_copy_init (type)
       || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
       || TREE_CODE (type) == REFERENCE_TYPE)
@@ -5646,6 +5666,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        parm = TREE_CHAIN (parm), ++arg_index, ++i)
     {
       tree type = TREE_VALUE (parm);
        parm = TREE_CHAIN (parm), ++arg_index, ++i)
     {
       tree type = TREE_VALUE (parm);
+      tree arg = VEC_index (tree, args, arg_index);
 
       conv = convs[i];
 
 
       conv = convs[i];
 
@@ -5660,7 +5681,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       if (cxx_dialect > cxx98
          && flag_deduce_init_list
          && cand->template_decl
       if (cxx_dialect > cxx98
          && flag_deduce_init_list
          && cand->template_decl
-         && is_std_init_list (non_reference (type)))
+         && is_std_init_list (non_reference (type))
+         && BRACE_ENCLOSED_INITIALIZER_P (arg))
        {
          tree tmpl = TI_TEMPLATE (cand->template_decl);
          tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn));
        {
          tree tmpl = TI_TEMPLATE (cand->template_decl);
          tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn));
@@ -5681,9 +5703,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
            }
        }
 
            }
        }
 
-      val = convert_like_with_context
-       (conv, VEC_index (tree, args, arg_index), fn, i - is_method,
-        complain);
+      val = convert_like_with_context (conv, arg, fn, i-is_method, complain);
 
       val = convert_for_arg_passing (type, val);
       if (val == error_mark_node)
 
       val = convert_for_arg_passing (type, val);
       if (val == error_mark_node)
@@ -5702,7 +5722,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
     {
       tree a = VEC_index (tree, args, arg_index);
       if (magic_varargs_p (fn))
     {
       tree a = VEC_index (tree, args, arg_index);
       if (magic_varargs_p (fn))
-       /* Do no conversions for magic varargs.  */;
+       /* Do no conversions for magic varargs.  */
+       a = mark_type_use (a);
       else
        a = convert_arg_to_ellipsis (a);
       argarray[j++] = a;
       else
        a = convert_arg_to_ellipsis (a);
       argarray[j++] = a;
@@ -5755,7 +5776,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        }
       /* [class.copy]: the copy constructor is implicitly defined even if
         the implementation elided its use.  */
        }
       /* [class.copy]: the copy constructor is implicitly defined even if
         the implementation elided its use.  */
-      else if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
+      else if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn))
+              || move_fn_p (fn))
        {
          mark_used (fn);
          already_used = true;
        {
          mark_used (fn);
          already_used = true;
@@ -5773,7 +5795,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        {
          if (TREE_CODE (arg) == TARGET_EXPR)
            return arg;
        {
          if (TREE_CODE (arg) == TARGET_EXPR)
            return arg;
-         else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
+         else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))
+                  && !move_fn_p (fn))
            return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
        }
       else if (TREE_CODE (arg) == TARGET_EXPR
            return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
        }
       else if (TREE_CODE (arg) == TARGET_EXPR
@@ -5797,7 +5820,15 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       tree as_base = CLASSTYPE_AS_BASE (type);
       tree arg = argarray[1];
 
       tree as_base = CLASSTYPE_AS_BASE (type);
       tree arg = argarray[1];
 
-      if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+      if (is_really_empty_class (type))
+       {
+         /* Avoid copying empty classes.  */
+         val = build2 (COMPOUND_EXPR, void_type_node, to, arg);
+         TREE_NO_WARNING (val) = 1;
+         val = build2 (COMPOUND_EXPR, type, val, to);
+         TREE_NO_WARNING (val) = 1;
+       }
+      else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
        {
          arg = cp_build_indirect_ref (arg, RO_NULL, complain);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
        {
          arg = cp_build_indirect_ref (arg, RO_NULL, complain);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
@@ -6188,13 +6219,14 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
   VEC(tree,gc) *user_args;
   tree call;
   tree fn;
   VEC(tree,gc) *user_args;
   tree call;
   tree fn;
-  tree class_type;
   int template_only = 0;
   bool any_viable_p;
   tree orig_instance;
   tree orig_fns;
   VEC(tree,gc) *orig_args = NULL;
   void *p;
   int template_only = 0;
   bool any_viable_p;
   tree orig_instance;
   tree orig_fns;
   VEC(tree,gc) *orig_args = NULL;
   void *p;
+  tree list = NULL_TREE;
+  bool try_normal;
 
   gcc_assert (instance != NULL_TREE);
 
 
   gcc_assert (instance != NULL_TREE);
 
@@ -6203,7 +6235,7 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
     *fn_p = NULL_TREE;
 
   if (error_operand_p (instance)
     *fn_p = NULL_TREE;
 
   if (error_operand_p (instance)
-      || error_operand_p (fns))
+      || !fns || error_operand_p (fns))
     return error_mark_node;
 
   if (!BASELINK_P (fns))
     return error_mark_node;
 
   if (!BASELINK_P (fns))
@@ -6256,11 +6288,10 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
       permerror (input_location,
                 "cannot call constructor %<%T::%D%> directly",
                 basetype, name);
       permerror (input_location,
                 "cannot call constructor %<%T::%D%> directly",
                 basetype, name);
-      inform (input_location, "for a function-style cast, remove the "
-             "redundant %<::%D%>", name);
+      permerror (input_location, "  for a function-style cast, remove the "
+                "redundant %<::%D%>", name);
       call = build_functional_cast (basetype, build_tree_list_vec (user_args),
                                    complain);
       call = build_functional_cast (basetype, build_tree_list_vec (user_args),
                                    complain);
-      release_tree_vector (user_args);
       return call;
     }
 
       return call;
     }
 
@@ -6308,67 +6339,56 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
     name = complete_dtor_identifier;
 
   /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form
     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.  */
+     initializer, not T({ }).  If the type doesn't have a list ctor (or no
+     viable list ctor), break apart the list into separate ctor args.  */
+  try_normal = true;
   if (DECL_CONSTRUCTOR_P (fn) && args != NULL && !VEC_empty (tree, *args)
       && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *args, 0))
   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))
+      && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0)))
     {
       gcc_assert (VEC_length (tree, *args) == 1);
     {
       gcc_assert (VEC_length (tree, *args) == 1);
-      *args = ctor_to_vec (VEC_index (tree, *args, 0));
+      list = VEC_index (tree, *args, 0);
+
+      if (TYPE_HAS_LIST_CTOR (basetype))
+       flags |= LOOKUP_LIST_ONLY;
+      else
+       try_normal = false;
     }
 
     }
 
-  class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
   first_mem_arg = instance_ptr;
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
   first_mem_arg = instance_ptr;
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
-  for (fn = fns; fn; fn = OVL_NEXT (fn))
+  any_viable_p = false;
+  if (try_normal)
     {
     {
-      tree t = OVL_CURRENT (fn);
-      tree this_first_arg;
-
-      /* We can end up here for copy-init of same or base class.  */
-      if ((flags & LOOKUP_ONLYCONVERTING)
-         && DECL_NONCONVERTING_P (t))
-       continue;
-
-      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
-       this_first_arg = first_mem_arg;
-      else
-       this_first_arg = NULL_TREE;
+      add_candidates (fns, first_mem_arg, user_args, optype,
+                     explicit_targs, template_only, conversion_path,
+                     access_binfo, flags, &candidates);
+      candidates = splice_viable (candidates, pedantic, &any_viable_p);
+    }
 
 
-      if (TREE_CODE (t) == TEMPLATE_DECL)
-       /* A member template.  */
-       add_template_candidate (&candidates, t,
-                               class_type,
-                               explicit_targs,
-                               this_first_arg,
-                               args == NULL ? NULL : *args,
-                               optype,
-                               access_binfo,
-                               conversion_path,
-                               flags,
-                               DEDUCE_CALL);
-      else if (! template_only)
-       add_function_candidate (&candidates, t,
-                               class_type,
-                               this_first_arg,
-                               args == NULL ? NULL : *args,
-                               access_binfo,
-                               conversion_path,
-                               flags);
+  if (!any_viable_p && list)
+    {
+      VEC(tree,gc) *list_args = ctor_to_vec (list);
+      flags &= ~LOOKUP_LIST_ONLY;
+      add_candidates (fns, first_mem_arg, list_args, optype,
+                     explicit_targs, template_only, conversion_path,
+                     access_binfo, flags, &candidates);
+      candidates = splice_viable (candidates, pedantic, &any_viable_p);
     }
 
     }
 
-  candidates = splice_viable (candidates, pedantic, &any_viable_p);
   if (!any_viable_p)
     {
       if (complain & tf_error)
        {
          if (!COMPLETE_TYPE_P (basetype))
            cxx_incomplete_type_error (instance_ptr, basetype);
   if (!any_viable_p)
     {
       if (complain & tf_error)
        {
          if (!COMPLETE_TYPE_P (basetype))
            cxx_incomplete_type_error (instance_ptr, basetype);
+         else if (optype)
+           error ("no matching function for call to %<%T::operator %T(%A)%#V%>",
+                  basetype, optype, build_tree_list_vec (user_args),
+                  TREE_TYPE (TREE_TYPE (instance_ptr)));
          else
            {
              char *pretty_name;
          else
            {
              char *pretty_name;
@@ -6425,8 +6445,8 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
            /* This is not an error, it is runtime undefined
               behavior.  */
            warning (0, (DECL_CONSTRUCTOR_P (current_function_decl) ?
            /* This is not an error, it is runtime undefined
               behavior.  */
            warning (0, (DECL_CONSTRUCTOR_P (current_function_decl) ?
-                     "abstract virtual %q#D called from constructor"
-                     : "abstract virtual %q#D called from destructor"),
+                     "pure virtual %q#D called from constructor"
+                     : "pure virtual %q#D called from destructor"),
                     fn);
 
          if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
                     fn);
 
          if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
@@ -6779,9 +6799,8 @@ compare_ics (conversion *ics1, conversion *ics2)
     Two conversion sequences with the same rank are indistinguishable
     unless one of the following rules applies:
 
     Two conversion sequences with the same rank are indistinguishable
     unless one of the following rules applies:
 
-    --A conversion that is not a conversion of a pointer, or pointer
-      to member, to bool is better than another conversion that is such
-      a conversion.
+    --A conversion that does not a convert a pointer, pointer to member,
+      or std::nullptr_t to bool is better than one that does.
 
     The ICS_STD_RANK automatically handles the pointer-to-bool rule,
     so that we do not have to check it explicitly.  */
 
     The ICS_STD_RANK automatically handles the pointer-to-bool rule,
     so that we do not have to check it explicitly.  */
@@ -7571,7 +7590,7 @@ perform_direct_initialization_if_possible (tree type,
     expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
                              /*issue_conversion_warnings=*/false,
                              c_cast_p,
     expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
                              /*issue_conversion_warnings=*/false,
                              c_cast_p,
-                             tf_warning_or_error);
+                             complain);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -7797,7 +7816,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup,
                expr = convert_to_base (expr,
                                        build_pointer_type (base_conv_type),
                                        /*check_access=*/true,
                expr = convert_to_base (expr,
                                        build_pointer_type (base_conv_type),
                                        /*check_access=*/true,
-                                       /*nonnull=*/true);
+                                       /*nonnull=*/true, complain);
              expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
            }
          else
              expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
            }
          else