]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/pt.c
PR c++/80290 - memory-hog with std::pair.
[thirdparty/gcc.git] / gcc / cp / pt.c
index e1e2f0152c112c6025b167d5afb2a464aea77392..3780f3492aa1b7fec32e3152210a140e62eb61db 100644 (file)
@@ -155,10 +155,12 @@ static void tsubst_enum   (tree, tree, tree);
 static tree add_to_template_args (tree, tree);
 static tree add_outermost_template_args (tree, tree);
 static bool check_instantiated_args (tree, tree, tsubst_flags_t);
+static int check_non_deducible_conversion (tree, tree, int, int,
+                                          struct conversion **, bool);
 static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
                                             tree);
 static int type_unification_real (tree, tree, tree, const tree *,
-                                 unsigned int, int, unification_kind_t, int,
+                                 unsigned int, int, unification_kind_t,
                                  vec<deferred_access_check, va_gc> **,
                                  bool);
 static void note_template_header (int);
@@ -19358,6 +19360,58 @@ pack_deducible_p (tree parm, tree fn)
   return true;
 }
 
+/* Subroutine of fn_type_unification: check non-dependent parms for
+   convertibility.  */
+
+static int
+check_non_deducible_conversions (tree parms, const tree *args, unsigned nargs,
+                                tree fn, unification_kind_t strict, int flags,
+                                struct conversion **convs, bool explain_p)
+{
+  /* Non-constructor methods need to leave a conversion for 'this', which
+     isn't included in nargs here.  */
+  unsigned offset = (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+                    && !DECL_CONSTRUCTOR_P (fn));
+
+  for (unsigned ia = 0;
+       parms && parms != void_list_node && ia < nargs; )
+    {
+      tree parm = TREE_VALUE (parms);
+
+      if (TREE_CODE (parm) == TYPE_PACK_EXPANSION
+         && (!TREE_CHAIN (parms)
+             || TREE_CHAIN (parms) == void_list_node))
+       /* For a function parameter pack that occurs at the end of the
+          parameter-declaration-list, the type A of each remaining
+          argument of the call is compared with the type P of the
+          declarator-id of the function parameter pack.  */
+       break;
+
+      parms = TREE_CHAIN (parms);
+
+      if (TREE_CODE (parm) == TYPE_PACK_EXPANSION)
+       /* For a function parameter pack that does not occur at the
+          end of the parameter-declaration-list, the type of the
+          parameter pack is a non-deduced context.  */
+       continue;
+
+      if (!uses_template_parms (parm))
+       {
+         tree arg = args[ia];
+         conversion **conv_p = convs ? &convs[ia+offset] : NULL;
+         int lflags = conv_flags (ia, nargs, fn, arg, flags);
+
+         if (check_non_deducible_conversion (parm, arg, strict, lflags,
+                                             conv_p, explain_p))
+           return 1;
+       }
+
+      ++ia;
+    }
+
+  return 0;
+}
+
 /* The FN is a TEMPLATE_DECL for a function.  ARGS is an array with
    NARGS elements of the arguments that are being used when calling
    it.  TARGS is a vector into which the deduced template arguments
@@ -19400,6 +19454,7 @@ fn_type_unification (tree fn,
                     tree return_type,
                     unification_kind_t strict,
                     int flags,
+                    struct conversion **convs,
                     bool explain_p,
                     bool decltype_p)
 {
@@ -19604,7 +19659,7 @@ fn_type_unification (tree fn,
 
   ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
                               full_targs, parms, args, nargs, /*subr=*/0,
-                              strict, flags, &checks, explain_p);
+                              strict, &checks, explain_p);
   if (!explain_p)
     pop_tinst_level ();
   if (!ok)
@@ -19638,6 +19693,12 @@ fn_type_unification (tree fn,
       goto fail;
     }
 
