OSDN Git Service

/cp
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 6a7a1b8..157b473 100644 (file)
@@ -144,7 +144,7 @@ static tree build_java_interface_fn_ref (tree, tree);
 static tree convert_like_real (conversion *, tree, tree, int, int, bool,
                               bool, tsubst_flags_t);
 static void op_error (enum tree_code, enum tree_code, tree, tree,
-                     tree, const char *);
+                     tree, bool);
 static VEC(tree,gc) *resolve_args (VEC(tree,gc) *);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
 static void print_z_candidate (const char *, struct z_candidate *);
@@ -190,7 +190,6 @@ static struct z_candidate *add_candidate
         conversion **, tree, tree, int);
 static tree source_type (conversion *);
 static void add_warning (struct z_candidate *, struct z_candidate *);
-static bool reference_related_p (tree, tree);
 static bool reference_compatible_p (tree, tree);
 static conversion *convert_class_to_reference (tree, tree, tree, int);
 static conversion *direct_reference_binding (tree, conversion *);
@@ -314,6 +313,9 @@ build_call_a (tree function, int n, tree *argarray)
   gcc_assert (TREE_CODE (fntype) == FUNCTION_TYPE
              || TREE_CODE (fntype) == METHOD_TYPE);
   result_type = TREE_TYPE (fntype);
+  /* An rvalue has no cv-qualifiers.  */
+  if (SCALAR_TYPE_P (result_type) || VOID_TYPE_P (result_type))
+    result_type = cv_unqualified (result_type);
 
   if (TREE_CODE (function) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
@@ -362,7 +364,8 @@ build_call_a (tree function, int n, tree *argarray)
                                argarray[i], t);
        }
 
-  function = build_call_array (result_type, function, n, argarray);
+  function = build_call_array_loc (input_location,
+                                  result_type, function, n, argarray);
   TREE_HAS_CONSTRUCTOR (function) = is_constructor;
   TREE_NOTHROW (function) = nothrow;
 
@@ -623,23 +626,27 @@ build_aggr_conv (tree type, tree ctor, int flags)
 {
   unsigned HOST_WIDE_INT i = 0;
   conversion *c;
-  tree field = TYPE_FIELDS (type);
+  tree field = next_initializable_field (TYPE_FIELDS (type));
 
-  for (; field; field = TREE_CHAIN (field), ++i)
+  for (; field; field = next_initializable_field (TREE_CHAIN (field)))
     {
-      if (TREE_CODE (field) != FIELD_DECL)
-       continue;
       if (i < CONSTRUCTOR_NELTS (ctor))
        {
          constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i);
          if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value),
                                ce->value, flags))
            return NULL;
+         ++i;
+         if (TREE_CODE (type) == UNION_TYPE)
+           break;
        }
       else if (build_value_init (TREE_TYPE (field)) == error_mark_node)
        return NULL;
     }
 
+  if (i < CONSTRUCTOR_NELTS (ctor))
+    return NULL;
+
   c = alloc_conversion (ck_aggr);
   c->type = type;
   c->rank = cr_exact;
@@ -893,10 +900,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
          || cp_type_quals (fbase) != cp_type_quals (tbase))
        return NULL;
 
-      from = cp_build_qualified_type (tbase, cp_type_quals (fbase));
-      from = build_method_type_directly (from,
-                                        TREE_TYPE (fromfn),
-                                        TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
+      from = build_memfn_type (fromfn, tbase, cp_type_quals (tbase));
       from = build_ptrmemfunc_type (build_pointer_type (from));
       conv = build_conv (ck_pmem, from, conv);
       conv->base_p = true;
@@ -965,7 +969,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
 /* Returns nonzero if T1 is reference-related to T2.  */
 
-static bool
+bool
 reference_related_p (tree t1, tree t2)
 {
   t1 = TYPE_MAIN_VARIANT (t1);
@@ -1009,7 +1013,7 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
   struct z_candidate *cand;
   bool any_viable_p;
 
-  conversions = lookup_conversions (s);
+  conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true);
   if (!conversions)
     return NULL;
 
@@ -1109,6 +1113,11 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
                = TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn)))
                  == TYPE_REF_IS_RVALUE (reference_type);
              cand->second_conv->bad_p |= cand->convs[0]->bad_p;
+
+              /* Don't allow binding of lvalues to rvalue references.  */
+              if (TYPE_REF_IS_RVALUE (reference_type)
+                  && !TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn))))
+                cand->second_conv->bad_p = true;
            }
        }
     }
@@ -1136,13 +1145,13 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
                     build_identity_conv (TREE_TYPE (expr), expr));
   conv->cand = cand;
 
+  if (cand->viable == -1)
+    conv->bad_p = true;
+
   /* Merge it with the standard conversion sequence from the
      conversion function's return type to the desired type.  */
   cand->second_conv = merge_conversion_sequences (conv, cand->second_conv);
 
-  if (cand->viable == -1)
-    conv->bad_p = true;
-
   return cand->second_conv;
 }
 
@@ -1204,7 +1213,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   tree tfrom;
   bool related_p;
   bool compatible_p;
