OSDN Git Service

PR c++/43509
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 46779fa..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;
 };
@@ -2573,6 +2574,7 @@ 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:
@@ -2957,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
@@ -3354,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);
@@ -5692,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)),