pt.c (value_dependent_expression_p): Tweak new cases to better match the wording...
[gcc.git] / gcc / cp / pt.c
index 243464dbb88b893e2cfb9bb3c7e450d4a23fc893..fde3091951747e7f9ed4c7195b41baa71ade989a 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle parameterized types (templates) for GNU -*- C++ -*-.
-   Copyright (C) 1992-2015 Free Software Foundation, Inc.
+   Copyright (C) 1992-2016 Free Software Foundation, Inc.
    Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
    Rewritten by Jason Merrill (jason@cygnus.com).
 
@@ -27,21 +27,15 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
 #include "cp-tree.h"
-#include "c-family/c-common.h"
 #include "timevar.h"
 #include "stringpool.h"
 #include "varasm.h"
 #include "attribs.h"
 #include "stor-layout.h"
 #include "intl.h"
-#include "flags.h"
 #include "c-family/c-objc.h"
 #include "cp-objcp-common.h"
-#include "tree-inline.h"
-#include "decl.h"
 #include "toplev.h"
 #include "tree-iterator.h"
 #include "type-utils.h"
@@ -166,8 +160,8 @@ static tree convert_nontype_argument_function (tree, tree, tsubst_flags_t);
 static tree convert_nontype_argument (tree, tree, tsubst_flags_t);
 static tree convert_template_argument (tree, tree, tree,
                                       tsubst_flags_t, int, tree);
-static int for_each_template_parm (tree, tree_fn_t, void*,
-                                  hash_set<tree> *, bool);
+static tree for_each_template_parm (tree, tree_fn_t, void*,
+                                   hash_set<tree> *, bool);
 static tree expand_template_argument_pack (tree);
 static tree build_template_parm_index (int, int, int, tree, tree);
 static bool inline_needs_template_parms (tree, bool);
@@ -184,6 +178,7 @@ static int check_cv_quals_for_unify (int, tree, tree);
 static void template_parm_level_and_index (tree, int*, int*);
 static int unify_pack_expansion (tree, tree, tree,
                                 tree, unification_kind_t, bool, bool);
+static tree copy_template_args (tree);
 static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
@@ -220,6 +215,7 @@ static tree listify_autos (tree, tree);
 static tree tsubst_template_parm (tree, tree, tsubst_flags_t);
 static tree instantiate_alias_template (tree, tree, tsubst_flags_t);
 static bool complex_alias_template_p (const_tree tmpl);
+static tree tsubst_attributes (tree, tree, tsubst_flags_t, tree);
 
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -334,7 +330,8 @@ get_template_info (const_tree t)
   if (!t || t == error_mark_node)
     return NULL;
 
-  if (TREE_CODE (t) == NAMESPACE_DECL)
+  if (TREE_CODE (t) == NAMESPACE_DECL
+      || TREE_CODE (t) == PARM_DECL)
     return NULL;
 
   if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
@@ -374,16 +371,20 @@ template_class_depth (tree type)
 {
   int depth;
 
-  for (depth = 0;
-       type && TREE_CODE (type) != NAMESPACE_DECL;
-       type = (TREE_CODE (type) == FUNCTION_DECL)
-        ? CP_DECL_CONTEXT (type) : CP_TYPE_CONTEXT (type))
+  for (depth = 0; type && TREE_CODE (type) != NAMESPACE_DECL; )
     {
       tree tinfo = get_template_info (type);
 
       if (tinfo && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo))
          && uses_template_parms (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo))))
        ++depth;
+
+      if (DECL_P (type))
+       type = CP_DECL_CONTEXT (type);
+      else if (LAMBDA_TYPE_P (type))
+       type = LAMBDA_TYPE_EXTRA_SCOPE (type);
+      else
+       type = CP_TYPE_CONTEXT (type);
     }
 
   return depth;
@@ -441,21 +442,8 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
          break;
 
        case PARM_DECL:
-         {
-           /* Make a CONST_DECL as is done in process_template_parm.
-              It is ugly that we recreate this here; the original
-              version built in process_template_parm is no longer
-              available.  */
-           tree decl = build_decl (DECL_SOURCE_LOCATION (parm),
-                                   CONST_DECL, DECL_NAME (parm),
-                                   TREE_TYPE (parm));
-           DECL_ARTIFICIAL (decl) = 1;
-           TREE_CONSTANT (decl) = 1;
-           TREE_READONLY (decl) = 1;
-           DECL_INITIAL (decl) = DECL_INITIAL (parm);
-           SET_DECL_TEMPLATE_PARM_P (decl);
-           pushdecl (decl);
-         }
+         /* Push the CONST_DECL.  */
+         pushdecl (TEMPLATE_PARM_DECL (DECL_INITIAL (parm)));
          break;
 
        default:
@@ -874,14 +862,20 @@ maybe_new_partial_specialization (tree type)
       if (!current_template_parms)
         return NULL_TREE;
 
+      // The injected-class-name is not a new partial specialization.
+      if (DECL_SELF_REFERENCE_P (TYPE_NAME (type)))
+       return NULL_TREE;
+
       // If the constraints are not the same as those of the primary
       // then, we can probably create a new specialization.
       tree type_constr = current_template_constraints ();
 
       if (type == TREE_TYPE (tmpl))
-       if (tree main_constr = get_constraints (tmpl))
+       {
+         tree main_constr = get_constraints (tmpl);
          if (equivalent_constraints (type_constr, main_constr))
            return NULL_TREE;
+       }
 
       // Also, if there's a pre-existing specialization with matching
       // constraints, then this also isn't new.
@@ -1134,9 +1128,8 @@ optimize_specialization_lookup_p (tree tmpl)
    gone through coerce_template_parms by now.  */
 
 static void
-check_unstripped_args (tree args ATTRIBUTE_UNUSED)
+verify_unstripped_args (tree args)
 {
-#ifdef ENABLE_CHECKING
   ++processing_template_decl;
   if (!any_dependent_template_arguments_p (args))
     {
@@ -1156,7 +1149,6 @@ check_unstripped_args (tree args ATTRIBUTE_UNUSED)
        }
     }
   --processing_template_decl;
-#endif
 }
 
 /* Retrieve the specialization (in the sense of [temp.spec] - a
@@ -1192,7 +1184,8 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
                  ? TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))
                  : template_class_depth (DECL_CONTEXT (tmpl))));
 
-  check_unstripped_args (args);
+  if (flag_checking)
+    verify_unstripped_args (args);
 
   if (optimize_specialization_lookup_p (tmpl))
     {
@@ -2820,14 +2813,6 @@ check_explicit_specialization (tree declarator,
                  error ("%qD is not a template function", dname);
                  fns = error_mark_node;
                }
-             else
-               {
-                 tree fn = OVL_CURRENT (fns);
-                 if (!is_associated_namespace (CP_DECL_CONTEXT (decl),
-                                               CP_DECL_CONTEXT (fn)))
-                   error ("%qD is not declared in %qD",
-                          decl, current_namespace);
-               }
            }
 
          declarator = lookup_template_function (fns, NULL_TREE);
@@ -2961,6 +2946,14 @@ check_explicit_specialization (tree declarator,
        return error_mark_node;
       else
        {
+         if (!ctype && !was_template_id
+             && (specialization || member_specialization
+                 || explicit_instantiation)
+             && !is_associated_namespace (CP_DECL_CONTEXT (decl),
+                                          CP_DECL_CONTEXT (tmpl)))
+           error ("%qD is not declared in %qD",
+                  tmpl, current_namespace);
+
          tree gen_tmpl = most_general_template (tmpl);
 
          if (explicit_instantiation)
@@ -3407,6 +3400,9 @@ struct find_parameter_pack_data
 
   /* Set of AST nodes that have been visited by the traversal.  */
   hash_set<tree> *visited;
+
+  /* True iff we're making a type pack expansion.  */
+  bool type_pack_expansion_p;
 };
 
 /* Identifies all of the argument packs that occur in a template
@@ -3443,6 +3439,12 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     case TEMPLATE_TYPE_PARM:
       t = TYPE_MAIN_VARIANT (t);
     case TEMPLATE_TEMPLATE_PARM:
+      /* If the placeholder appears in the decl-specifier-seq of a function
+        parameter pack (14.6.3), or the type-specifier-seq of a type-id that
+        is a pack expansion, the invented template parameter is a template
+        parameter pack.  */
+      if (ppd->type_pack_expansion_p && is_auto_or_concept (t))
+       TEMPLATE_TYPE_PARAMETER_PACK (t) = true;
       if (TEMPLATE_TYPE_PARAMETER_PACK (t))
         parameter_pack_p = true;
       break;
@@ -3562,6 +3564,20 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
       *walk_subtrees = 0;
       return NULL_TREE;
 
+    case DECLTYPE_TYPE:
+      {
+       /* When traversing a DECLTYPE_TYPE_EXPR, we need to set
+          type_pack_expansion_p to false so that any placeholders
+          within the expression don't get marked as parameter packs.  */
+       bool type_pack_expansion_p = ppd->type_pack_expansion_p;
+       ppd->type_pack_expansion_p = false;
+       cp_walk_tree (&DECLTYPE_TYPE_EXPR (t), &find_parameter_packs_r,
+                     ppd, ppd->visited);
+       ppd->type_pack_expansion_p = type_pack_expansion_p;
+       *walk_subtrees = 0;
+       return NULL_TREE;
+      }
+
     default:
       return NULL_TREE;
     }
@@ -3577,6 +3593,7 @@ uses_parameter_packs (tree t)
   struct find_parameter_pack_data ppd;
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = new hash_set<tree>;
+  ppd.type_pack_expansion_p = false;
   cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
   delete ppd.visited;
   return parameter_packs != NULL_TREE;
@@ -3627,6 +3644,8 @@ make_pack_expansion (tree arg)
          class expansion.  */
       ppd.visited = new hash_set<tree>;
       ppd.parameter_packs = &parameter_packs;
+      ppd.type_pack_expansion_p = true;
+      gcc_assert (TYPE_P (TREE_PURPOSE (arg)));
       cp_walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r, 
                     &ppd, ppd.visited);
 
@@ -3677,6 +3696,8 @@ make_pack_expansion (tree arg)
       /* Propagate type and const-expression information.  */
       TREE_TYPE (result) = TREE_TYPE (arg);
       TREE_CONSTANT (result) = TREE_CONSTANT (arg);
+      /* Mark this read now, since the expansion might be length 0.  */
+      mark_exp_read (arg);
     }
   else
     /* Just use structural equality for these TYPE_PACK_EXPANSIONS;
@@ -3686,6 +3707,7 @@ make_pack_expansion (tree arg)
   /* Determine which parameter packs will be expanded.  */
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = new hash_set<tree>;
+  ppd.type_pack_expansion_p = TYPE_P (arg);
   cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited);
   delete ppd.visited;
 
@@ -3733,6 +3755,7 @@ check_for_bare_parameter_packs (tree t)
 
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = new hash_set<tree>;
+  ppd.type_pack_expansion_p = false;
   cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
   delete ppd.visited;
 
@@ -4201,10 +4224,9 @@ template_parm_to_arg (tree t)
          /* Turn this argument into a TYPE_ARGUMENT_PACK
             with a single element, which expands T.  */
          tree vec = make_tree_vec (1);
-#ifdef ENABLE_CHECKING
-         SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
-           (vec, TREE_VEC_LENGTH (vec));
-#endif
+         if (CHECKING_P)
+           SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
+
          TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
 
          t = cxx_make_type (TYPE_ARGUMENT_PACK);
@@ -4221,10 +4243,9 @@ template_parm_to_arg (tree t)
             with a single element, which expands T.  */
          tree vec = make_tree_vec (1);
          tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
-#ifdef ENABLE_CHECKING
-         SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
-           (vec, TREE_VEC_LENGTH (vec));
-#endif
+         if (CHECKING_P)
+           SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
+
          t = convert_from_reference (t);
          TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
 
