PR c++/85149 - generic lambda and constexpr if.
[gcc.git] / gcc / cp / pt.c
index 02d448e99b67d1a866c064688d8b3485dd6a3aff..4c0d298cfcc58af357af92a48a43ff51f2569f2d 100644 (file)
@@ -1133,27 +1133,32 @@ optimize_specialization_lookup_p (tree tmpl)
 /* Make sure ARGS doesn't use any inappropriate typedefs; we should have
    gone through coerce_template_parms by now.  */
 
+static void
+verify_unstripped_args_1 (tree inner)
+{
+  for (int i = 0; i < TREE_VEC_LENGTH (inner); ++i)
+    {
+      tree arg = TREE_VEC_ELT (inner, i);
+      if (TREE_CODE (arg) == TEMPLATE_DECL)
+       /* OK */;
+      else if (TYPE_P (arg))
+       gcc_assert (strip_typedefs (arg, NULL) == arg);
+      else if (ARGUMENT_PACK_P (arg))
+       verify_unstripped_args_1 (ARGUMENT_PACK_ARGS (arg));
+      else if (strip_typedefs (TREE_TYPE (arg), NULL) != TREE_TYPE (arg))
+       /* Allow typedefs on the type of a non-type argument, since a
+          parameter can have them.  */;
+      else
+       gcc_assert (strip_typedefs_expr (arg, NULL) == arg);
+    }
+}
+
 static void
 verify_unstripped_args (tree args)
 {
   ++processing_template_decl;
   if (!any_dependent_template_arguments_p (args))
-    {
-      tree inner = INNERMOST_TEMPLATE_ARGS (args);
-      for (int i = 0; i < TREE_VEC_LENGTH (inner); ++i)
-       {
-         tree arg = TREE_VEC_ELT (inner, i);
-         if (TREE_CODE (arg) == TEMPLATE_DECL)
-           /* OK */;
-         else if (TYPE_P (arg))
-           gcc_assert (strip_typedefs (arg, NULL) == arg);
-         else if (strip_typedefs (TREE_TYPE (arg), NULL) != TREE_TYPE (arg))
-           /* Allow typedefs on the type of a non-type argument, since a
-              parameter can have them.  */;
-         else
-           gcc_assert (strip_typedefs_expr (arg, NULL) == arg);
-       }
-    }
+    verify_unstripped_args_1 (INNERMOST_TEMPLATE_ARGS (args));
   --processing_template_decl;
 }
 
@@ -1473,8 +1478,10 @@ is_specialization_of_friend (tree decl, tree friend_decl)
 
 /* Register the specialization SPEC as a specialization of TMPL with
    the indicated ARGS.  IS_FRIEND indicates whether the specialization
-   is actually just a friend declaration.  Returns SPEC, or an
-   equivalent prior declaration, if available.
+   is actually just a friend declaration.  ATTRLIST is the list of
+   attributes that the specialization is declared with or NULL when
+   it isn't.  Returns SPEC, or an equivalent prior declaration, if
+   available.
 
    We also store instantiations of field packs in the hash table, even
    though they are not themselves templates, to make lookup easier.  */
@@ -2058,7 +2065,8 @@ determine_specialization (tree template_id,
   /* We shouldn't be specializing a member template of an
      unspecialized class template; we already gave an error in
      check_specialization_scope, now avoid crashing.  */
-  if (template_count && DECL_CLASS_SCOPE_P (decl)
+  if (!VAR_P (decl)
+      && template_count && DECL_CLASS_SCOPE_P (decl)
       && template_class_depth (DECL_CONTEXT (decl)) > 0)
     {
       gcc_assert (errorcount);
@@ -2161,10 +2169,17 @@ determine_specialization (tree template_id,
             that the const qualification is the same.  Since
             get_bindings does not try to merge the "this" parameter,
             we must do the comparison explicitly.  */
-         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
-             && !same_type_p (TREE_VALUE (fn_arg_types),
-                              TREE_VALUE (decl_arg_types)))
-           continue;
+         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+           {
+             if (!same_type_p (TREE_VALUE (fn_arg_types),
+                               TREE_VALUE (decl_arg_types)))
+               continue;
+
+             /* And the ref-qualification.  */
+             if (type_memfn_rqual (TREE_TYPE (decl))
+                 != type_memfn_rqual (TREE_TYPE (fn)))
+               continue;
+           }
 
          /* Skip the "this" parameter and, for constructors of
             classes with virtual bases, the VTT parameter.  A
@@ -2203,6 +2218,11 @@ determine_specialization (tree template_id,
               specialize TMPL will produce DECL.  */
            continue;
 
+         if (uses_template_parms (targs))
+           /* We deduced something involving 'auto', which isn't a valid
+              template argument.  */
+           continue;
+
           /* Remove, from the set of candidates, all those functions
              whose constraints are not satisfied. */
           if (flag_concepts && !constraints_satisfied_p (fn, targs))
@@ -2270,6 +2290,11 @@ determine_specialization (tree template_id,
                         decl_arg_types))
             continue;
 
+         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+             && (type_memfn_rqual (TREE_TYPE (decl))
+                 != type_memfn_rqual (TREE_TYPE (fn))))
+           continue;
+
           // If the deduced arguments do not satisfy the constraints,
           // this is not a candidate.
           if (flag_concepts && !constraints_satisfied_p (fn))
@@ -2610,6 +2635,106 @@ check_unqualified_spec_or_inst (tree t, location_t loc)
     }
 }
 