-  cp_lvalue_kind lvalue_p = clk_none;
+  cp_lvalue_kind is_lvalue = clk_none;
 
   if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
     {
@@ -1217,14 +1226,30 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   if (TREE_CODE (from) == REFERENCE_TYPE)
     {
       /* Anything with reference type is an lvalue.  */
-      lvalue_p = clk_ordinary;
+      is_lvalue = clk_ordinary;
       from = TREE_TYPE (from);
     }
-  else if (expr)
-    lvalue_p = real_lvalue_p (expr);
+
+  if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+    {
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+      conv = implicit_conversion (to, from, expr, c_cast_p,
+                                 flags);
+      if (!CLASS_TYPE_P (to)
+         && CONSTRUCTOR_NELTS (expr) == 1)
+       {
+         expr = CONSTRUCTOR_ELT (expr, 0)->value;
+         if (error_operand_p (expr))
+           return NULL;
+         from = TREE_TYPE (expr);
+       }
+    }
+
+  if (is_lvalue == clk_none && expr)
+    is_lvalue = real_lvalue_p (expr);
 
   tfrom = from;
-  if ((lvalue_p & clk_bitfield) != 0)
+  if ((is_lvalue & clk_bitfield) != 0)
     tfrom = unlowered_expr_type (expr);
 
   /* Figure out whether or not the types are reference-related and
@@ -1241,12 +1266,15 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   /* Directly bind reference when target expression's type is compatible with
      the reference and expression is an lvalue. In DR391, the wording in
      [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
-     const and rvalue references to rvalues of compatible class type. */
+     const and rvalue references to rvalues of compatible class type.
+     We should also do direct bindings for non-class "rvalues" derived from
+     rvalue references.  */
   if (compatible_p
-      && (lvalue_p
-         || (!(flags & LOOKUP_NO_TEMP_BIND)
-             && (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto))
-             && CLASS_TYPE_P (from))))
+      && (is_lvalue
+         || (((CP_TYPE_CONST_NON_VOLATILE_P (to)
+               && !(flags & LOOKUP_NO_TEMP_BIND))
+              || TYPE_REF_IS_RVALUE (rto))
+             && (CLASS_TYPE_P (from) || (expr && lvalue_p (expr))))))
     {
       /* [dcl.init.ref]
 
@@ -1273,10 +1301,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
@@ -1290,6 +1318,11 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
           actually occurs.  */
        conv->need_temporary_p = true;
 
+      /* Don't allow binding of lvalues to rvalue references.  */
+      if (is_lvalue && TYPE_REF_IS_RVALUE (rto)
+          && !(flags & LOOKUP_PREFER_RVALUE))
+       conv->bad_p = true;
+
       return conv;
     }
   /* [class.conv.fct] A conversion function is never used to convert a
@@ -1362,8 +1395,9 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   if (!(flags & LOOKUP_COPY_PARM))
     flags |= LOOKUP_ONLYCONVERTING;
 
-  conv = implicit_conversion (to, from, expr, c_cast_p,
-                             flags);
+  if (!conv)
+    conv = implicit_conversion (to, from, expr, c_cast_p,
+                               flags);
   if (!conv)
     return NULL;
 
@@ -1603,7 +1637,8 @@ add_function_candidate (struct z_candidate **candidates,
              parmtype = build_pointer_type (parmtype);
            }
 
-         if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn))
+         if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn)
+             && (len-skip == 1))
            {
              /* Hack: Direct-initialize copy parm (i.e. suppress
                 LOOKUP_ONLYCONVERTING) to make explicit conversion ops
@@ -1750,7 +1785,14 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
 
   num_convs =  args[2] ? 3 : (args[1] ? 2 : 1);
   convs = alloc_conversions (num_convs);
-  flags |= LOOKUP_ONLYCONVERTING;
+
+  /* TRUTH_*_EXPR do "contextual conversion to bool", which means explicit
+     conversion ops are allowed.  We handle that here by just checking for
+     boolean_type_node because other operators don't ask for it.  COND_EXPR
+     also does contextual conversion to bool for the first operand, but we
+     handle that in build_conditional_expr, and type1 here is operand 2.  */
+  if (type1 != boolean_type_node)
+    flags |= LOOKUP_ONLYCONVERTING;
 
   for (i = 0; i < 2; ++i)
     {
@@ -2221,6 +2263,8 @@ type_decays_to (tree type)
     return build_pointer_type (TREE_TYPE (type));
   if (TREE_CODE (type) == FUNCTION_TYPE)
     return build_pointer_type (type);
+  if (!MAYBE_CLASS_TYPE_P (type))
+    type = cv_unqualified (type);
   return type;
 }
 
@@ -2324,7 +2368,8 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
          if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
            return;
 
-         convs = lookup_conversions (argtypes[i]);
+         convs = lookup_conversions (argtypes[i],
+                                     /*lookup_template_convs_p=*/false);
 
          if (code == COND_EXPR)
            {
@@ -2419,9 +2464,10 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
 {
   int ntparms = DECL_NTPARMS (tmpl);
   tree targs = make_tree_vec (ntparms);
-  unsigned int nargs;
-  int skip_without_in_chrg;
-  tree first_arg_without_in_chrg;
+  unsigned int len = VEC_length (tree, arglist);
+  unsigned int nargs = (first_arg == NULL_TREE ? 0 : 1) + len;
+  unsigned int skip_without_in_chrg = 0;
+  tree first_arg_without_in_chrg = first_arg;
   tree *args_without_in_chrg;
   unsigned int nargs_without_in_chrg;
   unsigned int ia, ix;
@@ -2430,12 +2476,6 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
   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))
@@ -2456,9 +2496,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
        ++skip_without_in_chrg;
     }
 