@@ -4265,9 +4286,8 @@ template_parms_to_args (tree parms)
       for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)
        TREE_VEC_ELT (a, i) = template_parm_to_arg (TREE_VEC_ELT (a, i));
 
-#ifdef ENABLE_CHECKING
-      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
-#endif
+      if (CHECKING_P)
+       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
 
       if (length > 1)
        TREE_VEC_ELT (args, --l) = a;
@@ -4505,8 +4525,8 @@ process_partial_specialization (tree decl)
     = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (maintmpl)));
   if (comp_template_args (inner_args, INNERMOST_TEMPLATE_ARGS (main_args))
       && (!flag_concepts
-         || !subsumes_constraints (current_template_constraints (),
-                                   get_constraints (maintmpl))))
+         || !strictly_subsumes (current_template_constraints (),
+                                get_constraints (maintmpl))))
     {
       if (!flag_concepts)
         error ("partial specialization %q+D does not specialize "
@@ -4772,6 +4792,7 @@ fixed_parameter_pack_p (tree parm)
   struct find_parameter_pack_data ppd;
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = new hash_set<tree>;
+  ppd.type_pack_expansion_p = false;
 
   fixed_parameter_pack_p_1 (parm, &ppd);
 
@@ -5636,8 +5657,7 @@ instantiate_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
 
      as two declarations of the same function, for example.  */
   if (processing_template_decl
-      && !instantiation_dependent_expression_p (expr)
-      && potential_constant_expression (expr))
+      && potential_nondependent_constant_expression (expr))
     {
       processing_template_decl_sentinel s;
       expr = instantiate_non_dependent_expr_internal (expr, complain);
@@ -5651,6 +5671,27 @@ instantiate_non_dependent_expr (tree expr)
   return instantiate_non_dependent_expr_sfinae (expr, tf_error);
 }
 
+/* Like instantiate_non_dependent_expr, but return NULL_TREE rather than
+   an uninstantiated expression.  */
+
+tree
+instantiate_non_dependent_or_null (tree expr)
+{
+  if (expr == NULL_TREE)
+    return NULL_TREE;
+  if (processing_template_decl)
+    {
+      if (!potential_nondependent_constant_expression (expr))
+       expr = NULL_TREE;
+      else
+       {
+         processing_template_decl_sentinel s;
+         expr = instantiate_non_dependent_expr_internal (expr, tf_error);
+       }
+    }
+  return expr;
+}
+
 /* True iff T is a specialization of a variable template.  */
 
 bool
@@ -6199,10 +6240,8 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
   if (TYPE_REF_OBJ_P (type)
       && has_value_dependent_address (expr))
     /* If we want the address and it's value-dependent, don't fold.  */;
-  else if (!type_unknown_p (expr)
-          && processing_template_decl
-          && !instantiation_dependent_expression_p (expr)
-          && potential_constant_expression (expr))
+  else if (processing_template_decl
+          && potential_nondependent_constant_expression (expr))
     non_dep = true;
   if (error_operand_p (expr))
     return error_mark_node;
@@ -6221,7 +6260,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
   /* 14.3.2/5: The null pointer{,-to-member} conversion is applied
      to a non-type argument of "nullptr".  */
   if (expr == nullptr_node && TYPE_PTR_OR_PTRMEM_P (type))
-    expr = convert (type, expr);
+    expr = fold_simple (convert (type, expr));
 
   /* In C++11, integral or enumeration non-type template arguments can be
      arbitrary constant expressions.  Pointer and pointer to
@@ -6909,7 +6948,8 @@ canonicalize_type_argument (tree arg, tsubst_flags_t complain)
   tree canon = strip_typedefs (arg, &removed_attributes);
   if (removed_attributes
       && (complain & tf_warning))
-    warning (0, "ignoring attributes on template argument %qT", arg);
+    warning (OPT_Wignored_attributes,
+            "ignoring attributes on template argument %qT", arg);
   return canon;
 }
 
@@ -7230,6 +7270,7 @@ convert_template_argument (tree parm,
           if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE
               && TREE_CODE (TREE_TYPE (TREE_TYPE (inner))) == FUNCTION_TYPE
               && TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE
+              && 0 < TREE_OPERAND_LENGTH (inner)
               && reject_gcc_builtin (TREE_OPERAND (inner, 0)))
               return error_mark_node;
         }
@@ -7385,10 +7426,9 @@ coerce_template_parameter_pack (tree parms,
     }
 
   SET_ARGUMENT_PACK_ARGS (argument_pack, packed_args);
-#ifdef ENABLE_CHECKING
-  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (packed_args,
-                                      TREE_VEC_LENGTH (packed_args));
-#endif
+  if (CHECKING_P)
+    SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (packed_args,
+                                        TREE_VEC_LENGTH (packed_args));
   return argument_pack;
 }
 
@@ -7695,11 +7735,9 @@ coerce_template_parms (tree parms,
   if (lost)
     return error_mark_node;
 
-#ifdef ENABLE_CHECKING
-  if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
+  if (CHECKING_P && !NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
     SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
                                         TREE_VEC_LENGTH (new_inner_args));
-#endif
 
   return new_inner_args;
 }
@@ -7873,9 +7911,9 @@ template_args_equal (tree ot, tree nt)
    template arguments.  Returns 0 otherwise, and updates OLDARG_PTR and
    NEWARG_PTR with the offending arguments if they are non-NULL.  */
 
-static int
-comp_template_args_with_info (tree oldargs, tree newargs,
-                             tree *oldarg_ptr, tree *newarg_ptr)
+int
+comp_template_args (tree oldargs, tree newargs,
+                   tree *oldarg_ptr, tree *newarg_ptr)
 {
   int i;
 
@@ -7905,15 +7943,6 @@ comp_template_args_with_info (tree oldargs, tree newargs,
   return 1;
 }
 
-/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
-   of template arguments.  Returns 0 otherwise.  */
-
-int
-comp_template_args (tree oldargs, tree newargs)
-{
-  return comp_template_args_with_info (oldargs, newargs, NULL, NULL);
-}
-
 static void
 add_pending_template (tree d)
 {
@@ -8375,6 +8404,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
              t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE,
                              tsubst (ENUM_UNDERLYING_TYPE (template_type),
                                      arglist, complain, in_decl),
+                             tsubst_attributes (TYPE_ATTRIBUTES (template_type),
+                                                arglist, complain, in_decl),
                              SCOPED_ENUM_P (template_type), NULL);
 
              if (t == error_mark_node)
@@ -8456,11 +8487,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
              tree attributes
                = lookup_attribute (tags[ix], TYPE_ATTRIBUTES (template_type));
 
-             if (!attributes)
-               ;
-             else if (!TREE_CHAIN (attributes) && !TYPE_ATTRIBUTES (t))
-               TYPE_ATTRIBUTES (t) = attributes;
-             else
+             if (attributes)
                TYPE_ATTRIBUTES (t)
                  = tree_cons (TREE_PURPOSE (attributes),
                               TREE_VALUE (attributes),
@@ -8525,6 +8552,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
                    arglist, complain, NULL_TREE);
          --processing_template_decl;
          TREE_VEC_LENGTH (arglist)++;
+         if (partial_inst_args == error_mark_node)
+           return error_mark_node;
          use_partial_inst_tmpl =
            /*...and we must not be looking at the partial instantiation
             itself. */
@@ -8672,6 +8701,24 @@ finish_template_variable (tree var, tsubst_flags_t complain)
 
   return instantiate_template (templ, arglist, complain);
 }
+
+/* Construct a TEMPLATE_ID_EXPR for the given variable template TEMPL having
+   TARGS template args, and instantiate it if it's not dependent.  */
+
+static tree
+lookup_and_finish_template_variable (tree templ, tree targs,
+                                    tsubst_flags_t complain)
+{
+  templ = lookup_template_variable (templ, targs);
+  if (!any_dependent_template_arguments_p (targs))
+    {
+      templ = finish_template_variable (templ, complain);
+      mark_used (templ);
+    }
+
+  return convert_from_reference (templ);
+}
+
 \f
 struct pair_fn_data
 {
@@ -8692,12 +8739,20 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
   struct pair_fn_data *pfd = (struct pair_fn_data *) d;
   tree_fn_t fn = pfd->fn;
   void *data = pfd->data;
+  tree result = NULL_TREE;
+
+#define WALK_SUBTREE(NODE)                                             \
+  do                                                                   \
+    {                                                                  \
+      result = for_each_template_parm (NODE, fn, data, pfd->visited,   \
+                                      pfd->include_nondeduced_p);      \
+      if (result) goto out;                                            \
+    }                                                                  \
+  while (0)
 
   if (TYPE_P (t)
-      && (pfd->include_nondeduced_p || TREE_CODE (t) != TYPENAME_TYPE)
-      && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited,
-                                pfd->include_nondeduced_p))
-    return error_mark_node;
+      && (pfd->include_nondeduced_p || TREE_CODE (t) != TYPENAME_TYPE))
+    WALK_SUBTREE (TYPE_CONTEXT (t));
 
   switch (TREE_CODE (t))
     {
@@ -8710,35 +8765,24 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case ENUMERAL_TYPE:
       if (!TYPE_TEMPLATE_INFO (t))
        *walk_subtrees = 0;
-      else if (for_each_template_parm (TYPE_TI_ARGS (t),
-                                      fn, data, pfd->visited, 
-                                      pfd->include_nondeduced_p))
-       return error_mark_node;
+      else
+       WALK_SUBTREE (TYPE_TI_ARGS (t));
       break;
 
     case INTEGER_TYPE:
-      if (for_each_template_parm (TYPE_MIN_VALUE (t),
-                                 fn, data, pfd->visited, 
-                                 pfd->include_nondeduced_p)
-         || for_each_template_parm (TYPE_MAX_VALUE (t),
-                                    fn, data, pfd->visited,
-                                    pfd->include_nondeduced_p))
-       return error_mark_node;
+      WALK_SUBTREE (TYPE_MIN_VALUE (t));
+      WALK_SUBTREE (TYPE_MAX_VALUE (t));
       break;
 
     case METHOD_TYPE:
       /* Since we're not going to walk subtrees, we have to do this
         explicitly here.  */
-      if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data,
-                                 pfd->visited, pfd->include_nondeduced_p))
-       return error_mark_node;
+      WALK_SUBTREE (TYPE_METHOD_BASETYPE (t));
       /* Fall through.  */
 
     case FUNCTION_TYPE:
       /* Check the return type.  */
-      if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
-                                 pfd->include_nondeduced_p))
-       return error_mark_node;
+      WALK_SUBTREE (TREE_TYPE (t));
 
       /* Check the parameter types.  Since default arguments are not
         instantiated until they are needed, the TYPE_ARG_TYPES may
@@ -8750,9 +8794,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
        tree parm;
 
        for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
-         if (for_each_template_parm (TREE_VALUE (parm), fn, data,
-                                     pfd->visited, pfd->include_nondeduced_p))
-           return error_mark_node;
+         WALK_SUBTREE (TREE_VALUE (parm));
 
        /* Since we've already handled the TYPE_ARG_TYPES, we don't
           want walk_tree walking into them itself.  */
@@ -8771,67 +8813,52 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
 
     case FUNCTION_DECL:
     case VAR_DECL:
-      if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
-         && for_each_template_parm (DECL_TI_ARGS (t), fn, data,
-                                    pfd->visited, pfd->include_nondeduced_p))
-       return error_mark_node;
+      if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
+       WALK_SUBTREE (DECL_TI_ARGS (t));
       /* Fall through.  */
 
     case PARM_DECL:
     case CONST_DECL:
-      if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t)
-         && for_each_template_parm (DECL_INITIAL (t), fn, data,
-                                    pfd->visited, pfd->include_nondeduced_p))
-       return error_mark_node;
+      if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t))
+       WALK_SUBTREE (DECL_INITIAL (t));
       if (DECL_CONTEXT (t)
-         && pfd->include_nondeduced_p
-         && for_each_template_parm (DECL_CONTEXT (t), fn, data,
-                                    pfd->visited, pfd->include_nondeduced_p))
-       return error_mark_node;
+         && pfd->include_nondeduced_p)
+       WALK_SUBTREE (DECL_CONTEXT (t));
       break;
 
     case BOUND_TEMPLATE_TEMPLATE_PARM:
       /* Record template parameters such as `T' inside `TT<T>'.  */
-      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited,
-                                 pfd->include_nondeduced_p))
-       return error_mark_node;
+      WALK_SUBTREE (TYPE_TI_ARGS (t));
       /* Fall through.  */
 
     case TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_PARM_INDEX:
       if (fn && (*fn)(t, data))
-       return error_mark_node;
+       return t;
       else if (!fn)
-       return error_mark_node;
+       return t;
       break;
 
     case TEMPLATE_DECL:
       /* A template template parameter is encountered.  */
-      if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
-         && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
-                                    pfd->include_nondeduced_p))
-       return error_mark_node;
+      if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
+       WALK_SUBTREE (TREE_TYPE (t));
 
       /* Already substituted template template parameter */
       *walk_subtrees = 0;
       break;
 
     case TYPENAME_TYPE:
-      if (!fn
-         || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn,
-                                    data, pfd->visited, 
-                                    pfd->include_nondeduced_p))
-       return error_mark_node;
+      /* A template-id in a TYPENAME_TYPE might be a deduced context after
+        partial instantiation.  */
+      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (t));
       break;
 
     case CONSTRUCTOR:
       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
-         && pfd->include_nondeduced_p
-         && for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
-                                    (TREE_TYPE (t)), fn, data,
-                                    pfd->visited, pfd->include_nondeduced_p))
-       return error_mark_node;
+         && pfd->include_nondeduced_p)
+       WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
       break;
 
     case INDIRECT_REF:
@@ -8861,8 +8888,11 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       break;
     }
 
+  #undef WALK_SUBTREE
+
   /* We didn't find any template parameters we liked.  */
-  return NULL_TREE;
+ out:
+  return result;
 }
 
 /* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM,
@@ -8878,13 +8908,13 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
    parameters that occur in non-deduced contexts.  When false, only
    visits those template parameters that can be deduced.  */
 
-static int
+static tree
 for_each_template_parm (tree t, tree_fn_t fn, void* data,
                        hash_set<tree> *visited,
                        bool include_nondeduced_p)
 {
   struct pair_fn_data pfd;
-  int result;
+  tree result;
 
   /* Set up.  */
   pfd.fn = fn;
@@ -8903,7 +8933,7 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
   result = cp_walk_tree (&t,
                         for_each_template_parm_r,
                         &pfd,
-                        pfd.visited) != NULL_TREE;
+                        pfd.visited);
 
   /* Clean up.  */
   if (!visited)
@@ -8979,7 +9009,7 @@ in_template_function (void)
 
 /* Returns true if T depends on any template parameter with level LEVEL.  */
 
-int
+bool
 uses_template_parms_level (tree t, int level)
 {
   return for_each_template_parm (t, template_parm_this_level_p, &level, NULL,
@@ -9533,7 +9563,111 @@ can_complete_type_without_circularity (tree type)
     return 1;
 }
 
-static tree tsubst_omp_clauses (tree, bool, bool, tree, tsubst_flags_t, tree);
+static tree tsubst_omp_clauses (tree, enum c_omp_region_type, tree,
+                               tsubst_flags_t, tree);
+
+/* Instantiate a single dependent attribute T (a TREE_LIST), and return either
+   T or a new TREE_LIST, possibly a chain in the case of a pack expansion.  */
+
+static tree
+tsubst_attribute (tree t, tree *decl_p, tree args,
+                 tsubst_flags_t complain, tree in_decl)
+{
+  gcc_assert (ATTR_IS_DEPENDENT (t));
+
+  tree val = TREE_VALUE (t);
+  if (val == NULL_TREE)
+    /* Nothing to do.  */;
+  else if ((flag_openmp || flag_openmp_simd || flag_cilkplus)
+          && is_attribute_p ("omp declare simd",
+                             get_attribute_name (t)))
+    {
+      tree clauses = TREE_VALUE (val);
+      clauses = tsubst_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD, args,
+                                   complain, in_decl);
+      c_omp_declare_simd_clauses_to_decls (*decl_p, clauses);
+      clauses = finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
+      tree parms = DECL_ARGUMENTS (*decl_p);
+      clauses
+       = c_omp_declare_simd_clauses_to_numbers (parms, clauses);
+      if (clauses)
+       val = build_tree_list (NULL_TREE, clauses);
+      else
+       val = NULL_TREE;
+    }
+  /* If the first attribute argument is an identifier, don't
+     pass it through tsubst.  Attributes like mode, format,
+     cleanup and several target specific attributes expect it
+     unmodified.  */
+  else if (attribute_takes_identifier_p (get_attribute_name (t)))
+    {
+      tree chain
+       = tsubst_expr (TREE_CHAIN (val), args, complain, in_decl,
+                      /*integral_constant_expression_p=*/false);
+      if (chain != TREE_CHAIN (val))
+       val = tree_cons (NULL_TREE, TREE_VALUE (val), chain);
+    }
+  else if (PACK_EXPANSION_P (val))
+    {
+      /* An attribute pack expansion.  */
+      tree purp = TREE_PURPOSE (t);
+      tree pack = tsubst_pack_expansion (val, args, complain, in_decl);
+      int len = TREE_VEC_LENGTH (pack);
+      tree list = NULL_TREE;
+      tree *q = &list;
+      for (int i = 0; i < len; ++i)
+       {
+         tree elt = TREE_VEC_ELT (pack, i);
+         *q = build_tree_list (purp, elt);
+         q = &TREE_CHAIN (*q);
+       }
+      return list;
+    }
+  else
+    val = tsubst_expr (val, args, complain, in_decl,
+                      /*integral_constant_expression_p=*/false);
+
+  if (val != TREE_VALUE (t))
+    return build_tree_list (TREE_PURPOSE (t), val);
+  return t;
+}
+
+/* Instantiate any dependent attributes in ATTRIBUTES, returning either it
+   unchanged or a new TREE_LIST chain.  */
+
+static tree
+tsubst_attributes (tree attributes, tree args,
+                  tsubst_flags_t complain, tree in_decl)
+{
+  tree last_dep = NULL_TREE;
+
+  for (tree t = attributes; t; t = TREE_CHAIN (t))
+    if (ATTR_IS_DEPENDENT (t))
+      {
+       last_dep = t;
+       attributes = copy_list (attributes);
+       break;
+      }
+
+  if (last_dep)
+    for (tree *p = &attributes; *p; p = &TREE_CHAIN (*p))
+      {
+       tree t = *p;
+       if (ATTR_IS_DEPENDENT (t))
+         {
+           tree subst = tsubst_attribute (t, NULL, args, complain, in_decl);
+           if (subst == t)
+             continue;
+           *p = subst;
+           do
+             p = &TREE_CHAIN (*p);
+           while (*p);
+           *p = TREE_CHAIN (t);
+         }
+      }
+
+  return attributes;
+}
 
 /* Apply any attributes which had to be deferred until instantiation
    time.  DECL_P, ATTRIBUTES and ATTR_FLAGS are as cplus_decl_attributes;
@@ -9576,61 +9710,10 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
            {
              *p = TREE_CHAIN (t);
              TREE_CHAIN (t) = NULL_TREE;
-             if ((flag_openmp || flag_openmp_simd || flag_cilkplus)
-                 && is_attribute_p ("omp declare simd",
-                                    get_attribute_name (t))
-                 && TREE_VALUE (t))
-               {
-                 tree clauses = TREE_VALUE (TREE_VALUE (t));
-                 clauses = tsubst_omp_clauses (clauses, true, false, args,
-                                               complain, in_decl);
-                 c_omp_declare_simd_clauses_to_decls (*decl_p, clauses);
-                 clauses = finish_omp_clauses (clauses, false, true);
-                 tree parms = DECL_ARGUMENTS (*decl_p);
-                 clauses
-                   = c_omp_declare_simd_clauses_to_numbers (parms, clauses);
-                 if (clauses)
-                   TREE_VALUE (TREE_VALUE (t)) = clauses;
-                 else
-                   TREE_VALUE (t) = NULL_TREE;
-               }
-             /* If the first attribute argument is an identifier, don't
-                pass it through tsubst.  Attributes like mode, format,
-                cleanup and several target specific attributes expect it
-                unmodified.  */
-             else if (attribute_takes_identifier_p (get_attribute_name (t))
-                      && TREE_VALUE (t))
-               {
-                 tree chain
-                   = tsubst_expr (TREE_CHAIN (TREE_VALUE (t)), args, complain,
-                                  in_decl,
-                                  /*integral_constant_expression_p=*/false);
-                 if (chain != TREE_CHAIN (TREE_VALUE (t)))
-                   TREE_VALUE (t)
-                     = tree_cons (NULL_TREE, TREE_VALUE (TREE_VALUE (t)),
-                                  chain);
-               }
-             else if (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t)))
-               {
-                 /* An attribute pack expansion.  */
-                 tree purp = TREE_PURPOSE (t);
-                 tree pack = (tsubst_pack_expansion
-                              (TREE_VALUE (t), args, complain, in_decl));
-                 int len = TREE_VEC_LENGTH (pack);
-                 for (int i = 0; i < len; ++i)
-                   {
-                     tree elt = TREE_VEC_ELT (pack, i);
-                     *q = build_tree_list (purp, elt);
-                     q = &TREE_CHAIN (*q);
-                   }
-                 continue;
-               }
-             else
-               TREE_VALUE (t)
-                 = tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
-                                /*integral_constant_expression_p=*/false);
-             *q = t;
-             q = &TREE_CHAIN (t);
+             *q = tsubst_attribute (t, decl_p, args, complain, in_decl);
+             do
+               q = &TREE_CHAIN (*q);
+             while (*q);
            }
          else
            p = &TREE_CHAIN (t);
@@ -9776,7 +9859,7 @@ instantiate_class_template_1 (tree type)
     DECL_SOURCE_LOCATION (typedecl);
 
   TYPE_PACKED (type) = TYPE_PACKED (pattern);
-  TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
+  SET_TYPE_ALIGN (type, TYPE_ALIGN (pattern));
   TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern);
   TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
   if (ANON_AGGR_TYPE_P (pattern))
@@ -10036,7 +10119,16 @@ instantiate_class_template_1 (tree type)
                          if (can_complete_type_without_circularity (rtype))
                            complete_type (rtype);
 
-                         if (!COMPLETE_TYPE_P (rtype))
+                          if (TREE_CODE (r) == FIELD_DECL
+                              && TREE_CODE (rtype) == ARRAY_TYPE
+                              && COMPLETE_TYPE_P (TREE_TYPE (rtype))
+                              && !COMPLETE_TYPE_P (rtype))
+                            {
+                              /* Flexible array mmembers of elements
+                                 of complete type have an incomplete type
+                                 and that's okay.  */
+                            }
+                          else if (!COMPLETE_TYPE_P (rtype))
                            {
                              cxx_incomplete_type_error (r, rtype);
                              TREE_TYPE (r) = error_mark_node;
@@ -10095,11 +10187,11 @@ instantiate_class_template_1 (tree type)
                       template <class U> friend class T::C;
 
                     otherwise.  */
+                 /* Bump processing_template_decl in case this is something like
+                    template <class T> friend struct A<T>::B.  */
+                 ++processing_template_decl;
                  friend_type = tsubst (friend_type, args,
                                        tf_warning_or_error, NULL_TREE);
-                 /* Bump processing_template_decl for correct
-                    dependent_type_p calculation.  */
-                 ++processing_template_decl;
                  if (dependent_type_p (friend_type))
                    adjust_processing_template_decl = true;
                  --processing_template_decl;
@@ -10193,7 +10285,12 @@ instantiate_class_template_1 (tree type)
        {
          if (!DECL_TEMPLATE_INFO (decl)
              || DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl)) != decl)