+/* Warn for a template specialization SPEC that is missing some of a set
+   of function or type attributes that the template TEMPL is declared with.
+   ATTRLIST is a list of additional attributes that SPEC should be taken
+   to ultimately be declared with.  */
+
+static void
+warn_spec_missing_attributes (tree tmpl, tree spec, tree attrlist)
+{
+  if (DECL_FUNCTION_TEMPLATE_P (tmpl))
+    tmpl = DECL_TEMPLATE_RESULT (tmpl);
+
+  if (TREE_CODE (tmpl) != FUNCTION_DECL)
+    return;
+
+  /* Avoid warning if either declaration or its type is deprecated.  */
+  if (TREE_DEPRECATED (tmpl)
+      || TREE_DEPRECATED (spec))
+    return;
+
+  tree tmpl_type = TREE_TYPE (tmpl);
+  tree spec_type = TREE_TYPE (spec);
+
+  if (TREE_DEPRECATED (tmpl_type)
+      || TREE_DEPRECATED (spec_type)
+      || TREE_DEPRECATED (TREE_TYPE (tmpl_type))
+      || TREE_DEPRECATED (TREE_TYPE (spec_type)))
+    return;
+
+  tree tmpl_attrs[] = { DECL_ATTRIBUTES (tmpl), TYPE_ATTRIBUTES (tmpl_type) };
+  tree spec_attrs[] = { DECL_ATTRIBUTES (spec), TYPE_ATTRIBUTES (spec_type) };
+
+  if (!spec_attrs[0])
+    spec_attrs[0] = attrlist;
+  else if (!spec_attrs[1])
+    spec_attrs[1] = attrlist;
+
+  /* Avoid warning if the primary has no attributes.  */
+  if (!tmpl_attrs[0] && !tmpl_attrs[1])
+    return;
+
+  /* Avoid warning if either declaration contains an attribute on
+     the white list below.  */
+  const char* const whitelist[] = {
+    "error", "warning"
+  };
+
+  for (unsigned i = 0; i != 2; ++i)
+    for (unsigned j = 0; j != sizeof whitelist / sizeof *whitelist; ++j)
+      if (lookup_attribute (whitelist[j], tmpl_attrs[i])
+         || lookup_attribute (whitelist[j], spec_attrs[i]))
+       return;
+
+  /* Avoid warning if the difference between the primary and
+     the specialization is not in one of the attributes below.  */
+  const char* const blacklist[] = {
+    "alloc_align", "alloc_size", "assume_aligned", "format",
+    "format_arg", "malloc", "nonnull"
+  };
+
+  /* Put together a list of the black listed attributes that the primary
+     template is declared with that the specialization is not, in case
+     it's not apparent from the most recent declaration of the primary.  */
+  unsigned nattrs = 0;
+  pretty_printer str;
+
+  for (unsigned i = 0; i != sizeof blacklist / sizeof *blacklist; ++i)
+    {
+      for (unsigned j = 0; j != 2; ++j)
+       {
+         if (!lookup_attribute (blacklist[i], tmpl_attrs[j]))
+           continue;
+
+         for (unsigned k = 0; k != 1 + !!spec_attrs[1]; ++k)
+           {
+             if (lookup_attribute (blacklist[i], spec_attrs[k]))
+               break;
+
+             if (nattrs)
+               pp_string (&str, ", ");
+             pp_begin_quote (&str, pp_show_color (global_dc->printer));
+             pp_string (&str, blacklist[i]);
+             pp_end_quote (&str, pp_show_color (global_dc->printer));
+             ++nattrs;
+           }
+       }
+    }
+
+  if (!nattrs)
+    return;
+
+  if (warning_at (DECL_SOURCE_LOCATION (spec), OPT_Wmissing_attributes,
+                 "explicit specialization %q#D may be missing attributes",
+                 spec))
+    inform (DECL_SOURCE_LOCATION (tmpl),
+           nattrs > 1
+           ? G_("missing primary template attributes %s")
+           : G_("missing primary template attribute %s"),
+           pp_formatted_text (&str));
+}
+
 /* Check to see if the function just declared, as indicated in
    DECLARATOR, and in DECL, is a specialization of a function
    template.  We may also discover that the declaration is an explicit
@@ -2651,7 +2776,8 @@ tree
 check_explicit_specialization (tree declarator,
                               tree decl,
                               int template_count,
-                              int flags)
+                              int flags,
+                              tree attrlist)
 {
   int have_def = flags & 2;
   int is_friend = flags & 4;
@@ -3108,8 +3234,13 @@ check_explicit_specialization (tree declarator,
             it again.  Partial specializations will be registered in
             process_partial_specialization.  */
          if (!processing_template_decl)