+  /* DR 1391: All parameters have args, now check non-dependent parms for
+     convertibility.  */
+  if (check_non_deducible_conversions (parms, args, nargs, fn, strict, flags,
+                                      convs, explain_p))
+    goto fail;
+
   /* All is well so far.  Now, check:
 
      [temp.deduct]
@@ -19826,14 +19887,15 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
   return result;
 }
 
-/* Subroutine of unify_one_argument.  PARM is a function parameter of a
-   template which does contain any deducible template parameters; check if
+/* Subroutine of fn_type_unification.  PARM is a function parameter of a
+   template which doesn't contain any deducible template parameters; check if
    ARG is a suitable match for it.  STRICT, FLAGS and EXPLAIN_P are as in
    unify_one_argument.  */
 
 static int
 check_non_deducible_conversion (tree parm, tree arg, int strict,
-                               int flags, bool explain_p)
+                               int flags, struct conversion **conv_p,
+                               bool explain_p)
 {
   tree type;
 
@@ -19845,17 +19907,23 @@ check_non_deducible_conversion (tree parm, tree arg, int strict,
   if (same_type_p (parm, type))
     return unify_success (explain_p);
 
+  tsubst_flags_t complain = (explain_p ? tf_warning_or_error : tf_none);
   if (strict == DEDUCE_CONV)
     {
-      if (can_convert_arg (type, parm, NULL_TREE, flags,
-                          explain_p ? tf_warning_or_error : tf_none))
+      if (can_convert_arg (type, parm, NULL_TREE, flags, complain))
        return unify_success (explain_p);
     }
   else if (strict != DEDUCE_EXACT)
     {
-      if (can_convert_arg (parm, type,
-                          TYPE_P (arg) ? NULL_TREE : arg,
-                          flags, explain_p ? tf_warning_or_error : tf_none))
+      bool ok = false;
+      tree conv_arg = TYPE_P (arg) ? NULL_TREE : arg;
+      if (conv_p)
+       /* Avoid recalculating this in add_function_candidate.  */
+       ok = (*conv_p
+             = good_conversion (parm, type, conv_arg, flags, complain));
+      else
+       ok = can_convert_arg (parm, type, conv_arg, flags, complain);
+      if (ok)
        return unify_success (explain_p);
     }
 
@@ -20157,7 +20225,6 @@ type_unification_real (tree tparms,
                       unsigned int xnargs,
                       int subr,
                       unification_kind_t strict,
-                      int flags,
                       vec<deferred_access_check, va_gc> **checks,
                       bool explain_p)
 {
@@ -20345,57 +20412,6 @@ type_unification_real (tree tparms,
          return unify_parameter_deduction_failure (explain_p, tparm);
        }
 
-      /* DR 1391: All parameters have args, now check non-dependent parms for
-        convertibility.  */
-      if (saw_undeduced < 2)
-       for (ia = 0, parms = xparms, args = xargs, nargs = xnargs;
-            parms && parms != void_list_node && ia < nargs; )
-         {
-           parm = TREE_VALUE (parms);
-
-           if (TREE_CODE (parm) == TYPE_PACK_EXPANSION
-               && (!TREE_CHAIN (parms)
-                   || TREE_CHAIN (parms) == void_list_node))
-             /* For a function parameter pack that occurs at the end of the
-                parameter-declaration-list, the type A of each remaining
-                argument of the call is compared with the type P of the
-                declarator-id of the function parameter pack.  */
-             break;
-
-           parms = TREE_CHAIN (parms);
-
-           if (TREE_CODE (parm) == TYPE_PACK_EXPANSION)
-             /* For a function parameter pack that does not occur at the
-                end of the parameter-declaration-list, the type of the
-                parameter pack is a non-deduced context.  */
-             continue;
-
-           arg = args[ia];
-           ++ia;
-
-           if (uses_template_parms (parm))
-             continue;
-           if (check_non_deducible_conversion (parm, arg, strict, flags,
-                                               explain_p))
-             return 1;
-
-           if (BRACE_ENCLOSED_INITIALIZER_P (arg)
-               && (TREE_CODE (parm) == ARRAY_TYPE || is_std_init_list (parm)))
-             {
-               tree elt, elttype;
-               unsigned int i;
-
-               if (TREE_CODE (parm) == ARRAY_TYPE)
-                 elttype = TREE_TYPE (parm);
-               else
-                 elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
-               FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
-                 if (check_non_deducible_conversion (elttype, elt, strict,
-                                                     flags, explain_p))
-                   return 1;
-             }
-         }
-
       /* Now substitute into the default template arguments.  */
       for (i = 0; i < ntparms; i++)
        {
@@ -22019,7 +22035,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 
        if (type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
                                   args, nargs, 1, DEDUCE_EXACT,
-                                  LOOKUP_NORMAL, NULL, explain_p))
+                                  NULL, explain_p))
          return 1;
 
        if (flag_noexcept_type)
@@ -22663,7 +22679,8 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
                           args, ix,
                           (check_rettype || DECL_CONV_FN_P (fn)
                            ? TREE_TYPE (decl_type) : NULL_TREE),
-                          DEDUCE_EXACT, LOOKUP_NORMAL, /*explain_p=*/false,
+                          DEDUCE_EXACT, LOOKUP_NORMAL, NULL,
+                          /*explain_p=*/false,
                           /*decltype*/false)
       == error_mark_node)
     return NULL_TREE;
@@ -26799,7 +26816,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
 
       targs = make_tree_vec (TREE_VEC_LENGTH (tparms));
       int val = type_unification_real (tparms, targs, parms, &init, 1, 0,
-                                      DEDUCE_CALL, LOOKUP_NORMAL,
+                                      DEDUCE_CALL,
                                       NULL, /*explain_p=*/false);
       if (val > 0)
        {
@@ -26818,7 +26835,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
              else
                error ("unable to deduce %qT from %qE", type, init);
              type_unification_real (tparms, targs, parms, &init, 1, 0,
-                                    DEDUCE_CALL, LOOKUP_NORMAL,
+                                    DEDUCE_CALL,
                                     NULL, /*explain_p=*/true);
            }
          return error_mark_node;