-           instantiate_decl (decl, false, false);
+           {
+             /* Set function_depth to avoid garbage collection.  */
+             ++function_depth;
+             instantiate_decl (decl, false, false);
+             --function_depth;
+           }
 
          /* We need to instantiate the capture list from the template
             after we've instantiated the closure members, but before we
@@ -10533,10 +10630,6 @@ gen_elem_of_pack_expansion_instantiation (tree pattern,
    sequence, the value of the expression is as follows; the program is
    ill-formed if the operator is not listed in this table.
 
-   *   1
-   +   0
-   &   -1
-   |   0
    &&  true
    ||  false
    ,   void()  */
@@ -10548,14 +10641,6 @@ expand_empty_fold (tree t, tsubst_flags_t complain)
   if (!FOLD_EXPR_MODIFY_P (t))
     switch (code)
       {
-      case MULT_EXPR:
-       return integer_one_node;
-      case PLUS_EXPR:
-       return integer_zero_node;
-      case BIT_AND_EXPR:
-       return integer_minus_one_node;
-      case BIT_IOR_EXPR:
-       return integer_zero_node;
       case TRUTH_ANDIF_EXPR:
        return boolean_true_node;
       case TRUTH_ORIF_EXPR:
@@ -10799,12 +10884,16 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
          if (PACK_EXPANSION_LOCAL_P (t) || CONSTRAINT_VAR_P (parm_pack))
            arg_pack = retrieve_local_specialization (parm_pack);
          else
+           /* We can't rely on local_specializations for a parameter
+              name used later in a function declaration (such as in a
+              late-specified return type).  Even if it exists, it might
+              have the wrong value for a recursive call.  */
+           need_local_specializations = true;
+
+         if (!arg_pack)
            {
-             /* We can't rely on local_specializations for a parameter
-                name used later in a function declaration (such as in a
-                late-specified return type).  Even if it exists, it might
-                have the wrong value for a recursive call.  Just make a
-                dummy decl, since it's only used for its type.  */
+             /* This parameter pack was used in an unevaluated context.  Just
+                make a dummy decl, since it's only used for its type.  */
              arg_pack = tsubst_decl (parm_pack, args, complain);
              if (arg_pack && DECL_PACK_P (arg_pack))
                /* Partial instantiation of the parm_pack, we can't build
@@ -10812,7 +10901,6 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
                arg_pack = NULL_TREE;
              else
                arg_pack = make_fnparm_pack (arg_pack);
-             need_local_specializations = true;
            }
        }
       else if (TREE_CODE (parm_pack) == FIELD_DECL)
@@ -10876,18 +10964,31 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
          /* We can't substitute for this parameter pack.  We use a flag as
             well as the missing_level counter because function parameter
             packs don't have a level.  */
+         gcc_assert (processing_template_decl);
          unsubstituted_packs = true;
        }
     }
 
-  /* If the expansion is just T..., return the matching argument pack.  */
+  /* If the expansion is just T..., return the matching argument pack, unless
+     we need to call convert_from_reference on all the elements.  This is an
+     important optimization; see c++/68422.  */
   if (!unsubstituted_packs
       && TREE_PURPOSE (packs) == pattern)
     {
       tree args = ARGUMENT_PACK_ARGS (TREE_VALUE (packs));
+      /* Types need no adjustment, nor does sizeof..., and if we still have
+        some pack expansion args we won't do anything yet.  */
       if (TREE_CODE (t) == TYPE_PACK_EXPANSION
+         || PACK_EXPANSION_SIZEOF_P (t)
          || pack_expansion_args_count (args))
        return args;
+      /* Also optimize expression pack expansions if we can tell that the
+        elements won't have reference type.  */
+      tree type = TREE_TYPE (pattern);
+      if (type && TREE_CODE (type) != REFERENCE_TYPE
+         && !PACK_EXPANSION_P (type)
+         && !WILDCARD_TYPE_P (type))
+       return args;
       /* Otherwise use the normal path so we get convert_from_reference.  */
     }
 
@@ -10932,11 +11033,12 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
   /* For each argument in each argument pack, substitute into the
      pattern.  */
   result = make_tree_vec (len);
+  tree elem_args = copy_template_args (args);
   for (i = 0; i < len; ++i)
     {
       t = gen_elem_of_pack_expansion_instantiation (pattern, packs,
                                                    i,
-                                                   args, complain,
+                                                   elem_args, complain,
                                                    in_decl);
       TREE_VEC_ELT (result, i) = t;
       if (t == error_mark_node)
@@ -11012,6 +11114,51 @@ get_pattern_parm (tree parm, tree tmpl)
   return patparm;
 }
 
+/* Make an argument pack out of the TREE_VEC VEC.  */
+
+static tree
+make_argument_pack (tree vec)
+{
+  tree pack;
+  tree elt = TREE_VEC_ELT (vec, 0);
+  if (TYPE_P (elt))
+    pack = cxx_make_type (TYPE_ARGUMENT_PACK);
+  else
+    {
+      pack = make_node (NONTYPE_ARGUMENT_PACK);
+      TREE_TYPE (pack) = TREE_TYPE (elt);
+      TREE_CONSTANT (pack) = 1;
+    }
+  SET_ARGUMENT_PACK_ARGS (pack, vec);
+  return pack;
+}
+
+/* Return an exact copy of template args T that can be modified
+   independently.  */
+
+static tree
+copy_template_args (tree t)
+{
+  if (t == error_mark_node)
+    return t;
+
+  int len = TREE_VEC_LENGTH (t);
+  tree new_vec = make_tree_vec (len);
+
+  for (int i = 0; i < len; ++i)
+    {
+      tree elt = TREE_VEC_ELT (t, i);
+      if (elt && TREE_CODE (elt) == TREE_VEC)
+       elt = copy_template_args (elt);
+      TREE_VEC_ELT (new_vec, i) = elt;
+    }
+
+  NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_vec)
+    = NON_DEFAULT_TEMPLATE_ARGS_COUNT (t);
+
+  return new_vec;
+}
+
 /* Substitute ARGS into the vector or list of template arguments T.  */
 
 static tree
@@ -11553,16 +11700,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL)
          {
            tree spec;
-           bool dependent_p;
 
-           /* If T is not dependent, just return it.  We have to
-              increment PROCESSING_TEMPLATE_DECL because
-              value_dependent_expression_p assumes that nothing is
-              dependent when PROCESSING_TEMPLATE_DECL is zero.  */
-           ++processing_template_decl;
-           dependent_p = value_dependent_expression_p (t);
-           --processing_template_decl;
-           if (!dependent_p)
+           /* If T is not dependent, just return it.  */
+           if (!uses_template_parms (DECL_TI_ARGS (t)))
              RETURN (t);
 
            /* Calculate the most general template of which R is a
@@ -12228,6 +12368,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        /* The initializer must not be expanded until it is required;
           see [temp.inst].  */
        DECL_INITIAL (r) = NULL_TREE;
+       if (VAR_P (r))
+         DECL_MODE (r) = VOIDmode;
        if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL))
          SET_DECL_RTL (r, NULL);
        DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0;
@@ -12258,8 +12400,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            SET_DECL_IMPLICIT_INSTANTIATION (r);
            register_specialization (r, gen_tmpl, argvec, false, hash);
          }
-       else if (!cp_unevaluated_operand)
-         register_local_specialization (r, t);
+       else
+         {
+           if (DECL_LANG_SPECIFIC (r))
+             DECL_TEMPLATE_INFO (r) = NULL_TREE;
+           if (!cp_unevaluated_operand)
+             register_local_specialization (r, t);
+         }
 
        DECL_CHAIN (r) = NULL_TREE;
 
@@ -12757,8 +12904,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        return t;
 
       if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST
-         && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
-       return t;
+          && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
+        return t;
 
       {
        tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
@@ -12977,6 +13124,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                TYPE_POINTER_TO (r) = NULL_TREE;
                TYPE_REFERENCE_TO (r) = NULL_TREE;
 
+               /* Propagate constraints on placeholders.  */
+                if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
+                  if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (t))
+                   PLACEHOLDER_TYPE_CONSTRAINTS (r)
+                     = tsubst_constraint (constr, args, complain, in_decl);
+
                if (TREE_CODE (r) == TEMPLATE_TEMPLATE_PARM)
                  /* We have reduced the level of the template
                     template parameter, but not the levels of its
@@ -12991,12 +13144,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                else
                  TYPE_CANONICAL (r) = canonical_type_parameter (r);
 
-               /* Propagate constraints on placeholders.  */
-                if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-                  if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (t))
-                   PLACEHOLDER_TYPE_CONSTRAINTS (r)
-                     = tsubst_constraint (constr, args, complain, in_decl);
-
                if (code == BOUND_TEMPLATE_TEMPLATE_PARM)
                  {
                    tree argvec = tsubst (TYPE_TI_ARGS (t), args,
@@ -13253,7 +13400,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
        if (TYPE_USER_ALIGN (t))
          {
-           TYPE_ALIGN (r) = TYPE_ALIGN (t);
+           SET_TYPE_ALIGN (r, TYPE_ALIGN (t));
            TYPE_USER_ALIGN (r) = 1;
          }
 
@@ -13493,7 +13640,15 @@ tsubst_baselink (tree baselink, tree object_type,
       name = mangle_conv_op_name_for_type (optype);
     baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
     if (!baselink)
-      return error_mark_node;
+      {
+       if (constructor_name_p (name, qualifying_scope))
+         {
+           if (complain & tf_error)
+             error ("cannot call constructor %<%T::%D%> directly",
+                    qualifying_scope, name);
+         }
+       return error_mark_node;
+      }
 
     /* If lookup found a single function, mark it as used at this
        point.  (If it lookup found multiple functions the one selected
@@ -13508,9 +13663,10 @@ tsubst_baselink (tree baselink, tree object_type,
     /* Add back the template arguments, if present.  */
     if (BASELINK_P (baselink) && template_id_p)
       BASELINK_FUNCTIONS (baselink)
-       = build_nt (TEMPLATE_ID_EXPR,
-                   BASELINK_FUNCTIONS (baselink),
-                   template_args);
+       = build2 (TEMPLATE_ID_EXPR,
+                 unknown_type_node,
+                 BASELINK_FUNCTIONS (baselink),
+                 template_args);
     /* Update the conversion operator type.  */
     BASELINK_OPTYPE (baselink) = optype;
 
@@ -13632,7 +13788,13 @@ tsubst_qualified_id (tree qualified_id, tree args,
     }
 
   if (is_template)
-    expr = lookup_template_function (expr, template_args);
+    {
+      if (variable_template_p (expr))
+       expr = lookup_and_finish_template_variable (expr, template_args,
+                                                   complain);
+      else
+       expr = lookup_template_function (expr, template_args);
+    }
 
   if (expr == error_mark_node && complain & tf_error)
     qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
@@ -13710,10 +13872,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
       if (r == NULL_TREE)
        {
-         /* We get here for a use of 'this' in an NSDMI.  */
+         /* We get here for a use of 'this' in an NSDMI as part of a
+            constructor call or as part of an aggregate initialization.  */
          if (DECL_NAME (t) == this_identifier
-             && current_function_decl
-             && DECL_CONSTRUCTOR_P (current_function_decl))
+             && ((current_function_decl
+                  && DECL_CONSTRUCTOR_P (current_function_decl))
+                 || (current_class_ref
+                     && TREE_CODE (current_class_ref) == PLACEHOLDER_EXPR)))
            return current_class_ptr;
 
          /* This can happen for a parameter name used later in a function
@@ -13950,9 +14115,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       }
 
     case SIZEOF_EXPR:
-      if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
+      if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))
+         || ARGUMENT_PACK_P (TREE_OPERAND (t, 0)))
         {
-
           tree expanded, op = TREE_OPERAND (t, 0);
          int len = 0;
 
@@ -13962,22 +14127,35 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          ++cp_unevaluated_operand;
          ++c_inhibit_evaluation_warnings;
          /* We only want to compute the number of arguments.  */
-         expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+         if (PACK_EXPANSION_P (op))
+           expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+         else
+           expanded = tsubst_template_args (ARGUMENT_PACK_ARGS (op),
+                                            args, complain, in_decl);
          --cp_unevaluated_operand;
          --c_inhibit_evaluation_warnings;
 
          if (TREE_CODE (expanded) == TREE_VEC)
-           len = TREE_VEC_LENGTH (expanded);
+           {
+             len = TREE_VEC_LENGTH (expanded);
+             /* Set TREE_USED for the benefit of -Wunused.  */
+             for (int i = 0; i < len; i++)
+               TREE_USED (TREE_VEC_ELT (expanded, i)) = true;
+           }
 
          if (expanded == error_mark_node)
            return error_mark_node;
          else if (PACK_EXPANSION_P (expanded)
                   || (TREE_CODE (expanded) == TREE_VEC
-                      && len > 0
-                      && PACK_EXPANSION_P (TREE_VEC_ELT (expanded, len-1))))
+                      && pack_expansion_args_count (expanded)))
+
            {
-             if (TREE_CODE (expanded) == TREE_VEC)
-               expanded = TREE_VEC_ELT (expanded, len - 1);
+             if (PACK_EXPANSION_P (expanded))
+               /* OK.  */;
+             else if (TREE_VEC_LENGTH (expanded) == 1)
+               expanded = TREE_VEC_ELT (expanded, 0);
+             else
+               expanded = make_argument_pack (expanded);
 
              if (TYPE_P (expanded))
                return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR, 
@@ -14297,8 +14475,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       return tsubst_binary_right_fold (t, args, complain, in_decl);
 
     default:
-      /* We shouldn't get here, but keep going if !ENABLE_CHECKING.  */
-      gcc_checking_assert (false);
+      /* We shouldn't get here, but keep going if !flag_checking.  */
+      if (flag_checking)
+       gcc_unreachable ();
       return t;
     }
 }
