OSDN Git Service

PR c++/43509
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 204a6bb..2dc73f5 100644 (file)
@@ -447,6 +447,7 @@ struct z_candidate {
      indicated by the CONVERSION_PATH.  */
   tree conversion_path;
   tree template_decl;
+  tree explicit_targs;
   candidate_warning *warnings;
   z_candidate *next;
 };
@@ -464,7 +465,7 @@ null_ptr_cst_p (tree t)
      an rvalue of type std::nullptr_t. */
   t = integral_constant_value (t);
   if (t == null_node
-      || TREE_CODE (TREE_TYPE (t)) == NULLPTR_TYPE)
+      || NULLPTR_TYPE_P (TREE_TYPE (t)))
     return true;
   if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t))
     {
@@ -783,7 +784,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
      null pointer constant of integral type can be converted to an
      rvalue of type std::nullptr_t. */
   if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to)
-       || tcode == NULLPTR_TYPE)
+       || 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)
@@ -924,14 +925,14 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
          || UNSCOPED_ENUM_P (from)
          || fcode == POINTER_TYPE
          || TYPE_PTR_TO_MEMBER_P (from)
-         || fcode == NULLPTR_TYPE)
+         || NULLPTR_TYPE_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)
-              || fcode == NULLPTR_TYPE)
+             || NULLPTR_TYPE_P (from))
            conv->rank = cr_pbool;
          return conv;
        }
@@ -2508,11 +2509,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
                           return_type, strict, flags);
 
   if (i != 0)
-    return NULL;
+    goto fail;
 
   fn = instantiate_template (tmpl, targs, tf_none);
   if (fn == error_mark_node)
-    return NULL;
+    goto fail;
 
   /* In [class.copy]:
 
@@ -2541,7 +2542,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))
-       return NULL;
+       goto fail;
     }
 
   if (obj != NULL_TREE)
@@ -2573,8 +2574,12 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
     cand->template_decl = build_template_info (tmpl, targs);
   else
     cand->template_decl = DECL_TEMPLATE_INFO (fn);
+  cand->explicit_targs = explicit_targs;
 
   return cand;
+ fail:
+  return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL,
+                       access_path, conversion_path, 0);
 }
 
 
@@ -2607,10 +2612,10 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
 }
 
 /* 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,
@@ -2675,6 +2680,10 @@ build_this (tree obj)
 static inline int
 equal_functions (tree fn1, tree fn2)
 {
+  if (TREE_CODE (fn1) != TREE_CODE (fn2))
+    return 0;
+  if (TREE_CODE (fn1) == TEMPLATE_DECL)
+    return fn1 == fn2;
   if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
       || DECL_EXTERN_C_FUNCTION_P (fn1))
     return decls_match (fn1, fn2);
@@ -2710,7 +2719,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);
-  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);
@@ -2750,12 +2759,12 @@ print_z_candidates (struct z_candidate *candidates)
     {
       tree fn = cand1->fn;
       /* Skip builtin candidates and conversion functions.  */