+  if (len < skip_without_in_chrg)
+    return NULL;
+
   nargs_without_in_chrg = ((first_arg_without_in_chrg != NULL_TREE ? 1 : 0)
-                          + (VEC_length (tree, arglist)
-                             - skip_without_in_chrg));
+                          + (len - skip_without_in_chrg));
   args_without_in_chrg = XALLOCAVEC (tree, nargs_without_in_chrg);
   ia = 0;
   if (first_arg_without_in_chrg != NULL_TREE)
@@ -2543,7 +2585,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
        for this will point at template <class T> template <> S<T>::f(int),
        so that we can find the definition.  For the purposes of
        overload resolution, however, we want the original TMPL.  */
-    cand->template_decl = tree_cons (tmpl, targs, NULL_TREE);
+    cand->template_decl = build_template_info (tmpl, targs);
   else
     cand->template_decl = DECL_TEMPLATE_INFO (fn);
 
@@ -2683,6 +2725,8 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
     inform (input_location, "%s %T <conversion>", msgstr, candidate->fn);
   else if (candidate->viable == -1)
     inform (input_location, "%s %+#D <near match>", msgstr, candidate->fn);
+  else if (DECL_DELETED_FN (candidate->fn))
+    inform (input_location, "%s %+#D <deleted>", msgstr, candidate->fn);
   else
     inform (input_location, "%s %+#D", msgstr, candidate->fn);
 }
@@ -2693,6 +2737,24 @@ print_z_candidates (struct z_candidate *candidates)
   const char *str;
   struct z_candidate *cand1;
   struct z_candidate **cand2;
+  char *spaces;
+
+  if (!candidates)
+    return;
+
+  /* Remove deleted candidates.  */
+  cand1 = candidates;
+  for (cand2 = &cand1; *cand2; )
+    {
+      if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+         && DECL_DELETED_FN ((*cand2)->fn))
+       *cand2 = (*cand2)->next;
+      else
+       cand2 = &(*cand2)->next;
+    }
+  /* ...if there are any non-deleted ones.  */
+  if (cand1)
+    candidates = cand1;
 
   /* There may be duplicates in the set of candidates.  We put off
      checking this condition as long as possible, since we have no way
@@ -2716,28 +2778,14 @@ print_z_candidates (struct z_candidate *candidates)
        }
     }
 
-  if (!candidates)
-    return;
-
-  str = _("candidates are:");
-  print_z_candidate (str, candidates);
-  if (candidates->next)
+  str = candidates->next ? _("candidates are:") :  _("candidate is:");
+  spaces = NULL;
+  for (; candidates; candidates = candidates->next)
     {
-      /* Indent successive candidates by the width of the translation
-        of the above string.  */
-      size_t len = gcc_gettext_width (str) + 1;
-      char *spaces = (char *) alloca (len);
-      memset (spaces, ' ', len-1);
-      spaces[len - 1] = '\0';
-
-      candidates = candidates->next;
-      do
-       {
-         print_z_candidate (spaces, candidates);
-         candidates = candidates->next;
-       }
-      while (candidates);
+      print_z_candidate (spaces ? spaces : str, candidates);
+      spaces = spaces ? spaces : get_spaces (str);
     }
+  free (spaces);
 }
 
 /* USER_SEQ is a user-defined conversion sequence, beginning with a
@@ -2810,7 +2858,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
             reference to it)...  */
        }
       else
-       conv_fns = lookup_conversions (fromtype);
+       conv_fns = lookup_conversions (fromtype,
+                                      /*lookup_template_convs_p=*/true);
     }
 
   candidates = 0;
@@ -3330,6 +3379,7 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
       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,
                                    first_mem_arg, *args, NULL_TREE,
@@ -3343,7 +3393,7 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
        }
     }
 