@@ -14350,7 +14529,7 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
 /* Like tsubst_copy, but specifically for OpenMP clauses.  */
 
 static tree
-tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
+tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
                    tree args, tsubst_flags_t complain, tree in_decl)
 {
   tree new_clauses = NULL_TREE, nc, oc;
@@ -14406,6 +14585,13 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
        case OMP_CLAUSE_PRIORITY:
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_HINT:
+       case OMP_CLAUSE_NUM_GANGS:
+       case OMP_CLAUSE_NUM_WORKERS:
+       case OMP_CLAUSE_VECTOR_LENGTH:
+       case OMP_CLAUSE_WORKER:
+       case OMP_CLAUSE_VECTOR:
+       case OMP_CLAUSE_ASYNC:
+       case OMP_CLAUSE_WAIT:
          OMP_CLAUSE_OPERAND (nc, 0)
            = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, 
                           in_decl, /*integral_constant_expression_p=*/false);
@@ -14430,7 +14616,7 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
            = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
                                      in_decl);
          break;
-       case OMP_CLAUSE_LINEAR:
+       case OMP_CLAUSE_GANG:
        case OMP_CLAUSE_ALIGNED:
          OMP_CLAUSE_DECL (nc)
            = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
@@ -14438,12 +14624,25 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
          OMP_CLAUSE_OPERAND (nc, 1)
            = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
                           in_decl, /*integral_constant_expression_p=*/false);
-         if (OMP_CLAUSE_CODE (oc) == OMP_CLAUSE_LINEAR
-             && OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE)
+         break;
+       case OMP_CLAUSE_LINEAR:
+         OMP_CLAUSE_DECL (nc)
+           = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
+                                     in_decl);
+         if (OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE)
            {
              gcc_assert (!linear_no_step);
              linear_no_step = nc;
            }
+         else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (oc))
+           OMP_CLAUSE_LINEAR_STEP (nc)
+             = tsubst_omp_clause_decl (OMP_CLAUSE_LINEAR_STEP (oc), args,
+                                       complain, in_decl);
+         else
+           OMP_CLAUSE_LINEAR_STEP (nc)
+             = tsubst_expr (OMP_CLAUSE_LINEAR_STEP (oc), args, complain,
+                            in_decl,
+                            /*integral_constant_expression_p=*/false);
          break;
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_DEFAULT:
@@ -14460,13 +14659,30 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
        case OMP_CLAUSE_THREADS:
        case OMP_CLAUSE_SIMD:
        case OMP_CLAUSE_DEFAULTMAP:
+       case OMP_CLAUSE_INDEPENDENT:
+       case OMP_CLAUSE_AUTO:
+       case OMP_CLAUSE_SEQ:
+         break;
+       case OMP_CLAUSE_TILE:
+         {
+           tree lnc, loc;
+           for (lnc = OMP_CLAUSE_TILE_LIST (nc),
+                  loc = OMP_CLAUSE_TILE_LIST (oc);
+                loc;
+                loc = TREE_CHAIN (loc), lnc = TREE_CHAIN (lnc))
+             {
+               TREE_VALUE (lnc) = tsubst_expr (TREE_VALUE (loc), args,
+                                               complain, in_decl, false);
+             }
+         }
          break;
        default:
          gcc_unreachable ();
        }
-      if (allow_fields)
+      if ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP)
        switch (OMP_CLAUSE_CODE (nc))
          {
+         case OMP_CLAUSE_SHARED:
          case OMP_CLAUSE_PRIVATE:
          case OMP_CLAUSE_FIRSTPRIVATE:
          case OMP_CLAUSE_LASTPRIVATE:
@@ -14525,9 +14741,9 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
     }
 
   new_clauses = nreverse (new_clauses);
-  if (!declare_simd)
+  if (ort != C_ORT_OMP_DECLARE_SIMD)
     {
-      new_clauses = finish_omp_clauses (new_clauses, allow_fields);
+      new_clauses = finish_omp_clauses (new_clauses, ort);
       if (linear_no_step)
        for (nc = new_clauses; nc; nc = OMP_CLAUSE_CHAIN (nc))
          if (nc == linear_no_step)
@@ -14646,7 +14862,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
                        && DECL_NAME (v) == this_identifier)
                      {
                        decl = TREE_OPERAND (decl, 1);
-                       decl = omp_privatize_field (decl);
+                       decl = omp_privatize_field (decl, false);
                      }
                    /* FALLTHRU */
                  default:
@@ -14748,7 +14964,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
        {
          tree c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
          OMP_CLAUSE_DECL (c) = decl;
-         c = finish_omp_clauses (c, true);
+         c = finish_omp_clauses (c, C_ORT_OMP);
          if (c)
            {
              OMP_CLAUSE_CHAIN (c) = *clauses;
@@ -14827,6 +15043,27 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
 #undef RECUR
 }
 
+/* Helper function of tsubst_expr, find OMP_TEAMS inside
+   of OMP_TARGET's body.  */
+
+static tree
+tsubst_find_omp_teams (tree *tp, int *walk_subtrees, void *)
+{
+  *walk_subtrees = 0;
+  switch (TREE_CODE (*tp))
+    {
+    case OMP_TEAMS:
+      return *tp;
+    case BIND_EXPR:
+    case STATEMENT_LIST:
+      *walk_subtrees = 1;
+      break;
+    default:
+      break;
+    }
+  return NULL_TREE;
+}
+
 /* Like tsubst_copy for expressions, etc. but also does semantic
    processing.  */
 
@@ -14895,7 +15132,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
          {
            tree scope = USING_DECL_SCOPE (decl);
            tree name = DECL_NAME (decl);
-           tree decl;
 
            scope = tsubst (scope, args, complain, in_decl);
            decl = lookup_qualified_name (scope, name,
@@ -15208,10 +15444,19 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       }
       break;
 
+    case OACC_KERNELS:
+    case OACC_PARALLEL:
+      tmp = tsubst_omp_clauses (OMP_CLAUSES (t), C_ORT_ACC, args, complain,
+                               in_decl);
+      stmt = begin_omp_parallel ();
+      RECUR (OMP_BODY (t));
+      finish_omp_construct (TREE_CODE (t), stmt, tmp);
+      break;
+
     case OMP_PARALLEL:
       r = push_omp_privatization_clauses (OMP_PARALLEL_COMBINED (t));
-      tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t), false, true,
-                               args, complain, in_decl);
+      tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t), C_ORT_OMP, args,
+                               complain, in_decl);
       if (OMP_PARALLEL_COMBINED (t))
        omp_parallel_combined_clauses = &tmp;
       stmt = begin_omp_parallel ();
@@ -15224,8 +15469,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
 
     case OMP_TASK:
       r = push_omp_privatization_clauses (false);
-      tmp = tsubst_omp_clauses (OMP_TASK_CLAUSES (t), false, true,
-                               args, complain, in_decl);
+      tmp = tsubst_omp_clauses (OMP_TASK_CLAUSES (t), C_ORT_OMP, args,
+                               complain, in_decl);
       stmt = begin_omp_task ();
       RECUR (OMP_TASK_BODY (t));
       finish_omp_task (tmp, stmt);
@@ -15238,20 +15483,27 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
     case CILK_FOR:
     case OMP_DISTRIBUTE:
     case OMP_TASKLOOP:
+    case OACC_LOOP:
       {
        tree clauses, body, pre_body;
        tree declv = NULL_TREE, initv = NULL_TREE, condv = NULL_TREE;
        tree orig_declv = NULL_TREE;
        tree incrv = NULL_TREE;
+       enum c_omp_region_type ort = C_ORT_OMP;
        int i;
 
+       if (TREE_CODE (t) == CILK_SIMD || TREE_CODE (t) == CILK_FOR)
+         ort = C_ORT_CILK;
+       else if (TREE_CODE (t) == OACC_LOOP)
+         ort = C_ORT_ACC;
+
        r = push_omp_privatization_clauses (OMP_FOR_INIT (t) == NULL_TREE);
-       clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t), false, true,
-                                     args, complain, in_decl);
+       clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t), ort, args, complain,
+                                     in_decl);
        if (OMP_FOR_INIT (t) != NULL_TREE)
          {
            declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
-           if (TREE_CODE (t) == OMP_FOR && OMP_FOR_ORIG_DECLS (t))
+           if (OMP_FOR_ORIG_DECLS (t))
              orig_declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
            initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
            condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
@@ -15278,7 +15530,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
        if (OMP_FOR_INIT (t) != NULL_TREE)
          t = finish_omp_for (EXPR_LOCATION (t), TREE_CODE (t), declv,
                              orig_declv, initv, condv, incrv, body, pre_body,
-                             clauses);
+                             NULL, clauses);
        else
          {
            t = make_node (TREE_CODE (t));
@@ -15303,8 +15555,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
     case OMP_CRITICAL:
       r = push_omp_privatization_clauses (TREE_CODE (t) == OMP_TEAMS
                                          && OMP_TEAMS_COMBINED (t));
-      tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false, true,
-                               args, complain, in_decl);
+      tmp = tsubst_omp_clauses (OMP_CLAUSES (t), C_ORT_OMP, args, complain,
+                               in_decl);
       stmt = push_stmt_list ();
       RECUR (OMP_BODY (t));
       stmt = pop_stmt_list (stmt);
@@ -15316,10 +15568,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       pop_omp_privatization_clauses (r);
       break;
 
+    case OACC_DATA:
     case OMP_TARGET_DATA:
     case OMP_TARGET:
-      tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false, true,
-                               args, complain, in_decl);
+      tmp = tsubst_omp_clauses (OMP_CLAUSES (t), (TREE_CODE (t) == OACC_DATA)
+                               ? C_ORT_ACC : C_ORT_OMP, args, complain,
+                               in_decl);
       keep_next_level (true);
       stmt = begin_omp_structured_block ();
 
@@ -15329,22 +15583,70 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       t = copy_node (t);
       OMP_BODY (t) = stmt;
       OMP_CLAUSES (t) = tmp;
+      if (TREE_CODE (t) == OMP_TARGET && OMP_TARGET_COMBINED (t))
+       {
+         tree teams = cp_walk_tree (&stmt, tsubst_find_omp_teams, NULL, NULL);
+         if (teams)
+           {
+             /* For combined target teams, ensure the num_teams and
+                thread_limit clause expressions are evaluated on the host,
+                before entering the target construct.  */
+             tree c;
+             for (c = OMP_TEAMS_CLAUSES (teams);
+                  c; c = OMP_CLAUSE_CHAIN (c))
+               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
+                   && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
+                 {
+                   tree expr = OMP_CLAUSE_OPERAND (c, 0);
+                   expr = force_target_expr (TREE_TYPE (expr), expr, tf_none);
+                   if (expr == error_mark_node)
+                     continue;
+                   tmp = TARGET_EXPR_SLOT (expr);
+                   add_stmt (expr);
+                   OMP_CLAUSE_OPERAND (c, 0) = expr;
+                   tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+                                               OMP_CLAUSE_FIRSTPRIVATE);
+                   OMP_CLAUSE_DECL (tc) = tmp;
+                   OMP_CLAUSE_CHAIN (tc) = OMP_TARGET_CLAUSES (t);
+                   OMP_TARGET_CLAUSES (t) = tc;
+                 }
+           }
+       }
+      add_stmt (t);
+      break;
+
+    case OACC_DECLARE:
+      t = copy_node (t);
+      tmp = tsubst_omp_clauses (OACC_DECLARE_CLAUSES (t), C_ORT_ACC, args,
+                               complain, in_decl);
+      OACC_DECLARE_CLAUSES (t) = tmp;
       add_stmt (t);
       break;
 
     case OMP_TARGET_UPDATE:
     case OMP_TARGET_ENTER_DATA:
     case OMP_TARGET_EXIT_DATA:
-      tmp = tsubst_omp_clauses (OMP_STANDALONE_CLAUSES (t), false, true,
-                               args, complain, in_decl);
+      tmp = tsubst_omp_clauses (OMP_STANDALONE_CLAUSES (t), C_ORT_OMP, args,
+                               complain, in_decl);
+      t = copy_node (t);
+      OMP_STANDALONE_CLAUSES (t) = tmp;
+      add_stmt (t);
+      break;
+
+    case OACC_ENTER_DATA:
+    case OACC_EXIT_DATA:
+    case OACC_UPDATE:
+      tmp = tsubst_omp_clauses (OMP_STANDALONE_CLAUSES (t), C_ORT_ACC, args,
+                               complain, in_decl);
       t = copy_node (t);
       OMP_STANDALONE_CLAUSES (t) = tmp;
       add_stmt (t);
       break;
 
     case OMP_ORDERED:
-      tmp = tsubst_omp_clauses (OMP_ORDERED_CLAUSES (t), false, true,
-                               args, complain, in_decl);
+      tmp = tsubst_omp_clauses (OMP_ORDERED_CLAUSES (t), C_ORT_OMP, args,
+                               complain, in_decl);
       stmt = push_stmt_list ();
       RECUR (OMP_BODY (t));
       stmt = pop_stmt_list (stmt);
@@ -15686,15 +15988,7 @@ tsubst_copy_and_build (tree t,
          return error_mark_node;
 
        if (variable_template_p (templ))
-         {
-           templ = lookup_template_variable (templ, targs);
-           if (!any_dependent_template_arguments_p (targs))
-             {
-               templ = finish_template_variable (templ, complain);
-               mark_used (templ);
-             }
-           RETURN (convert_from_reference (templ));
-         }
+         RETURN (lookup_and_finish_template_variable (templ, targs, complain));
 
        if (TREE_CODE (templ) == COMPONENT_REF)
          {
@@ -15727,6 +16021,10 @@ tsubst_copy_and_build (tree t,
        else
          r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR,
                                    complain|decltype_flag);
+
+       if (TREE_CODE (r) == INDIRECT_REF)
+         REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t);
+
        RETURN (r);
       }
 
@@ -15924,7 +16222,8 @@ tsubst_copy_and_build (tree t,
                                          length, stride, TREE_TYPE (op1)));
       }
     case SIZEOF_EXPR:
-      if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
+      if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))
+         || ARGUMENT_PACK_P (TREE_OPERAND (t, 0)))
        RETURN (tsubst_copy (t, args, complain, in_decl));
       /* Fall through */
       
@@ -16802,8 +17101,6 @@ tsubst_copy_and_build (tree t,
        else
          gcc_unreachable ();
        LAMBDA_EXPR_EXTRA_SCOPE (r) = scope;
-       LAMBDA_EXPR_RETURN_TYPE (r)
-         = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl);
 
        gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (t) == NULL_TREE
                    && LAMBDA_EXPR_PENDING_PROXIES (t) == NULL);
@@ -16814,6 +17111,9 @@ tsubst_copy_and_build (tree t,
           declaration of the op() for later calls to lambda_function.  */
        complete_type (type);
 
+       if (tree fn = lambda_function (type))
+         LAMBDA_EXPR_RETURN_TYPE (r) = TREE_TYPE (TREE_TYPE (fn));
+
        LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE;
 
        insert_pending_capture_proxies ();
@@ -17021,12 +17321,14 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain)
 
   /* Check to see if we already have this specialization.  */
   gen_tmpl = most_general_template (tmpl);
-  if (tmpl != gen_tmpl)
-    /* The TMPL is a partial instantiation.  To get a full set of
-       arguments we must add the arguments used to perform the
-       partial instantiation.  */
-    targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl),
-                                           targ_ptr);
+  if (TMPL_ARGS_DEPTH (targ_ptr)
+      < TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (gen_tmpl)))
+    /* targ_ptr only has the innermost template args, so add the outer ones
+       from tmpl, which could be either a partial instantiation or gen_tmpl (in
+       the case of a non-dependent call within a template definition).  */
+    targ_ptr = (add_outermost_template_args
+               (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (tmpl)),
+                targ_ptr));
 
   /* It would be nice to avoid hashing here and then again in tsubst_decl,
      but it doesn't seem to be on the hot path.  */
@@ -18206,10 +18508,9 @@ type_unification_real (tree tparms,
       if (saw_undeduced++ == 1)
        goto again;
     }
-#ifdef ENABLE_CHECKING
-  if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
+
+  if (CHECKING_P && !NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
     SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
-#endif
 
   return unify_success (explain_p);
 }
@@ -18352,7 +18653,7 @@ resolve_overloaded_unification (tree tparms,
    lvalue for the function template specialization.  */
 
 tree
-resolve_nondeduced_context (tree orig_expr)
+resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
 {
   tree expr, offset, baselink;
   bool addr;
@@ -18435,16 +18736,16 @@ resolve_nondeduced_context (tree orig_expr)
            {
              tree base
                = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0)));
-             expr = build_offset_ref (base, expr, addr, tf_warning_or_error);
+             expr = build_offset_ref (base, expr, addr, complain);
            }
          if (addr)
-           expr = cp_build_addr_expr (expr, tf_warning_or_error);
+           expr = cp_build_addr_expr (expr, complain);
          return expr;
        }
-      else if (good == 0 && badargs)
+      else if (good == 0 && badargs && (complain & tf_error))
        /* There were no good options and at least one bad one, so let the
           user know what the problem is.  */
-       instantiate_template (badfn, badargs, tf_warning_or_error);
+       instantiate_template (badfn, badargs, complain);
     }
   return orig_expr;
 }
@@ -18516,6 +18817,28 @@ try_one_overload (tree tparms,
           template args used in the function parm list with our own
           template parms.  Discard them.  */
        TREE_VEC_ELT (tempargs, i) = NULL_TREE;
+      else if (oldelt && ARGUMENT_PACK_P (oldelt))
+       {
+         /* Check that the argument at each index of the deduced argument pack
+            is equivalent to the corresponding explicitly specified argument.
+            We may have deduced more arguments than were explicitly specified,
+            and that's OK.  */
+         gcc_assert (ARGUMENT_PACK_INCOMPLETE_P (oldelt));
+         gcc_assert (ARGUMENT_PACK_ARGS (oldelt)
+                     == ARGUMENT_PACK_EXPLICIT_ARGS (oldelt));
+
+         tree explicit_pack = ARGUMENT_PACK_ARGS (oldelt);
+         tree deduced_pack = ARGUMENT_PACK_ARGS (elt);
+
+         if (TREE_VEC_LENGTH (deduced_pack)
+             < TREE_VEC_LENGTH (explicit_pack))
+           return 0;
+
+         for (int j = 0; j < TREE_VEC_LENGTH (explicit_pack); j++)
+           if (!template_args_equal (TREE_VEC_ELT (explicit_pack, j),
+                                     TREE_VEC_ELT (deduced_pack, j)))
+             return 0;
+       }
       else if (oldelt && !template_args_equal (oldelt, elt))
        return 0;
     }
@@ -18905,8 +19228,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
          tree bad_old_arg = NULL_TREE, bad_new_arg = NULL_TREE;
          tree old_args = ARGUMENT_PACK_ARGS (old_pack);
 
-         if (!comp_template_args_with_info (old_args, new_args,
-                                            &bad_old_arg, &bad_new_arg))
+         if (!comp_template_args (old_args, new_args,
+                                  &bad_old_arg, &bad_new_arg))
            /* Inconsistent unification of this parameter pack.  */
            return unify_parameter_pack_inconsistent (explain_p,
                                                      bad_old_arg,
@@ -19633,7 +19956,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
                                         explain_p, &t);
 
                  if (!t)