-      if (TREE_CODE (fn) != FUNCTION_DECL)
+      if (!DECL_P (fn))
        continue;
       cand2 = &cand1->next;
       while (*cand2)
        {
-         if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+         if (DECL_P ((*cand2)->fn)
              && equal_functions (fn, (*cand2)->fn))
            *cand2 = (*cand2)->next;
          else
@@ -2860,6 +2869,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
   if (ctors)
     {
       int ctorflags = flags;
+      bool try_single_arg = true;
       ctors = BASELINK_FUNCTIONS (ctors);
 
       first_arg = build_int_cst (build_pointer_type (totype), 0);
@@ -2868,28 +2878,44 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
          /* 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))
-           args = make_tree_vector_single (expr);
+           ctorflags |= LOOKUP_LIST_ONLY;
          else
-           {
-             args = ctor_to_vec (expr);
-             /* 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;
-           }
+           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)));
 
-      add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
-                     TYPE_BINFO (totype), TYPE_BINFO (totype),
-                     ctorflags, &candidates);
+      /* 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 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)
        {
@@ -2933,11 +2959,33 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
 
       for (cand = candidates; cand != old_candidates; cand = cand->next)
        {
-         conversion *ics
-           = implicit_conversion (totype,
-                                  TREE_TYPE (TREE_TYPE (cand->fn)),
-                                  0,
-                                  /*c_cast_p=*/false, convflags);
+         tree fn = OVL_CURRENT (fns);
+
+         if (DECL_NONCONVERTING_P (fn)
+             && (flags & LOOKUP_ONLYCONVERTING))
+           continue;
+
+         /* [over.match.funcs] For conversion functions, the function
+            is considered to be a member of the class of the implicit
+            object argument for the purpose of defining the type of
+            the implicit object parameter.
+
+            So we pass fromtype as CTYPE to add_*_candidate.  */
+
+         if (TREE_CODE (fn) == TEMPLATE_DECL)
+           cand = add_template_candidate (&candidates, fn, fromtype,
+                                          NULL_TREE,
+                                          first_arg, NULL, totype,
+                                          TYPE_BINFO (fromtype),
+                                          conversion_path,
+                                          flags,
+                                          DEDUCE_CONV);
+         else
+           cand = add_function_candidate (&candidates, fn, fromtype,
+                                          first_arg, NULL,
+                                          TYPE_BINFO (fromtype),
+                                          conversion_path,
+                                          flags);
 
          /* If LOOKUP_NO_TEMP_BIND isn't set, then this is
             copy-initialization.  In that case, "The result of the
@@ -3150,7 +3198,8 @@ build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p,
     {
       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);
@@ -3329,11 +3378,21 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
     {
       first_mem_arg = build_this (obj);
 
-      add_candidates (BASELINK_FUNCTIONS (fns),
-                     first_mem_arg, *args, NULL_TREE,
-                     NULL_TREE, false,
-                     BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns),
-                     LOOKUP_NORMAL, &candidates);
+      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,
+                                   TYPE_BINFO (type),
+                                   TYPE_BINFO (type),
+                                   LOOKUP_NORMAL, DEDUCE_CALL);
+         else
+           add_function_candidate
+             (&candidates, fn, base, first_mem_arg, *args, TYPE_BINFO (type),
+              TYPE_BINFO (type), LOOKUP_NORMAL);
+       }
     }
 
   convs = lookup_conversions (type, /*lookup_template_convs_p=*/true);
@@ -4009,6 +4068,7 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
 {
   tree ctype;
   const VEC(tree,gc) *non_static_args;
+  bool check_list_ctor;
   bool check_converting;
   unification_kind_t strict;
   tree fn;
@@ -4020,6 +4080,7 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
   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).  */
@@ -4036,9 +4097,15 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
   else
     {
       if (DECL_CONSTRUCTOR_P (fn))
-       check_converting = !!(flags & LOOKUP_ONLYCONVERTING);
+       {
+         check_list_ctor = !!(flags & LOOKUP_LIST_ONLY);
+         check_converting = !!(flags & LOOKUP_ONLYCONVERTING);
+       }
       else
-       check_converting = false;
+       {
+         check_list_ctor = false;
+         check_converting = false;
+       }
       strict = DEDUCE_CALL;
       ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
     }
@@ -4058,6 +4125,8 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
 
       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))
@@ -4482,7 +4551,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 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, 
@@ -5174,7 +5243,7 @@ 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);
-  else if (TREE_CODE (TREE_TYPE (arg)) == NULLPTR_TYPE)
+  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);
@@ -5631,6 +5700,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);
+      tree arg = VEC_index (tree, args, arg_index);
 
       conv = convs[i];
 
@@ -5645,7 +5715,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
-         && 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));
@@ -5655,7 +5726,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
            pattype = PACK_EXPANSION_PATTERN (pattype);
          pattype = non_reference (pattype);
 
-         if (!is_std_init_list (pattype))
+         if (TREE_CODE (pattype) == TEMPLATE_TYPE_PARM
+             && (cand->explicit_targs == NULL_TREE
+                 || (TREE_VEC_LENGTH (cand->explicit_targs)
+                     <= TEMPLATE_TYPE_IDX (pattype))))
            {
              pedwarn (input_location, 0, "deducing %qT as %qT",
                       non_reference (TREE_TYPE (patparm)),
@@ -5666,9 +5740,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)
@@ -5741,7 +5813,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.  */
-      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;
@@ -5759,7 +5832,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        {
          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
@@ -6188,6 +6262,8 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
   tree orig_fns;
   VEC(tree,gc) *orig_args = NULL;
   void *p;
+  tree list = NULL_TREE;
+  bool try_normal;
 
   gcc_assert (instance != NULL_TREE);
 
@@ -6300,15 +6376,20 @@ 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
-     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))
-      && 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);
-      *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;
     }
 
   first_mem_arg = instance_ptr;
@@ -6316,11 +6397,25 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
-  add_candidates (fns, first_mem_arg, args ? *args : NULL, optype,
-                 explicit_targs, template_only, conversion_path,
-                 access_binfo, flags, &candidates);
+  any_viable_p = false;
+  if (try_normal)
+    {
+      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 (!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)
@@ -6387,8 +6482,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) ?
-                     "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