-  convs = lookup_conversions (type);
+  convs = lookup_conversions (type, /*lookup_template_convs_p=*/true);
 
   for (; convs; convs = TREE_CHAIN (convs))
     {
@@ -3423,7 +3473,7 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
 
 static void
 op_error (enum tree_code code, enum tree_code code2,
-         tree arg1, tree arg2, tree arg3, const char *problem)
+         tree arg1, tree arg2, tree arg3, bool match)
 {
   const char *opname;
 
@@ -3435,31 +3485,58 @@ op_error (enum tree_code code, enum tree_code code2,
   switch (code)
     {
     case COND_EXPR:
-      error ("%s for ternary %<operator?:%> in %<%E ? %E : %E%>",
-            problem, arg1, arg2, arg3);
+      if (match)
+        error ("ambiguous overload for ternary %<operator?:%> "
+               "in %<%E ? %E : %E%>", arg1, arg2, arg3);
+      else
+        error ("no match for ternary %<operator?:%> "
+               "in %<%E ? %E : %E%>", arg1, arg2, arg3);
       break;
 
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
-      error ("%s for %<operator%s%> in %<%E%s%>", problem, opname, arg1, opname);
+      if (match)
+        error ("ambiguous overload for %<operator%s%> in %<%E%s%>",
+               opname, arg1, opname);
+      else
+        error ("no match for %<operator%s%> in %<%E%s%>", 
+               opname, arg1, opname);
       break;
 
     case ARRAY_REF:
-      error ("%s for %<operator[]%> in %<%E[%E]%>", problem, arg1, arg2);
+      if (match)
+        error ("ambiguous overload for %<operator[]%> in %<%E[%E]%>", 
+               arg1, arg2);
+      else
+        error ("no match for %<operator[]%> in %<%E[%E]%>", 
+               arg1, arg2);
       break;
 
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      error ("%s for %qs in %<%s %E%>", problem, opname, opname, arg1);
+      if (match)
+        error ("ambiguous overload for %qs in %<%s %E%>", 
+               opname, opname, arg1);
+      else
+        error ("no match for %qs in %<%s %E%>",
+               opname, opname, arg1);
       break;
 
     default:
       if (arg2)
-       error ("%s for %<operator%s%> in %<%E %s %E%>",
-              problem, opname, arg1, opname, arg2);
+        if (match)
+          error ("ambiguous overload for %<operator%s%> in %<%E %s %E%>",
+                  opname, arg1, opname, arg2);
+        else
+          error ("no match for %<operator%s%> in %<%E %s %E%>",
+                 opname, arg1, opname, arg2);
       else
-       error ("%s for %<operator%s%> in %<%s%E%>",
-              problem, opname, opname, arg1);
+        if (match)
+          error ("ambiguous overload for %<operator%s%> in %<%s%E%>",
+                 opname, opname, arg1);
+        else
+          error ("no match for %<operator%s%> in %<%s%E%>",
+                 opname, opname, arg1);
       break;
     }
 }
@@ -3538,6 +3615,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
   tree arg2_type;
   tree arg3_type;
   tree result = NULL_TREE;
+  tree result_save;
   tree result_type = NULL_TREE;
   bool lvalue_p = true;
   struct z_candidate *candidates = 0;
@@ -3565,7 +3643,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
 
      The first expression is implicitly converted to bool (clause
      _conv_).  */
-  arg1 = perform_implicit_conversion (boolean_type_node, arg1, complain);
+  arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
+                                           LOOKUP_NORMAL);
 
   /* If something has already gone wrong, just pass that fact up the
      tree.  */
@@ -3763,7 +3842,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
       bool any_viable_p;
 
       /* Rearrange the arguments so that add_builtin_candidate only has
-        to know about two args.  In build_builtin_candidates, the
+        to know about two args.  In build_builtin_candidate, the
         arguments are unscrambled.  */
       args[0] = arg2;
       args[1] = arg3;
@@ -3784,7 +3863,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
        {
           if (complain & tf_error)
             {
-              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
+              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
               print_z_candidates (candidates);
             }
          return error_mark_node;
@@ -3794,7 +3873,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
        {
           if (complain & tf_error)
             {
-              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
+              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
               print_z_candidates (candidates);
             }
          return error_mark_node;
@@ -3809,8 +3888,10 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
       arg1 = convert_like (conv, arg1, complain);
       conv = cand->convs[1];
       arg2 = convert_like (conv, arg2, complain);
+      arg2_type = TREE_TYPE (arg2);
       conv = cand->convs[2];
       arg3 = convert_like (conv, arg3, complain);
+      arg3_type = TREE_TYPE (arg3);
     }
 
   /* [expr.cond]
@@ -3829,7 +3910,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
     arg2_type = TREE_TYPE (arg2);
 
   arg3 = force_rvalue (arg3);
-  if (!CLASS_TYPE_P (arg2_type))
+  if (!CLASS_TYPE_P (arg3_type))
     arg3_type = TREE_TYPE (arg3);
 
   if (arg2 == error_mark_node || arg3 == error_mark_node)
@@ -3904,7 +3985,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
           || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
     {
       result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
-                                           arg3, "conditional expression",
+                                           arg3, CPO_CONDITIONAL_EXPR,
                                            complain);
       if (result_type == error_mark_node)
        return error_mark_node;
@@ -3921,8 +4002,13 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
     }
 
  valid_operands:
-  result = fold_if_not_in_template (build3 (COND_EXPR, result_type, arg1,
-                                           arg2, arg3));
+  result_save = build3 (COND_EXPR, result_type, arg1, arg2, arg3);
+  result = fold_if_not_in_template (result_save);
+
+  if (cp_unevaluated_operand && TREE_CODE (result) == CALL_EXPR)
+    /* Avoid folding to a CALL_EXPR within decltype (c++/42013).  */
+    result = result_save;
+
   /* We can't use result_type below, as fold might have returned a
      throw_expr.  */
 
@@ -4129,14 +4215,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
   arg3 = prep_operand (arg3);
 
   if (code == COND_EXPR)
-    {
-      if (arg2 == NULL_TREE
-         || TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE
-         || TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE
-         || (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))
-             && ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
-       goto builtin;
-    }
+    /* Use build_conditional_expr instead.  */
+    gcc_unreachable ();
   else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
           && (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))))
     goto builtin;
@@ -4178,22 +4258,9 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
                        flags, &candidates);
     }
 
-  /* Rearrange the arguments for ?: so that add_builtin_candidate only has
-     to know about two args; a builtin candidate will always have a first
-     parameter of type bool.  We'll handle that in
-     build_builtin_candidate.  */
-  if (code == COND_EXPR)
-    {
-      args[0] = arg2;
-      args[1] = arg3;
-      args[2] = arg1;
-    }
-  else
-    {
-      args[0] = arg1;
-      args[1] = arg2;
-      args[2] = NULL_TREE;
-    }
+  args[0] = arg1;
+  args[1] = arg2;
+  args[2] = NULL_TREE;
 
   add_builtin_candidates (&candidates, code, code2, fnname, args, flags);
 