-                   return unify_no_common_base (explain_p, r, parm, arg);
+                   {
+                     /* Don't give the derived diagnostic if we're
+                        already dealing with the same template.  */
+                     bool same_template
+                       = (CLASSTYPE_TEMPLATE_INFO (arg)
+                          && (CLASSTYPE_TI_TEMPLATE (parm)
+                              == CLASSTYPE_TI_TEMPLATE (arg)));
+                     return unify_no_common_base (explain_p && !same_template,
+                                                  r, parm, arg);
+                   }
                }
            }
          else if (CLASSTYPE_TEMPLATE_INFO (arg)
@@ -19731,11 +20063,20 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
       return unify_template_argument_mismatch (explain_p, parm, arg);
 
     case VAR_DECL:
-      /* A non-type template parameter that is a variable should be a
-        an integral constant, in which case, it whould have been
-        folded into its (constant) value. So we should not be getting
-        a variable here.  */
-      gcc_unreachable ();
+      /* We might get a variable as a non-type template argument in parm if the
+        corresponding parameter is type-dependent.  Make any necessary
+        adjustments based on whether arg is a reference.  */
+      if (CONSTANT_CLASS_P (arg))
+       parm = fold_non_dependent_expr (parm);
+      else if (REFERENCE_REF_P (arg))
+       {
+         tree sub = TREE_OPERAND (arg, 0);
+         STRIP_NOPS (sub);
+         if (TREE_CODE (sub) == ADDR_EXPR)
+           arg = TREE_OPERAND (sub, 0);
+       }
+      /* Now use the normal expression code to check whether they match.  */
+      goto expr;
 
     case TYPE_ARGUMENT_PACK:
     case NONTYPE_ARGUMENT_PACK:
@@ -19768,7 +20109,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
       if (is_overloaded_fn (parm) || type_unknown_p (parm))
        return unify_success (explain_p);
       gcc_assert (EXPR_P (parm));
-
+    expr:
       /* We must be looking at an expression.  This can happen with
         something like:
 
@@ -20015,7 +20356,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
 
       if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION)
         {
-          int i, len2 = list_length (args2);
+          int i, len2 = remaining_arguments (args2);
           tree parmvec = make_tree_vec (1);
           tree argvec = make_tree_vec (len2);
           tree ta = args2;
@@ -20039,7 +20380,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
         }
       else if (TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
         {
-          int i, len1 = list_length (args1);
+          int i, len1 = remaining_arguments (args1);
           tree parmvec = make_tree_vec (1);
           tree argvec = make_tree_vec (len1);
           tree ta = args1;
@@ -20508,6 +20849,36 @@ most_general_template (tree decl)
   return decl;
 }
 
+/* True iff the TEMPLATE_DECL tmpl is a partial specialization.  */
+
+static bool
+partial_specialization_p (tree tmpl)
+{
+  /* Any specialization has DECL_TEMPLATE_SPECIALIZATION.  */
+  if (!DECL_TEMPLATE_SPECIALIZATION (tmpl))
+    return false;
+  tree t = DECL_TI_TEMPLATE (tmpl);
+  /* A specialization that fully specializes one of the containing classes is
+     not a partial specialization.  */
+  return (list_length (DECL_TEMPLATE_PARMS (tmpl))
+         == list_length (DECL_TEMPLATE_PARMS (t)));
+}
+
+/* If TMPL is a partial specialization, return the arguments for its primary
+   template.  */
+
+static tree
+impartial_args (tree tmpl, tree args)
+{
+  if (!partial_specialization_p (tmpl))
+    return args;
+
+  /* If TMPL is a partial specialization, we need to substitute to get
+     the args for the primary template.  */
+  return tsubst_template_args (DECL_TI_ARGS (tmpl), args,
+                              tf_warning_or_error, tmpl);
+}
+
 /* Return the most specialized of the template partial specializations
    which can produce TARGET, a specialization of some class or variable
    template.  The value returned is actually a TREE_LIST; the TREE_VALUE is
@@ -21332,7 +21703,7 @@ instantiate_decl (tree d, int defer_ok,
     return d;
 
   gen_tmpl = most_general_template (tmpl);
-  gen_args = DECL_TI_ARGS (d);
+  gen_args = impartial_args (tmpl, DECL_TI_ARGS (d));
 
   if (tmpl != gen_tmpl)
     /* We should already have the extra args.  */
@@ -21370,7 +21741,8 @@ instantiate_decl (tree d, int defer_ok,
   if (TREE_CODE (d) == FUNCTION_DECL)
     {
       deleted_p = DECL_DELETED_FN (code_pattern);
-      pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE
+      pattern_defined = ((DECL_SAVED_TREE (code_pattern) != NULL_TREE
+                         && DECL_INITIAL (code_pattern) != error_mark_node)
                         || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern)
                         || deleted_p);
     }
@@ -21570,7 +21942,7 @@ instantiate_decl (tree d, int defer_ok,
       if (enter_context)
         pop_nested_class ();
 
-      if (variable_template_p (td))
+      if (variable_template_p (gen_tmpl))
        note_variable_template_instantiation (d);
     }
   else if (TREE_CODE (d) == FUNCTION_DECL && DECL_DEFAULTED_FN (code_pattern))
@@ -22276,6 +22648,17 @@ value_dependent_expression_p (tree expression)
 
   switch (TREE_CODE (expression))
     {
+    case BASELINK:
+      /* A dependent member function of the current instantiation.  */
+      return dependent_type_p (BINFO_TYPE (BASELINK_BINFO (expression)));
+
+    case FUNCTION_DECL:
+      /* A dependent member function of the current instantiation.  */
+      if (DECL_CLASS_SCOPE_P (expression)
+         && dependent_type_p (DECL_CONTEXT (expression)))
+       return true;
+      break;
+
     case IDENTIFIER_NODE:
       /* A name that has not been looked up -- must be dependent.  */
       return true;
@@ -22302,6 +22685,7 @@ value_dependent_expression_p (tree expression)
          && (TREE_CODE (DECL_INITIAL (expression)) == TREE_LIST
              /* cp_finish_decl doesn't fold reference initializers.  */
              || TREE_CODE (TREE_TYPE (expression)) == REFERENCE_TYPE
+             || type_dependent_expression_p (DECL_INITIAL (expression))
              || value_dependent_expression_p (DECL_INITIAL (expression))))
        return true;
       return false;
@@ -22352,7 +22736,7 @@ value_dependent_expression_p (tree expression)
         return true;
       else if (TYPE_P (expression))
        return dependent_type_p (expression);
-      return instantiation_dependent_expression_p (expression);
+      return instantiation_dependent_uneval_expression_p (expression);
 
     case AT_ENCODE_EXPR:
       /* An 'encode' expression is value-dependent if the operand is
@@ -22362,7 +22746,7 @@ value_dependent_expression_p (tree expression)
 
     case NOEXCEPT_EXPR:
       expression = TREE_OPERAND (expression, 0);
-      return instantiation_dependent_expression_p (expression);
+      return instantiation_dependent_uneval_expression_p (expression);
 
     case SCOPE_REF:
       /* All instantiation-dependent expressions should also be considered
@@ -22419,10 +22803,10 @@ value_dependent_expression_p (tree expression)
 
     case CALL_EXPR:
       {
+       if (value_dependent_expression_p (CALL_EXPR_FN (expression)))
+         return true;
        tree fn = get_callee_fndecl (expression);
        int i, nargs;
-       if (!fn && value_dependent_expression_p (CALL_EXPR_FN (expression)))
-         return true;
        nargs = call_expr_nargs (expression);
        for (i = 0; i < nargs; ++i)
          {
@@ -22586,13 +22970,6 @@ type_dependent_expression_p (tree expression)
              || dependent_scope_p (scope));
     }
 
-  if (TREE_CODE (expression) == FUNCTION_DECL
-      && DECL_LANG_SPECIFIC (expression)
-      && DECL_TEMPLATE_INFO (expression)
-      && (any_dependent_template_arguments_p
-         (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
-    return true;
-
   if (TREE_CODE (expression) == TEMPLATE_DECL
       && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
     return false;
@@ -22645,13 +23022,18 @@ type_dependent_expression_p (tree expression)
       && DECL_INITIAL (expression))
    return true;
 
-  /* A variable template specialization is type-dependent if it has any
-     dependent template arguments.  */
-  if (VAR_P (expression)
+  /* A function or variable template-id is type-dependent if it has any
+     dependent template arguments.  Note that we only consider the innermost
+     template arguments here, since those are the ones that come from the
+     template-id; the template arguments for the enclosing class do not make it
+     type-dependent, they only make a member function value-dependent.  */
+  if (VAR_OR_FUNCTION_DECL_P (expression)
       && DECL_LANG_SPECIFIC (expression)
       && DECL_TEMPLATE_INFO (expression)
-      && variable_template_p (DECL_TI_TEMPLATE (expression)))
-    return any_dependent_template_arguments_p (DECL_TI_ARGS (expression));
+      && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (expression))
+      && (any_dependent_template_arguments_p
+         (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
+    return true;
 
   /* Always dependent, on the number of arguments if nothing else.  */
   if (TREE_CODE (expression) == EXPR_PACK_EXPANSION)
@@ -22709,6 +23091,22 @@ type_dependent_expression_p (tree expression)
   return (dependent_type_p (TREE_TYPE (expression)));
 }
 
+/* [temp.dep.expr]/5: A class member access expression (5.2.5) is
+   type-dependent if the expression refers to a member of the current
+   instantiation and the type of the referenced member is dependent, or the
+   class member access expression refers to a member of an unknown
+   specialization.
+
+   This function returns true if the OBJECT in such a class member access
+   expression is of an unknown specialization.  */
+
+bool
+type_dependent_object_expression_p (tree object)
+{
+  tree scope = TREE_TYPE (object);
+  return (!scope || dependent_scope_p (scope));
+}
+
 /* walk_tree callback function for instantiation_dependent_expression_p,
    below.  Returns non-zero if a dependent subexpression is found.  */
 
@@ -22733,13 +23131,6 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
     case TREE_VEC:
       return NULL_TREE;
 
-    case VAR_DECL:
-    case CONST_DECL:
-      /* A constant with a dependent initializer is dependent.  */
-      if (value_dependent_expression_p (*tp))
-       return *tp;
-      break;
-
     case TEMPLATE_PARM_INDEX:
       return *tp;
 
@@ -22765,12 +23156,6 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
        break;
       }
 
-    case TRAIT_EXPR:
-      if (value_dependent_expression_p (*tp))
-       return *tp;
-      *walk_subtrees = false;
-      return NULL_TREE;
-
     case COMPONENT_REF:
       if (identifier_p (TREE_OPERAND (*tp, 1)))
        /* In a template, finish_class_member_access_expr creates a
@@ -22821,10 +23206,15 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
 
    "An expression is instantiation-dependent if it is type-dependent
    or value-dependent, or it has a subexpression that is type-dependent
-   or value-dependent."  */
+   or value-dependent."
+
+   Except don't actually check value-dependence for unevaluated expressions,
+   because in sizeof(i) we don't care about the value of i.  Checking
+   type-dependence will in turn check value-dependence of array bounds/template
+   arguments as needed.  */
 
 bool
-instantiation_dependent_expression_p (tree expression)
+instantiation_dependent_uneval_expression_p (tree expression)
 {
   tree result;
 
@@ -22839,6 +23229,15 @@ instantiation_dependent_expression_p (tree expression)
   return result != NULL_TREE;
 }
 
+/* As above, but also check value-dependence of the expression as a whole.  */
+
+bool
+instantiation_dependent_expression_p (tree expression)
+{
+  return (instantiation_dependent_uneval_expression_p (expression)
+         || value_dependent_expression_p (expression));
+}
+
 /* Like type_dependent_expression_p, but it also works while not processing
    a template definition, i.e. during substitution or mangling.  */
 
@@ -22912,9 +23311,18 @@ dependent_template_arg_p (tree arg)
   if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT)
     arg = ARGUMENT_PACK_SELECT_ARG (arg);
 
-  if (TREE_CODE (arg) == TEMPLATE_DECL
-      || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
-    return dependent_template_p (arg);
+  if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+    return true;
+  if (TREE_CODE (arg) == TEMPLATE_DECL)
+    {
+      if (DECL_TEMPLATE_PARM_P (arg))
+       return true;
+      /* A member template of a dependent class is not necessarily
+        type-dependent, but it is a dependent template argument because it
+        will be a member of an unknown specialization to that template.  */
+      tree scope = CP_DECL_CONTEXT (arg);
+      return TYPE_P (scope) && dependent_type_p (scope);
+    }
   else if (ARGUMENT_PACK_P (arg))
     {
       tree args = ARGUMENT_PACK_ARGS (arg);
@@ -23010,7 +23418,7 @@ any_dependent_template_arguments_p (const_tree args)
   return false;
 }
 
-/* Returns TRUE if the template TMPL is dependent.  */
+/* Returns TRUE if the template TMPL is type-dependent.  */
 
 bool
 dependent_template_p (tree tmpl)
@@ -23033,9 +23441,6 @@ dependent_template_p (tree tmpl)
   /* So are names that have not been looked up.  */
   if (TREE_CODE (tmpl) == SCOPE_REF || identifier_p (tmpl))
     return true;
-  /* So are member templates of dependent classes.  */
-  if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
-    return dependent_type_p (DECL_CONTEXT (tmpl));
   return false;
 }
 