-           decl = register_specialization (decl, gen_tmpl, targs,
-                                           is_friend, 0);
+           {
+             warn_spec_missing_attributes (gen_tmpl, decl, attrlist);
+
+             decl = register_specialization (decl, gen_tmpl, targs,
+                                             is_friend, 0);
+           }
+
 
          /* A 'structor should already have clones.  */
          gcc_assert (decl == error_mark_node
@@ -3912,7 +4043,8 @@ check_for_bare_parameter_packs (tree t)
     return false;
 
   /* A lambda might use a parameter pack from the containing context.  */
-  if (current_class_type && LAMBDA_TYPE_P (current_class_type))
+  if (current_class_type && LAMBDA_TYPE_P (current_class_type)
+      && CLASSTYPE_TEMPLATE_INFO (current_class_type))
     return false;
 
   if (TREE_CODE (t) == TYPE_DECL)
@@ -4299,6 +4431,9 @@ process_template_parm (tree list, location_t parm_loc, tree parm,
 
   pushdecl (decl);
 
+  if (defval && TREE_CODE (defval) == OVERLOAD)
+    lookup_keep (defval, true);
+  
   /* Build the parameter node linking the parameter declaration,
      its default argument (if any), and its constraints (if any). */
   parm = build_tree_list (defval, parm);
@@ -4542,6 +4677,7 @@ tree
 build_template_decl (tree decl, tree parms, bool member_template_p)
 {
   tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);
+  SET_DECL_LANGUAGE (tmpl, DECL_LANGUAGE (decl));
   DECL_TEMPLATE_PARMS (tmpl) = parms;
   DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
   DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
@@ -4715,10 +4851,13 @@ process_partial_specialization (tree decl)
     {
       if (!flag_concepts)
         error ("partial specialization %q+D does not specialize "
-              "any template arguments", decl);
+              "any template arguments; to define the primary template, "
+              "remove the template argument list", decl);
       else
         error ("partial specialization %q+D does not specialize any "
-              "template arguments and is not more constrained than", decl);
+              "template arguments and is not more constrained than "
+              "the primary template; to define the primary template, "
+              "remove the template argument list", decl);
       inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here");
     }
 