@@ -4227,13 +4294,23 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          if (!(complain & tf_error))
            return error_mark_node;
 
-         /* Look for an `operator++ (int)'.  If they didn't have
-            one, then we fall back to the old way of doing things.  */
+         /* Look for an `operator++ (int)'. Pre-1985 C++ didn't
+            distinguish between prefix and postfix ++ and
+            operator++() was used for both, so we allow this with
+            -fpermissive.  */
          if (flags & LOOKUP_COMPLAIN)
-           permerror (input_location, "no %<%D(int)%> declared for postfix %qs, "
-                      "trying prefix operator instead",
-                      fnname,
-                      operator_name_info[code].name);
+           {
+             const char *msg = (flag_permissive) 
+               ? G_("no %<%D(int)%> declared for postfix %qs,"
+                    " trying prefix operator instead")
+               : G_("no %<%D(int)%> declared for postfix %qs");
+             permerror (input_location, msg, fnname,
+                        operator_name_info[code].name);
+           }
+
+         if (!flag_permissive)
+           return error_mark_node;
+
          if (code == POSTINCREMENT_EXPR)
            code = PREINCREMENT_EXPR;
          else
@@ -4264,7 +4341,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
                  {
                    /* ... Otherwise, report the more generic
                       "no matching operator found" error */
-                   op_error (code, code2, arg1, arg2, arg3, "no match");
+                   op_error (code, code2, arg1, arg2, arg3, FALSE);
                    print_z_candidates (candidates);
                  }
            }
@@ -4279,7 +4356,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
        {
          if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
            {
-             op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
+             op_error (code, code2, arg1, arg2, arg3, TRUE);
              print_z_candidates (candidates);
            }
          result = error_mark_node;
@@ -4381,7 +4458,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       return cp_build_modify_expr (arg1, code2, arg2, complain);
 
     case INDIRECT_REF:
-      return cp_build_indirect_ref (arg1, "unary *", complain);
+      return cp_build_indirect_ref (arg1, RO_UNARY_STAR, complain);
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
@@ -4425,11 +4502,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
     case ARRAY_REF:
       return build_array_ref (input_location, arg1, arg2);
 
-    case COND_EXPR:
-      return build_conditional_expr (arg1, arg2, arg3, complain);
-
     case MEMBER_REF:
-      return build_m_component_ref (cp_build_indirect_ref (arg1, NULL, 
+      return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL, 
                                                            complain), 
                                     arg2);
 
@@ -4445,6 +4519,33 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
   return NULL_TREE;
 }
 
+/* Returns true iff T, an element of an OVERLOAD chain, is a usual
+   deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]).  */
+
+static bool
+non_placement_deallocation_fn_p (tree t)
+{
+  /* A template instance is never a usual deallocation function,
+     regardless of its signature.  */
+  if (TREE_CODE (t) == TEMPLATE_DECL
+      || primary_template_instantiation_p (t))
+    return false;
+
+  /* If a class T has a member deallocation function named operator delete
+     with exactly one parameter, then that function is a usual
+     (non-placement) deallocation function. If class T does not declare
+     such an operator delete but does declare a member deallocation
+     function named operator delete with exactly two parameters, the second
+     of which has type std::size_t (18.2), then this function is a usual
+     deallocation function.  */
+  t = FUNCTION_ARG_CHAIN (t);
+  if (t == void_list_node
+      || (t && same_type_p (TREE_VALUE (t), size_type_node)
+         && TREE_CHAIN (t) == void_list_node))
+    return true;
+  return false;
+}
+
 /* Build a call to operator delete.  This has to be handled very specially,
    because the restrictions on what signatures match are different from all
    other call instances.  For a normal delete, only a delete taking (void *)
@@ -4470,8 +4571,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
                      tree alloc_fn)
 {
   tree fn = NULL_TREE;
-  tree fns, fnname, argtypes, type;
-  int pass;
+  tree fns, fnname, type, t;
 
   if (addr == error_mark_node)
     return error_mark_node;
@@ -4506,78 +4606,86 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
 
   if (placement)
     {
-      /* Get the parameter types for the allocation function that is
-        being called.  */
-      gcc_assert (alloc_fn != NULL_TREE);
-      argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
-    }
-  else
-    {
-      /* First try it without the size argument.  */
-      argtypes = void_list_node;
-    }
-
-  /* We make two tries at finding a matching `operator delete'.  On
-     the first pass, we look for a one-operator (or placement)
-     operator delete.  If we're not doing placement delete, then on
-     the second pass we look for a two-argument delete.  */
-  for (pass = 0; pass < (placement ? 1 : 2); ++pass)
-    {
-      /* Go through the `operator delete' functions looking for one
-        with a matching type.  */
-      for (fn = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
-          fn;
-          fn = OVL_NEXT (fn))
+      /* "A declaration of a placement deallocation function matches the
+        declaration of a placement allocation function if it has the same
+        number of parameters and, after parameter transformations (8.3.5),
+        all parameter types except the first are identical."
+
+        So we build up the function type we want and ask instantiate_type
+        to get it for us.  */
+      t = FUNCTION_ARG_CHAIN (alloc_fn);
+      t = tree_cons (NULL_TREE, ptr_type_node, t);
+      t = build_function_type (void_type_node, t);
+
+      fn = instantiate_type (t, fns, tf_none);
+      if (fn == error_mark_node)
+       return NULL_TREE;
+
+      if (BASELINK_P (fn))
+       fn = BASELINK_FUNCTIONS (fn);
+
+      /* "If the lookup finds the two-parameter form of a usual deallocation
+        function (3.7.4.2) and that function, considered as a placement
+        deallocation function, would have been selected as a match for the
+        allocation function, the program is ill-formed."  */
+      if (non_placement_deallocation_fn_p (fn))
        {
-         tree t;
-
-         /* The first argument must be "void *".  */
-         t = TYPE_ARG_TYPES (TREE_TYPE (OVL_CURRENT (fn)));
-         if (!same_type_p (TREE_VALUE (t), ptr_type_node))
-           continue;
-         t = TREE_CHAIN (t);
-         /* On the first pass, check the rest of the arguments.  */
-         if (pass == 0)
+         /* But if the class has an operator delete (void *), then that is
+            the usual deallocation function, so we shouldn't complain
+            about using the operator delete (void *, size_t).  */
+         for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
+              t; t = OVL_NEXT (t))
            {
-             tree a = argtypes;
-             while (a && t)
-               {
-                 if (!same_type_p (TREE_VALUE (a), TREE_VALUE (t)))
-                   break;
-                 a = TREE_CHAIN (a);
-                 t = TREE_CHAIN (t);
-               }
-             if (!a && !t)
-               break;
+             tree elt = OVL_CURRENT (t);
+             if (non_placement_deallocation_fn_p (elt)
+                 && FUNCTION_ARG_CHAIN (elt) == void_list_node)
+               goto ok;
            }
-         /* On the second pass, look for a function with exactly two
-            arguments: "void *" and "size_t".  */
-         else if (pass == 1
-                  /* For "operator delete(void *, ...)" there will be
-                     no second argument, but we will not get an exact
-                     match above.  */
-                  && t
-                  && same_type_p (TREE_VALUE (t), size_type_node)
-                  && TREE_CHAIN (t) == void_list_node)
-           break;
+         permerror (0, "non-placement deallocation function %q+D", fn);
+         permerror (input_location, "selected for placement delete");
+       ok:;
        }