@@ -23226,9 +23631,9 @@ resolve_typename_type (tree type, bool only_current_p)
     {
       /* Ill-formed programs can cause infinite recursion here, so we
         must catch that.  */
-      TYPENAME_IS_RESOLVING_P (type) = 1;
+      TYPENAME_IS_RESOLVING_P (result) = 1;
       result = resolve_typename_type (result, only_current_p);
-      TYPENAME_IS_RESOLVING_P (type) = 0;
+      TYPENAME_IS_RESOLVING_P (result) = 0;
     }
   
   /* Qualify the resulting type.  */
@@ -23248,12 +23653,16 @@ build_non_dependent_expr (tree expr)
 {
   tree inner_expr;
 
-#ifdef ENABLE_CHECKING
-  /* Try to get a constant value for all non-dependent expressions in
-      order to expose bugs in *_dependent_expression_p and constexpr.  */
-  if (cxx_dialect >= cxx11)
+  /* When checking, try to get a constant value for all non-dependent
+     expressions in order to expose bugs in *_dependent_expression_p
+     and constexpr.  This can affect code generation, see PR70704, so
+     only do this for -fchecking=2.  */
+  if (flag_checking > 1
+      && cxx_dialect >= cxx11
+      /* Don't do this during nsdmi parsing as it can lead to
+        unexpected recursive instantiations.  */
+      && !parsing_nsdmi ())
     fold_non_dependent_expr (expr);
-#endif
 
   /* Preserve OVERLOADs; the functions must be available to resolve
      types.  */
@@ -23339,10 +23748,10 @@ make_args_non_dependent (vec<tree, va_gc> *args)
 
 /* Returns a type which represents 'auto' or 'decltype(auto)'.  We use a
    TEMPLATE_TYPE_PARM with a level one deeper than the actual template
-   parms.  */
+   parms.  If set_canonical is true, we set TYPE_CANONICAL on it.  */
 
 static tree
-make_auto_1 (tree name)
+make_auto_1 (tree name, bool set_canonical)
 {
   tree au = cxx_make_type (TEMPLATE_TYPE_PARM);
   TYPE_NAME (au) = build_decl (input_location,
@@ -23351,7 +23760,8 @@ make_auto_1 (tree name)
   TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index
     (0, processing_template_decl + 1, processing_template_decl + 1,
      TYPE_NAME (au), NULL_TREE);
-  TYPE_CANONICAL (au) = canonical_type_parameter (au);
+  if (set_canonical)
+    TYPE_CANONICAL (au) = canonical_type_parameter (au);
   DECL_ARTIFICIAL (TYPE_NAME (au)) = 1;
   SET_DECL_TEMPLATE_PARM_P (TYPE_NAME (au));
 
@@ -23361,13 +23771,43 @@ make_auto_1 (tree name)
 tree
 make_decltype_auto (void)
 {
-  return make_auto_1 (get_identifier ("decltype(auto)"));
+  return make_auto_1 (get_identifier ("decltype(auto)"), true);
 }
 
 tree
 make_auto (void)
 {
-  return make_auto_1 (get_identifier ("auto"));
+  return make_auto_1 (get_identifier ("auto"), true);
+}
+
+/* Make a "constrained auto" type-specifier. This is an
+   auto type with constraints that must be associated after
+   deduction.  The constraint is formed from the given
+   CONC and its optional sequence of arguments, which are
+   non-null if written as partial-concept-id.  */
+
+tree
+make_constrained_auto (tree con, tree args)
+{
+  tree type = make_auto_1 (get_identifier ("auto"), false);
+
+  /* Build the constraint. */
+  tree tmpl = DECL_TI_TEMPLATE (con);
+  tree expr;
+  if (VAR_P (con))
+    expr = build_concept_check (tmpl, type, args);
+  else
+    expr = build_concept_check (build_overload (tmpl, NULL_TREE), type, args);
+
+  tree constr = make_predicate_constraint (expr);
+  PLACEHOLDER_TYPE_CONSTRAINTS (type) = constr;
+
+  /* Our canonical type depends on the constraint.  */
+  TYPE_CANONICAL (type) = canonical_type_parameter (type);
+
+  /* Attach the constraint to the type declaration. */
+  tree decl = TYPE_NAME (type);
+  return decl;
 }
 
 /* Given type ARG, return std::initializer_list<ARG>.  */
@@ -23403,6 +23843,100 @@ listify_autos (tree type, tree auto_node)
   return tsubst (type, argvec, tf_warning_or_error, NULL_TREE);
 }
 
+/* Hash traits for hashing possibly constrained 'auto'
+   TEMPLATE_TYPE_PARMs for use by do_auto_deduction.  */
+
+struct auto_hash : default_hash_traits<tree>
+{
+  static inline hashval_t hash (tree);
+  static inline bool equal (tree, tree);
+};
+
+/* Hash the 'auto' T.  */
+
+inline hashval_t
+auto_hash::hash (tree t)
+{
+  if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
+    /* Matching constrained-type-specifiers denote the same template
+       parameter, so hash the constraint.  */
+    return hash_placeholder_constraint (c);
+  else
+    /* But unconstrained autos are all separate, so just hash the pointer.  */
+    return iterative_hash_object (t, 0);
+}
+
+/* Compare two 'auto's.  */
+
+inline bool
+auto_hash::equal (tree t1, tree t2)
+{
+  if (t1 == t2)
+    return true;
+
+  tree c1 = PLACEHOLDER_TYPE_CONSTRAINTS (t1);
+  tree c2 = PLACEHOLDER_TYPE_CONSTRAINTS (t2);
+
+  /* Two unconstrained autos are distinct.  */
+  if (!c1 || !c2)
+    return false;
+
+  return equivalent_placeholder_constraints (c1, c2);
+}
+
+/* for_each_template_parm callback for extract_autos: if t is a (possibly
+   constrained) auto, add it to the vector.  */
+
+static int
+extract_autos_r (tree t, void *data)
+{
+  hash_table<auto_hash> &hash = *(hash_table<auto_hash>*)data;
+  if (is_auto_or_concept (t))
+    {
+      /* All the autos were built with index 0; fix that up now.  */
+      tree *p = hash.find_slot (t, INSERT);
+      unsigned idx;
+      if (*p)
+       /* If this is a repeated constrained-type-specifier, use the index we
+          chose before.  */
+       idx = TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (*p));
+      else
+       {
+         /* Otherwise this is new, so use the current count.  */
+         *p = t;
+         idx = hash.elements () - 1;
+       }
+      TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (t)) = idx;
+    }
+
+  /* Always keep walking.  */
+  return 0;
+}
+
+/* Return a TREE_VEC of the 'auto's used in type under the Concepts TS, which
+   says they can appear anywhere in the type.  */
+
+static tree
+extract_autos (tree type)
+{
+  hash_set<tree> visited;
+  hash_table<auto_hash> hash (2);
+
+  for_each_template_parm (type, extract_autos_r, &hash, &visited, true);
+
+  tree tree_vec = make_tree_vec (hash.elements());
+  for (hash_table<auto_hash>::iterator iter = hash.begin();
+       iter != hash.end(); ++iter)
+    {
+      tree elt = *iter;
+      unsigned i = TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (elt));
+      TREE_VEC_ELT (tree_vec, i)
+       = build_tree_list (NULL_TREE, TYPE_NAME (elt));
+    }
+
+  return tree_vec;
+}
+
 /* 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.  */
 
@@ -23457,13 +23991,16 @@ do_auto_deduction (tree type, tree init, tree auto_node,
        }
     }
 
-  init = resolve_nondeduced_context (init);
+  if (type == error_mark_node)
+    return error_mark_node;
+
+  init = resolve_nondeduced_context (init, complain);
 
-  targs = make_tree_vec (1);
   if (AUTO_IS_DECLTYPE (auto_node))
     {
       bool id = (DECL_P (init) || (TREE_CODE (init) == COMPONENT_REF
                                   && !REF_PARENTHESIZED_P (init)));
+      targs = make_tree_vec (1);
       TREE_VEC_ELT (targs, 0)
        = finish_decltype_type (init, id, tf_warning_or_error);
       if (type != auto_node)
@@ -23476,14 +24013,21 @@ do_auto_deduction (tree type, tree init, tree auto_node,
   else
     {
       tree parms = build_tree_list (NULL_TREE, type);
-      tree tparms = make_tree_vec (1);
-      int val;
-
-      TREE_VEC_ELT (tparms, 0)
-       = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
-      val = type_unification_real (tparms, targs, parms, &init, 1, 0,
-                                  DEDUCE_CALL, LOOKUP_NORMAL,
-                                  NULL, /*explain_p=*/false);
+      tree tparms;
+
+      if (flag_concepts)
+       tparms = extract_autos (type);
+      else
+       {
+         tparms = make_tree_vec (1);
+         TREE_VEC_ELT (tparms, 0)
+           = build_tree_list (NULL_TREE, TYPE_NAME (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,
+                                      NULL, /*explain_p=*/false);
       if (val > 0)
        {
          if (processing_template_decl)
@@ -23500,31 +24044,14 @@ do_auto_deduction (tree type, tree init, tree auto_node,
                error ("unable to deduce lambda return type from %qE", init);
              else
                error ("unable to deduce %qT from %qE", type, init);
+             type_unification_real (tparms, targs, parms, &init, 1, 0,
+                                    DEDUCE_CALL, LOOKUP_NORMAL,
+                                    NULL, /*explain_p=*/true);
            }
          return error_mark_node;
        }
     }
 
-  /* If the list of declarators contains more than one declarator, the type
-     of each declared variable is determined as described above. If the
-     type deduced for the template parameter U is not the same in each
-     deduction, the program is ill-formed.  */
-  if (TREE_TYPE (auto_node)
-      && !same_type_p (TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0)))
-    {
-      if (cfun && auto_node == current_function_auto_return_pattern
-         && LAMBDA_FUNCTION_P (current_function_decl))
-       error ("inconsistent types %qT and %qT deduced for "
-              "lambda return type", TREE_TYPE (auto_node),
-              TREE_VEC_ELT (targs, 0));
-      else
-       error ("inconsistent deduction for %qT: %qT and then %qT",
-              auto_node, TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0));
-      return error_mark_node;
-    }
-  if (context != adc_requirement)
-    TREE_TYPE (auto_node) = TREE_VEC_ELT (targs, 0);
-
   /* Check any placeholder constraints against the deduced type. */
   if (flag_concepts && !processing_template_decl)
     if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node))
@@ -23579,7 +24106,7 @@ splice_late_return_type (tree type, tree late_return_type)
        /* In an abbreviated function template we didn't know we were dealing
           with a function template when we saw the auto return type, so update
           it to have the correct level.  */
-       return make_auto_1 (TYPE_IDENTIFIER (type));
+       return make_auto_1 (TYPE_IDENTIFIER (type), true);
     }
   return type;
 }
@@ -23598,13 +24125,35 @@ is_auto (const_tree type)
     return false;
 }
 
+/* for_each_template_parm callback for type_uses_auto.  */
+
+int
+is_auto_r (tree tp, void */*data*/)
+{
+  return is_auto_or_concept (tp);
+}
+
 /* Returns the TEMPLATE_TYPE_PARM in TYPE representing `auto' iff TYPE contains
    a use of `auto'.  Returns NULL_TREE otherwise.  */
 
 tree
 type_uses_auto (tree type)
 {
-  return find_type_usage (type, is_auto);
+  if (type == NULL_TREE)
+    return NULL_TREE;
+  else if (flag_concepts)
+    {
+      /* The Concepts TS allows multiple autos in one type-specifier; just
+        return the first one we find, do_auto_deduction will collect all of
+        them.  */
+      if (uses_template_parms (type))
+       return for_each_template_parm (type, is_auto_r, /*data*/NULL,
+                                      /*visited*/NULL, /*nondeduced*/true);
+      else
+       return NULL_TREE;
+    }
+  else
+    return find_type_usage (type, is_auto);
 }
 
 /* Returns true iff TYPE is a TEMPLATE_TYPE_PARM representing 'auto',