@@ -4962,7 +5101,7 @@ static void
 fixed_parameter_pack_p_1 (tree parm, struct find_parameter_pack_data *ppd)
 {
   /* A type parm can't refer to another parm.  */
-  if (TREE_CODE (parm) == TYPE_DECL)
+  if (TREE_CODE (parm) == TYPE_DECL || parm == error_mark_node)
     return;
   else if (TREE_CODE (parm) == PARM_DECL)
     {
@@ -6138,7 +6277,12 @@ convert_nontype_argument_function (tree type, tree expr,
 
  accept:
   if (TREE_CODE (type) == REFERENCE_TYPE)
-    fn = build_address (fn);
+    {
+      if (REFERENCE_REF_P (fn))
+       fn = TREE_OPERAND (fn, 0);
+      else
+       fn = build_address (fn);
+    }
   if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (fn)))
     fn = build_nop (type, fn);
 
@@ -6610,7 +6754,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
              else
                expr = cxx_constant_value (expr);
              if (errorcount > errs || warningcount + werrorcount > warns)
-               inform (loc, "in template argument for type %qT ", type);
+               inform (loc, "in template argument for type %qT", type);
              if (expr == error_mark_node)
                return NULL_TREE;
              /* else cxx_constant_value complained but gave us
@@ -7825,7 +7969,11 @@ convert_template_argument (tree parm,
     {
       tree t = TREE_TYPE (parm);
 
-      if (tree a = type_uses_auto (t))
+      if (TEMPLATE_PARM_LEVEL (get_template_parm_index (parm))
+         > TMPL_ARGS_DEPTH (args))
+       /* We don't have enough levels of args to do any substitution.  This
+          can happen in the context of -fnew-ttp-matching.  */;
+      else if (tree a = type_uses_auto (t))
        {
          t = do_auto_deduction (t, arg, a, complain, adc_unify, args);
          if (t == error_mark_node)
@@ -8087,6 +8235,11 @@ coerce_template_parms (tree parms,
   int variadic_args_p = 0;
   int post_variadic_parms = 0;
 
+  /* Adjustment to nparms for fixed parameter packs.  */
+  int fixed_pack_adjust = 0;
+  int fixed_packs = 0;
+  int missing = 0;
+
   /* Likewise for parameters with default arguments.  */
   int default_p = 0;
 
@@ -8131,6 +8284,7 @@ coerce_template_parms (tree parms,
              || (TREE_VEC_ELT (parms, nargs) != error_mark_node
                   && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
     {
+    bad_nargs:
       if (complain & tf_error)
        {
           if (variadic_p || default_p)
@@ -8242,11 +8396,17 @@ coerce_template_parms (tree parms,
              lost++;
              /* We are done with all of the arguments.  */
              arg_idx = nargs;
+             break;
            }
          else
            {
              pack_adjust = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) - 1;
              arg_idx += pack_adjust;
+             if (fixed_parameter_pack_p (TREE_VALUE (parm)))
+               {
+                 ++fixed_packs;
+                 fixed_pack_adjust += pack_adjust;
+               }
            }
           
           continue;
@@ -8304,12 +8464,18 @@ coerce_template_parms (tree parms,
            error ("template argument %d is invalid", arg_idx + 1);
        }
       else if (!arg)
-        /* This only occurs if there was an error in the template
-           parameter list itself (which we would already have
-           reported) that we are trying to recover from, e.g., a class
-           template with a parameter list such as
-           template<typename..., typename>.  */
-       ++lost;
+       {
+         /* This can occur if there was an error in the template
+            parameter list itself (which we would already have
+            reported) that we are trying to recover from, e.g., a class
+            template with a parameter list such as
+            template<typename..., typename> (cpp0x/variadic150.C).  */
+         ++lost;
+
+         /* This can also happen with a fixed parameter pack (71834).  */
+         if (arg_idx >= nargs)
+           ++missing;
+       }
       else
        arg = convert_template_argument (TREE_VALUE (parm),
                                         arg, new_args, complain, 
@@ -8322,20 +8488,36 @@ coerce_template_parms (tree parms,
   cp_unevaluated_operand = saved_unevaluated_operand;
   c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
 
-  if (variadic_p && arg_idx < nargs)
+  if (missing || arg_idx < nargs - variadic_args_p)
     {
-      if (complain & tf_error)
-       {
-         error ("wrong number of template arguments "
-                "(%d, should be %d)", nargs, arg_idx);
-         if (in_decl)
-           error ("provided for %q+D", in_decl);
-       }
-      return error_mark_node;
+      /* If we had fixed parameter packs, we didn't know how many arguments we
+        actually needed earlier; now we do.  */
+      nparms += fixed_pack_adjust;
+      variadic_p -= fixed_packs;
+      goto bad_nargs;
+    }
+
+  if (arg_idx < nargs)
+    {
+      /* We had some pack expansion arguments that will only work if the packs
+        are empty, but wait until instantiation time to complain.
+        See variadic-ttp3.C.  */
+      int len = nparms + (nargs - arg_idx);
+      tree args = make_tree_vec (len);
+      int i = 0;
+      for (; i < nparms; ++i)
+       TREE_VEC_ELT (args, i) = TREE_VEC_ELT (new_inner_args, i);
+      for (; i < len; ++i, ++arg_idx)
+       TREE_VEC_ELT (args, i) = TREE_VEC_ELT (inner_args,
+                                              arg_idx - pack_adjust);
+      new_inner_args = args;
     }
 
   if (lost)
-    return error_mark_node;
+    {
+      gcc_assert (!(complain & tf_error) || seen_error ());
+      return error_mark_node;
+    }
 
   if (CHECKING_P && !NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
     SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
@@ -10235,9 +10417,8 @@ tsubst_attributes (tree attributes, tree args,
            if (subst != t)
              {
                *p = subst;
-               do
+               while (*p)
                  p = &TREE_CHAIN (*p);
-               while (*p);
                *p = TREE_CHAIN (t);
                continue;
              }
@@ -10304,9 +10485,8 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
              *p = TREE_CHAIN (t);
              TREE_CHAIN (t) = NULL_TREE;
              *q = tsubst_attribute (t, decl_p, args, complain, in_decl);
-             do
+             while (*q)
                q = &TREE_CHAIN (*q);
-             while (*q);
            }
          else
            p = &TREE_CHAIN (t);
@@ -11483,6 +11663,46 @@ extract_local_specs (tree pattern, tsubst_flags_t complain)
   return data.extra;
 }
 
+/* Extract any uses of local_specializations from PATTERN and add them to ARGS
+   for use in PACK_EXPANSION_EXTRA_ARGS.  */
+
+tree
+build_extra_args (tree pattern, tree args, tsubst_flags_t complain)
+{
+  tree extra = args;
+  if (local_specializations)
+    if (tree locals = extract_local_specs (pattern, complain))
+      extra = tree_cons (NULL_TREE, extra, locals);
+  return extra;
+}
+
+/* Apply any local specializations from PACK_EXPANSION_EXTRA_ARGS and add the
+   normal template args to ARGS.  */
+
+tree
+add_extra_args (tree extra, tree args)
+{
+  if (extra && TREE_CODE (extra) == TREE_LIST)
+    {
+      for (tree elt = TREE_CHAIN (extra); elt; elt = TREE_CHAIN (elt))
+       {
+         /* The partial instantiation involved local declarations collected in
+            extract_local_specs; map from the general template to our local
+            context.  */
+         tree gen = TREE_PURPOSE (elt);
+         tree inst = TREE_VALUE (elt);
+         if (DECL_P (inst))
+           if (tree local = retrieve_local_specialization (inst))
+             inst = local;
+         /* else inst is already a full instantiation of the pack.  */
+         register_local_specialization (inst, gen);
+       }
+      gcc_assert (!TREE_PURPOSE (extra));
+      extra = TREE_VALUE (extra);
+    }
+  return add_to_template_args (extra, args);
+}
+
 /* Substitute ARGS into T, which is an pack expansion
    (i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a
    TREE_VEC with the substituted arguments, a PACK_EXPANSION_* node
@@ -11506,25 +11726,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
   pattern = PACK_EXPANSION_PATTERN (t);
 
   /* Add in any args remembered from an earlier partial instantiation.  */
-  tree extra = PACK_EXPANSION_EXTRA_ARGS (t);
-  if (extra && TREE_CODE (extra) == TREE_LIST)
-    {
-      for (tree elt = TREE_CHAIN (extra); elt; elt = TREE_CHAIN (elt))
-       {
-         /* The partial instantiation involved local declarations collected in
-            extract_local_specs; map from the general template to our local
-            context.  */
-         tree gen = TREE_PURPOSE (elt);
-         tree inst = TREE_VALUE (elt);
-         if (DECL_PACK_P (inst))
-           inst = retrieve_local_specialization (inst);
-         /* else inst is already a full instantiation of the pack.  */
-         register_local_specialization (inst, gen);
-       }
-      gcc_assert (!TREE_PURPOSE (extra));
-      extra = TREE_VALUE (extra);
-    }
-  args = add_to_template_args (extra, args);
+  args = add_extra_args (PACK_EXPANSION_EXTRA_ARGS (t), args);
 
   levels = TMPL_ARGS_DEPTH (args);
 
@@ -11576,7 +11778,9 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
            {
              /* This parameter pack was used in an unevaluated context.  Just
                 make a dummy decl, since it's only used for its type.  */
+             ++cp_unevaluated_operand;
              arg_pack = tsubst_decl (parm_pack, args, complain);
+             --cp_unevaluated_operand;
              if (arg_pack && DECL_PACK_P (arg_pack))
                /* Partial instantiation of the parm_pack, we can't build
                   up an argument pack yet.  */
@@ -11698,11 +11902,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
         have values for all the packs.  So remember these until then.  */
 
       t = make_pack_expansion (pattern, complain);
-      tree extra = args;
-      if (local_specializations)
-       if (tree locals = extract_local_specs (pattern, complain))
-         extra = tree_cons (NULL_TREE, extra, locals);
-      PACK_EXPANSION_EXTRA_ARGS (t) = extra;
+      PACK_EXPANSION_EXTRA_ARGS (t)
+       = build_extra_args (pattern, args, complain);
       return t;
     }
   else if (unsubstituted_packs)
@@ -12170,6 +12371,9 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
   tree parmtype = TREE_TYPE (parm);
   if (DECL_BY_REFERENCE (parm))
     parmtype = TREE_TYPE (parmtype);
+  if (parmtype == error_mark_node)
+    return error_mark_node;
+
   gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, parmtype));
 
   tree *slot;
@@ -12750,7 +12954,7 @@ enclosing_instantiation_of (tree otctx)
       for (; flambda_count < lambda_count && fn && LAMBDA_FUNCTION_P (fn);
           fn = decl_function_context (fn))
        ++flambda_count;
-      if (DECL_TEMPLATE_INFO (fn)
+      if ((fn && DECL_TEMPLATE_INFO (fn))
          ? most_general_template (fn) != most_general_template (tctx)
          : fn != tctx)
        continue;
@@ -13984,8 +14188,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                        = tsubst_constraint (constr, args, complain, in_decl);
                    else if (tree pl = CLASS_PLACEHOLDER_TEMPLATE (t))
                      {
-                       if (DECL_TEMPLATE_TEMPLATE_PARM_P (pl))
-                         pl = tsubst (pl, args, complain, in_decl);
+                       pl = tsubst_copy (pl, args, complain, in_decl);
                        CLASS_PLACEHOLDER_TEMPLATE (r) = pl;
                      }
                  }
@@ -14547,9 +14750,16 @@ tsubst_baselink (tree baselink, tree object_type,
   /* If lookup found a single function, mark it as used at this point.
      (If lookup found multiple functions the one selected later by
      overload resolution will be marked as used at that point.)  */
-  if (!template_id_p && !really_overloaded_fn (fns)
-      && !mark_used (OVL_FIRST (fns), complain) && !(complain & tf_error))
-    return error_mark_node;
+  if (!template_id_p && !really_overloaded_fn (fns))
+    {
+      tree fn = OVL_FIRST (fns);
+      bool ok = mark_used (fn, complain);
+      if (!ok && !(complain & tf_error))
+       return error_mark_node;
+      if (ok && BASELINK_P (baselink))
+       /* We might have instantiated an auto function.  */
+       TREE_TYPE (baselink) = TREE_TYPE (fn);
+    }
 
   if (BASELINK_P (baselink))
     {
@@ -15780,7 +15990,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
   tree auto_node = type_uses_auto (TREE_TYPE (decl));
   if (auto_node && init)
     TREE_TYPE (decl)
-      = do_auto_deduction (TREE_TYPE (decl), init, auto_node);
+      = do_auto_deduction (TREE_TYPE (decl), init, auto_node, complain);
 
   gcc_assert (!type_dependent_expression_p (decl));
 
@@ -16293,8 +16503,24 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
     case IF_STMT:
       stmt = begin_if_stmt ();
       IF_STMT_CONSTEXPR_P (stmt) = IF_STMT_CONSTEXPR_P (t);
+      if (IF_STMT_CONSTEXPR_P (t))
+       args = add_extra_args (IF_STMT_EXTRA_ARGS (t), args);
       tmp = RECUR (IF_COND (t));
       tmp = finish_if_stmt_cond (tmp, stmt);
+      if (IF_STMT_CONSTEXPR_P (t)
+         && instantiation_dependent_expression_p (tmp))
+       {
+         /* We're partially instantiating a generic lambda, but the condition
+            of the constexpr if is still dependent.  Don't substitute into the
+            branches now, just remember the template arguments.  */
+         do_poplevel (IF_SCOPE (stmt));
+         IF_COND (stmt) = IF_COND (t);
+         THEN_CLAUSE (stmt) = THEN_CLAUSE (t);
+         ELSE_CLAUSE (stmt) = ELSE_CLAUSE (t);
+         IF_STMT_EXTRA_ARGS (stmt) = build_extra_args (t, args, complain);
+         add_stmt (stmt);
+         break;
+       }
       if (IF_STMT_CONSTEXPR_P (t) && integer_zerop (tmp))
        /* Don't instantiate the THEN_CLAUSE. */;
       else
@@ -17059,6 +17285,10 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       bool nested = cfun;
       if (nested)
        push_function_context ();
+      else
+       /* Still increment function_depth so that we don't GC in the
+          middle of an expression.  */
+       ++function_depth;
 
       local_specialization_stack s (lss_copy);
 
@@ -17073,6 +17303,8 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
       if (nested)
        pop_function_context ();
+      else
+       --function_depth;
 
       /* The capture list was built up in reverse order; fix that now.  */
       LAMBDA_EXPR_CAPTURE_LIST (r)
@@ -17179,14 +17411,14 @@ tsubst_copy_and_build (tree t,
        if (targs)
          targs = tsubst_template_args (targs, args, complain, in_decl);
        if (targs == error_mark_node)
-         return error_mark_node;
+         RETURN (error_mark_node);
 
        if (TREE_CODE (templ) == SCOPE_REF)
          {
            tree name = TREE_OPERAND (templ, 1);
            tree tid = lookup_template_function (name, targs);
            TREE_OPERAND (templ, 1) = tid;
-           return templ;
+           RETURN (templ);
          }
 
        if (variable_template_p (templ))
@@ -17262,6 +17494,8 @@ tsubst_copy_and_build (tree t,
       {
        tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
        tree op0 = RECUR (TREE_OPERAND (t, 0));
+       if (op0 == error_mark_node)
+         RETURN (error_mark_node);
        RETURN (build1 (CONVERT_EXPR, type, op0));
       }
 
@@ -17333,8 +17567,7 @@ tsubst_copy_and_build (tree t,
                                complain|decltype_flag));
 
     case FIX_TRUNC_EXPR:
-      RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)),
-                                false, complain));
+      gcc_unreachable ();    
 
     case ADDR_EXPR:
       op1 = TREE_OPERAND (t, 0);
@@ -17410,7 +17643,7 @@ tsubst_copy_and_build (tree t,
       {
        tree op0 = RECUR (TREE_OPERAND (t, 0));
        tree op1 = RECUR (TREE_OPERAND (t, 1));
-       return fold_build_pointer_plus (op0, op1);
+       RETURN (fold_build_pointer_plus (op0, op1));
       }
 
     case SCOPE_REF:
@@ -19815,28 +20048,49 @@ type_unification_real (tree tparms,
          if (targ || tparm == error_mark_node)
            continue;
          tree parm = TREE_VALUE (tparm);
-
-         if (TREE_CODE (parm) == PARM_DECL
-             && uses_template_parms (TREE_TYPE (parm))
-             && saw_undeduced < 2)
-           continue;
-
          tree arg = TREE_PURPOSE (tparm);
          reopen_deferring_access_checks (*checks);
          location_t save_loc = input_location;
          if (DECL_P (parm))
            input_location = DECL_SOURCE_LOCATION (parm);
-         arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
-         if (!uses_template_parms (arg))
-           arg = convert_template_argument (parm, arg, full_targs, complain,
-                                            i, NULL_TREE);
-         else if (saw_undeduced < 2)
-           arg = NULL_TREE;
+         if (saw_undeduced == 1)
+           ++processing_template_decl;
+
+         if (saw_undeduced == 1
+             && TREE_CODE (parm) == PARM_DECL
+             && uses_template_parms (TREE_TYPE (parm)))
+           {
+             /* The type of this non-type parameter depends on undeduced
+                parameters.  Don't try to use its default argument yet,
+                but do check whether the arguments we already have cause
+                substitution failure, so that that happens before we try
+                later default arguments (78489).  */
+             tree type = tsubst (TREE_TYPE (parm), full_targs, complain,
+                                 NULL_TREE);
+             if (type == error_mark_node)
+               arg = error_mark_node;
+             else
+               arg = NULL_TREE;
+           }
          else
-           arg = error_mark_node;
+           {
+             arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
+
+             if (!uses_template_parms (arg))
+               arg = convert_template_argument (parm, arg, full_targs,
+                                                complain, i, NULL_TREE);
+             else if (saw_undeduced == 1)
+               arg = NULL_TREE;
+             else
+               arg = error_mark_node;
+           }
+
+         if (saw_undeduced == 1)
+           --processing_template_decl;
          input_location = save_loc;
          *checks = get_deferred_access_checks ();
          pop_deferring_access_checks ();
+
          if (arg == error_mark_node)
            return 1;
          else if (arg)
@@ -20444,6 +20698,11 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
       tree parm_pack = TREE_VALUE (pack);
       int idx, level;
 
+      /* Only template parameter packs can be deduced, not e.g. function
+        parameter packs or __bases or __integer_pack.  */
+      if (!TEMPLATE_PARM_P (parm_pack))
+       continue;
+
       /* Determine the index and level of this parameter pack.  */
       template_parm_level_and_index (parm_pack, &level, &idx);
       if (level < levels)
@@ -21054,14 +21313,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
         template-parameter exactly, except that a template-argument
         deduced from an array bound may be of any integral type.
         The non-type parameter might use already deduced type parameters.  */
-      ++processing_template_decl;
-      tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
-      --processing_template_decl;
-      if (tree a = type_uses_auto (tparm))
+      tparm = TREE_TYPE (parm);
+      if (TEMPLATE_PARM_LEVEL (parm) > TMPL_ARGS_DEPTH (targs))
+       /* We don't have enough levels of args to do any substitution.  This
+          can happen in the context of -fnew-ttp-matching.  */;
+      else
        {
-         tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify);
-         if (tparm == error_mark_node)
-           return 1;
+         ++processing_template_decl;
+         tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
+         --processing_template_decl;
+
+         if (tree a = type_uses_auto (tparm))
+           {
+             tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify);
+             if (tparm == error_mark_node)
+               return 1;
+           }
        }
 
       if (!TREE_TYPE (arg))
@@ -23290,6 +23557,9 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
   bool push_to_top, nested;
   tree fn_context;
   fn_context = decl_function_context (d);
+  if (LAMBDA_FUNCTION_P (d))
+    /* tsubst_lambda_expr resolved any references to enclosing functions.  */
+    fn_context = NULL_TREE;
   nested = current_function_decl != NULL_TREE;
   push_to_top = !(nested && fn_context == current_function_decl);
 
@@ -23541,6 +23811,7 @@ static tree
 tsubst_initializer_list (tree t, tree argvec)
 {
   tree inits = NULL_TREE;
+  tree target_ctor = error_mark_node;
 
   for (; t; t = TREE_CHAIN (t))
     {
@@ -23657,6 +23928,28 @@ tsubst_initializer_list (tree t, tree argvec)
               in_base_initializer = 0;
             }
 
+         if (target_ctor != error_mark_node
+             && init != error_mark_node)
+           {
+             error ("mem-initializer for %qD follows constructor delegation",
+                    decl);
+             return inits;
+           }
+         /* Look for a target constructor. */
+         if (init != error_mark_node
+             && decl && CLASS_TYPE_P (decl)
+             && same_type_p (decl, current_class_type))
+           {
+             maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS);
+             if (inits)
+               {
+                 error ("constructor delegation follows mem-initializer for %qD",
+                        TREE_PURPOSE (inits));
+                 continue;
+               }
+             target_ctor = init;
+           }
+
           if (decl)
             {
               init = build_tree_list (decl, init);
@@ -23776,7 +24069,10 @@ invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
 {
   if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     return false;
-  else if (POINTER_TYPE_P (type))
+  else if (TYPE_PTR_P (type))
+    return false;
+  else if (TREE_CODE (type) == REFERENCE_TYPE
+          && !TYPE_REF_IS_RVALUE (type))
     return false;
   else if (TYPE_PTRMEM_P (type))
     return false;
@@ -24472,7 +24768,8 @@ type_dependent_expression_p (tree expression)
   if (TREE_CODE (expression) == FUNCTION_DECL
       && !(DECL_CLASS_SCOPE_P (expression)
           && dependent_type_p (DECL_CONTEXT (expression)))
-      && !(DECL_FRIEND_P (expression)
+      && !(DECL_LANG_SPECIFIC (expression)
+          && DECL_FRIEND_P (expression)
           && (!DECL_FRIEND_CONTEXT (expression)
               || dependent_type_p (DECL_FRIEND_CONTEXT (expression))))
       && !DECL_LOCAL_FUNCTION_P (expression))
@@ -24873,6 +25170,39 @@ any_dependent_template_arguments_p (const_tree args)
   return false;
 }
 
+/* Returns true if ARGS contains any errors.  */
+
+bool
+any_erroneous_template_args_p (const_tree args)
+{
+  int i;
+  int j;
+
+  if (args == error_mark_node)
+    return true;
+
+  if (args && TREE_CODE (args) != TREE_VEC)
+    {
+      if (tree ti = get_template_info (args))
+       args = TI_ARGS (ti);
+      else
+       args = NULL_TREE;
+    }
+
+  if (!args)
+    return false;
+
+  for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+    {
+      const_tree level = TMPL_ARGS_LEVEL (args, i + 1);
+      for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
+       if (error_operand_p (TREE_VEC_ELT (level, j)))
+         return true;
+    }
+
+  return false;
+}
+
 /* Returns TRUE if the template TMPL is type-dependent.  */
 
 bool
@@ -24984,6 +25314,9 @@ resolve_typename_type (tree type, bool only_current_p)
   gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
 
   scope = TYPE_CONTEXT (type);
+  /* We shouldn't have built a TYPENAME_TYPE with a non-dependent scope.  */
+  gcc_checking_assert (uses_template_parms (scope));
+
   /* Usually the non-qualified identifier of a TYPENAME_TYPE is
      TYPE_IDENTIFIER (type). But when 'type' is a typedef variant of
      a TYPENAME_TYPE node, then TYPE_NAME (type) is set to the TYPE_DECL representing
@@ -25020,8 +25353,6 @@ resolve_typename_type (tree type, bool only_current_p)
     /* scope is either the template itself or a compatible instantiation
        like X<T>, so look up the name in the original template.  */
     scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope);
-  /* We shouldn't have built a TYPENAME_TYPE with a non-dependent scope.  */
-  gcc_checking_assert (uses_template_parms (scope));
   /* If scope has no fields, it can't be a current instantiation.  Check this
      before currently_open_class to avoid infinite recursion (71515).  */
   if (!TYPE_FIELDS (scope))
@@ -25192,7 +25523,8 @@ build_non_dependent_expr (tree expr)
   gcc_assert (TREE_TYPE (expr) != unknown_type_node);
 
   /* Otherwise, build a NON_DEPENDENT_EXPR.  */
-  return build1 (NON_DEPENDENT_EXPR, TREE_TYPE (expr), expr);
+  return build1_loc (EXPR_LOCATION (orig_expr), NON_DEPENDENT_EXPR,
+                    TREE_TYPE (expr), expr);
 }
 
 /* ARGS is a vector of expressions as arguments to a function call.
@@ -25448,7 +25780,8 @@ dguide_name (tree tmpl)
 bool
 dguide_name_p (tree name)
 {
-  return (TREE_TYPE (name)
+  return (TREE_CODE (name) == IDENTIFIER_NODE
+         && TREE_TYPE (name)
          && !strncmp (IDENTIFIER_POINTER (name), dguide_base,
                       strlen (dguide_base)));
 }
@@ -25515,8 +25848,21 @@ rewrite_template_parm (tree olddecl, unsigned index, unsigned level,
          = TEMPLATE_TYPE_PARM_FOR_CLASS (oldtype);
     }
   else
-    newtype = tsubst (TREE_TYPE (olddecl), tsubst_args,
-                     complain, NULL_TREE);
+    {
+      newtype = TREE_TYPE (olddecl);
+      if (type_uses_auto (newtype))
+       {
+         // Substitute once to fix references to other template parameters.
+         newtype = tsubst (newtype, tsubst_args,
+                           complain|tf_partial, NULL_TREE);
+         // Now substitute again to reduce the level of the auto.
+         newtype = tsubst (newtype, current_template_args (),
+                           complain, NULL_TREE);
+       }
+      else
+       newtype = tsubst (newtype, tsubst_args,
+                         complain, NULL_TREE);
+    }
 
   tree newdecl
     = build_decl (DECL_SOURCE_LOCATION (olddecl), TREE_CODE (olddecl),
@@ -25555,7 +25901,7 @@ rewrite_template_parm (tree olddecl, unsigned index, unsigned level,
          // Substitute ttargs into ttparms to fix references to
          // other template parameters.
          ttparms = tsubst_template_parms_level (ttparms, ttargs,
-                                                complain);
+                                                complain|tf_partial);
          // Now substitute again with args based on tparms, to reduce
          // the level of the ttparms.
          ttargs = current_template_args ();
@@ -25935,17 +26281,6 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
   return cp_build_qualified_type (TREE_TYPE (call), cp_type_quals (ptype));
 }
 
-/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
-   from INIT.  AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE.  */
-
-tree
-do_auto_deduction (tree type, tree init, tree auto_node)
-{
-  return do_auto_deduction (type, init, auto_node,
-                            tf_warning_or_error,
-                            adc_unspecified);
-}
-
 /* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
    from INIT.  AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE.
    The CONTEXT determines the context in which auto deduction is performed
@@ -25981,7 +26316,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
     /* C++17 class template argument deduction.  */
     return do_class_deduction (type, tmpl, init, flags, complain);
 
-  if (TREE_TYPE (init) == NULL_TREE)
+  if (init == NULL_TREE || TREE_TYPE (init) == NULL_TREE)
     /* Nothing we can do with this, even in deduction context.  */
     return type;