-
-      /* If we found a match, we're done.  */
-      if (fn)
-       break;
     }
+  else
+    /* "Any non-placement deallocation function matches a non-placement
+       allocation function. If the lookup finds a single matching
+       deallocation function, that function will be called; otherwise, no
+       deallocation function will be called."  */
+    for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
+        t; t = OVL_NEXT (t))
+      {
+       tree elt = OVL_CURRENT (t);
+       if (non_placement_deallocation_fn_p (elt))
+         {
+           fn = elt;
+           /* "If a class T has a member deallocation function named
+              operator delete with exactly one parameter, then that
+              function is a usual (non-placement) deallocation
+              function. If class T does not declare such an operator
+              delete but does declare a member deallocation function named
+              operator delete with exactly two parameters, the second of
+              which has type std::size_t (18.2), then this function is a
+              usual deallocation function."
+
+              So (void*) beats (void*, size_t).  */
+           if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
+             break;
+         }
+      }
 
   /* If we have a matching function, call it.  */
   if (fn)
     {
-      /* Make sure we have the actual function, and not an
-        OVERLOAD.  */
-      fn = OVL_CURRENT (fn);
+      gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
 
       /* If the FN is a member function, make sure that it is
         accessible.  */
-      if (DECL_CLASS_SCOPE_P (fn))
-       perform_or_defer_access_check (TYPE_BINFO (type), fn, fn);
+      if (BASELINK_P (fns))
+       perform_or_defer_access_check (BASELINK_BINFO (fns), fn, fn);
+
+      /* Core issue 901: It's ok to new a type with deleted delete.  */
+      if (DECL_DELETED_FN (fn) && alloc_fn)
+       return NULL_TREE;
 
       if (placement)
        {
@@ -4597,7 +4705,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
          tree ret;
          VEC(tree,gc) *args = VEC_alloc (tree, gc, 2);
          VEC_quick_push (tree, args, addr);
-         if (pass != 0)
+         if (FUNCTION_ARG_CHAIN (fn) != void_list_node)
            VEC_quick_push (tree, args, size);
          ret = cp_build_function_call_vec (fn, &args, tf_warning_or_error);
          VEC_free (tree, gc, args);
@@ -4688,17 +4796,19 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
   if (expr == null_node && TREE_CODE (t) != BOOLEAN_TYPE && ARITHMETIC_TYPE_P (t))
     {
       if (fn)
-       warning (OPT_Wconversion, "passing NULL to non-pointer argument %P of %qD",
-                argnum, fn);
+       warning_at (input_location, OPT_Wconversion_null,
+                   "passing NULL to non-pointer argument %P of %qD",
+                   argnum, fn);
       else
-       warning (OPT_Wconversion, "converting to non-pointer type %qT from NULL", t);
+       warning_at (input_location, OPT_Wconversion_null,
+                   "converting to non-pointer type %qT from NULL", t);
     }
 
   /* Issue warnings if "false" is converted to a NULL pointer */
   else if (expr == boolean_false_node && fn && POINTER_TYPE_P (t))
-    warning (OPT_Wconversion,
-            "converting %<false%> to pointer type for argument %P of %qD",
-            argnum, fn);
+    warning_at (input_location, OPT_Wconversion_null,
+               "converting %<false%> to pointer type for argument %P of %qD",
+               argnum, fn);
 }
 
 /* Perform the conversions in CONVS on the expression EXPR.  FN and
@@ -4837,6 +4947,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
         }
       return expr;
     case ck_ambig:
+      if (!(complain & tf_error))
+       return error_mark_node;
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
        (totype, convs->u.expr, LOOKUP_NORMAL);
@@ -4897,7 +5009,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
   switch (convs->kind)
     {
     case ck_rvalue:
-      expr = convert_bitfield_to_declared_type (expr);
+      expr = decay_conversion (expr);
       if (! MAYBE_CLASS_TYPE_P (totype))
        return expr;
       /* Else fall through.  */
@@ -4909,8 +5021,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
          /* Build an expression for `*((base*) &expr)'.  */
          expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
          expr = convert_to_base (expr, build_pointer_type (totype),
-                                 !c_cast_p, /*nonnull=*/true);
-         expr = cp_build_indirect_ref (expr, "implicit conversion", complain);
+                                 !c_cast_p, /*nonnull=*/true, complain);
+         expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
          return expr;
        }
 
@@ -4938,6 +5050,19 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       {
        tree ref_type = totype;
 
+       if (convs->bad_p && TYPE_REF_IS_RVALUE (ref_type)
+           && real_lvalue_p (expr))
+         {
+           if (complain & tf_error)
+             {
+               error ("cannot bind %qT lvalue to %qT",
+                      TREE_TYPE (expr), totype);
+               if (fn)
+                 error ("  initializing argument %P of %q+D", argnum, fn);
+             }
+           return error_mark_node;
+         }
+
        /* If necessary, create a temporary. 
 
            VA_ARG_EXPR and CONSTRUCTOR expressions are special cases
@@ -5019,7 +5144,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     case ck_ptr:
       if (convs->base_p)
        expr = convert_to_base (expr, totype, !c_cast_p,
-                               /*nonnull=*/false);
+                               /*nonnull=*/false, complain);
       return build_nop (totype, expr);
 
     case ck_pmem:
@@ -5061,7 +5186,8 @@ convert_arg_to_ellipsis (tree arg)
      promoted type before the call.  */
   if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
       && (TYPE_PRECISION (TREE_TYPE (arg))
-         < TYPE_PRECISION (double_type_node)))
+         < TYPE_PRECISION (double_type_node))
+      && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (arg))))
     arg = convert_to_real (double_type_node, arg);
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
     arg = perform_integral_promotions (arg);
@@ -5114,7 +5240,7 @@ build_x_va_arg (tree expr, tree type)
       error ("cannot receive objects of non-trivially-copyable type %q#T "
             "through %<...%>; ", type);
       expr = convert (build_pointer_type (type1), null_node);
-      expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
+      expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
       return expr;
     }
 
@@ -5365,8 +5491,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
            alcarray[ix + 1] = arg;
          argarray = alcarray;
        }
-      expr = build_call_array (return_type, build_addr_func (fn), nargs,
-                              argarray);
+      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))
@@ -5524,6 +5651,32 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
          && !TREE_ADDRESSABLE (type))
        conv = conv->u.next;
 
+      /* Warn about initializer_list deduction that isn't currently in the
+        working draft.  */
+      if (cxx_dialect > cxx98
+         && flag_deduce_init_list
+         && cand->template_decl
+         && is_std_init_list (non_reference (type)))
+       {
+         tree tmpl = TI_TEMPLATE (cand->template_decl);
+         tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn));
+         tree patparm = get_pattern_parm (realparm, tmpl);
+         tree pattype = TREE_TYPE (patparm);
+         if (PACK_EXPANSION_P (pattype))
+           pattype = PACK_EXPANSION_PATTERN (pattype);
+         pattype = non_reference (pattype);
+
+         if (!is_std_init_list (pattype))
+           {
+             pedwarn (input_location, 0, "deducing %qT as %qT",
+                      non_reference (TREE_TYPE (patparm)),
+                      non_reference (type));
+             pedwarn (input_location, 0, "  in call to %q+D", cand->fn);
+             pedwarn (input_location, 0,
+                      "  (you can disable this with -fno-deduce-init-list)");
+           }
+       }
+
       val = convert_like_with_context
        (conv, VEC_index (tree, args, arg_index), fn, i - is_method,
         complain);
@@ -5588,7 +5741,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       if (targ)
        arg = targ;
       else
-       arg = cp_build_indirect_ref (arg, 0, complain);
+       arg = cp_build_indirect_ref (arg, RO_NULL, complain);
 
       if (TREE_CODE (arg) == TARGET_EXPR
          && TARGET_EXPR_LIST_INIT_P (arg))
@@ -5623,10 +5776,22 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
               || (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))
                   && !move_fn_p (fn)))
        {
-         tree to = stabilize_reference (cp_build_indirect_ref (fa, 0,
+         tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL,
                                                                complain));
+         tree type = TREE_TYPE (to);
 
-         val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
+         if (TREE_CODE (arg) != TARGET_EXPR
+             && TREE_CODE (arg) != AGGR_INIT_EXPR
+             && 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
+           val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
          return val;
        }
     }
@@ -5635,14 +5800,22 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
           && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
     {
       tree to = stabilize_reference
-       (cp_build_indirect_ref (argarray[0], 0, complain));
+       (cp_build_indirect_ref (argarray[0], RO_NULL, complain));
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
       tree arg = argarray[1];
 
-      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, 0, complain);
+         arg = cp_build_indirect_ref (arg, RO_NULL, complain);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
        }
       else
@@ -5675,7 +5848,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
          t = convert (TREE_TYPE (arg0), t);
          if (test)
            t = build3 (COND_EXPR, TREE_TYPE (t), test, arg0, t);
-         val = cp_build_indirect_ref (t, 0, complain);
+         val = cp_build_indirect_ref (t, RO_NULL, complain);
           TREE_NO_WARNING (val) = 1;
        }
 
@@ -5783,7 +5956,7 @@ build_java_interface_fn_ref (tree fn, tree instance)
 
   /* Look up the pointer to the runtime java.lang.Class object for `instance'.
      This is the first entry in the vtable.  */
-  klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, 0
+  klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, RO_NULL
                                                      tf_warning_or_error),
                              integer_zero_node);
 
@@ -6046,7 +6219,7 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
     *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))
@@ -6088,6 +6261,24 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
        make_args_non_dependent (*args);
     }
 
+  user_args = args == NULL ? NULL : *args;
+  /* Under DR 147 A::A() is an invalid constructor call,
+     not a functional cast.  */
+  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
+    {
+      if (! (complain & tf_error))
+       return error_mark_node;
+
+      permerror (input_location,
+                "cannot call constructor %<%T::%D%> directly",
+                basetype, name);
+      permerror (input_location, "  for a function-style cast, remove the "
+                "redundant %<::%D%>", name);
+      call = build_functional_cast (basetype, build_tree_list_vec (user_args),
+                                   complain);
+      return call;
+    }
+
   /* Figure out whether to skip the first argument for the error
      message we will display to users if an error occurs.  We don't
      want to display any compiler-generated arguments.  The "this"
@@ -6095,7 +6286,6 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
      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
@@ -6435,7 +6625,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;
     }
 
@@ -6476,6 +6665,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
@@ -6511,8 +6708,9 @@ compare_ics (conversion *ics1, conversion *ics2)
       /* We couldn't make up our minds; try to figure it out below.  */
     }
 
-  if (ics1->ellipsis_p)
-    /* Both conversions are ellipsis conversions.  */
+  if (ics1->ellipsis_p || ics1->kind == ck_list)
+    /* Both conversions are ellipsis conversions or both are building a
+       std::initializer_list.  */
     return 0;
 
   /* User-defined  conversion sequence U1 is a better conversion sequence
@@ -6526,26 +6724,13 @@ compare_ics (conversion *ics1, conversion *ics2)
       conversion *t1;
       conversion *t2;
 
-      for (t1 = ics1; t1->kind != ck_user && t1->kind != ck_list; t1 = t1->u.next)
+      for (t1 = ics1; t1->kind != ck_user; t1 = t1->u.next)
        if (t1->kind == ck_ambig || t1->kind == ck_aggr)
          return 0;
-      for (t2 = ics2; t2->kind != ck_user && t2->kind != ck_list; t2 = t2->u.next)
+      for (t2 = ics2; t2->kind != ck_user; t2 = t2->u.next)
        if (t2->kind == ck_ambig || t2->kind == ck_aggr)
          return 0;
 
-      /* Conversion to std::initializer_list is better than other
-        user-defined conversions.  */
-      if (t1->kind == ck_list
-         || t2->kind == ck_list)
-       {
-         if (t2->kind != ck_list)
-           return 1;
-         else if (t1->kind != ck_list)
-           return -1;
-         else
-           return 0;
-       }
-
       if (t1->cand->fn != t2->cand->fn)
        return 0;
 
@@ -7401,7 +7586,7 @@ perform_direct_initialization_if_possible (tree type,
     expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
                              /*issue_conversion_warnings=*/false,
                              c_cast_p,
-                             tf_warning_or_error);
+                             complain);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -7523,7 +7708,8 @@ set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp)
    Return the converted expression.  */
 
 tree
-initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
+initialize_reference (tree type, tree expr, tree decl, tree *cleanup,
+                     tsubst_flags_t complain)
 {
   conversion *conv;
   void *p;
@@ -7538,15 +7724,19 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
                            LOOKUP_NORMAL);
   if (!conv || conv->bad_p)
     {
-      if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
-         && !real_lvalue_p (expr))
-       error ("invalid initialization of non-const reference of "
-              "type %qT from a temporary of type %qT",
-              type, TREE_TYPE (expr));
-      else
-       error ("invalid initialization of reference of type "
-              "%qT from expression of type %qT", type,
-              TREE_TYPE (expr));
+      if (complain & tf_error)
+       {
+         if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
+             && !TYPE_REF_IS_RVALUE (type)
+             && !real_lvalue_p (expr))
+           error ("invalid initialization of non-const reference of "
+                  "type %qT from an rvalue of type %qT",
+                  type, TREE_TYPE (expr));
+         else
+           error ("invalid initialization of reference of type "
+                  "%qT from expression of type %qT", type,
+                  TREE_TYPE (expr));
+       }
       return error_mark_node;
     }
 
@@ -7622,7 +7812,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
                expr = convert_to_base (expr,
                                        build_pointer_type (base_conv_type),
                                        /*check_access=*/true,
-                                       /*nonnull=*/true);
+                                       /*nonnull=*/true, complain);
              expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
            }
          else