OSDN Git Service

* pt.c (determine_specialization): Give helpful error about missing
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index ace340e..dfe7791 100644 (file)
@@ -189,9 +189,9 @@ static tree tsubst_copy     (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_decl (tree, tree, tsubst_flags_t);
 static void perform_typedefs_access_check (tree tmpl, tree targs);
-static void append_type_to_template_for_access_check_1 (tree, tree, tree);
+static void append_type_to_template_for_access_check_1 (tree, tree, tree,
+                                                       location_t);
 static hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
-static bool primary_template_instantiation_p (const_tree);
 static tree listify (tree);
 static tree listify_autos (tree, tree);
 
@@ -287,6 +287,17 @@ finish_member_template_decl (tree decl)
   return error_mark_node;
 }
 
+/* Create a template info node.  */
+
+tree
+build_template_info (tree template_decl, tree template_args)
+{
+  tree result = make_node (TEMPLATE_INFO);
+  TI_TEMPLATE (result) = template_decl;
+  TI_ARGS (result) = template_args;
+  return result;
+}
+
 /* Return the template info node corresponding to T, whatever T is.  */
 
 tree
@@ -1501,7 +1512,8 @@ iterative_hash_template_arg (tree arg, hashval_t val)
       }
 
     case PARM_DECL:
-      val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
+      if (!DECL_ARTIFICIAL (arg))
+       val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
       return iterative_hash_template_arg (TREE_TYPE (arg), val);
 
     case TARGET_EXPR:
@@ -1933,6 +1945,10 @@ determine_specialization (tree template_id,
     {
       error ("template-id %qD for %q+D does not match any template "
             "declaration", template_id, decl);
+      if (header_count && header_count != template_count + 1)
+       inform (input_location, "saw %d %<template<>%>, need %d for "
+               "specializing a member function template",
+               header_count, template_count + 1);
       return error_mark_node;
     }
   else if ((templates && TREE_CHAIN (templates))
@@ -1941,7 +1957,7 @@ determine_specialization (tree template_id,
     {
       error ("ambiguous template specialization %qD for %q+D",
             template_id, decl);
-      chainon (candidates, templates);
+      candidates = chainon (candidates, templates);
       print_candidates (candidates);
       return error_mark_node;
     }
@@ -2492,7 +2508,7 @@ check_explicit_specialization (tree declarator,
            }
 
          /* Set up the DECL_TEMPLATE_INFO for DECL.  */
-         DECL_TEMPLATE_INFO (decl) = tree_cons (tmpl, targs, NULL_TREE);
+         DECL_TEMPLATE_INFO (decl) = build_template_info (tmpl, targs);
 
          /* Inherit default function arguments from the template
             DECL is specializing.  */
@@ -2738,7 +2754,7 @@ make_ith_pack_parameter_name (tree name, int i)
 /* Return true if T is a primary function
    or class template instantiation.  */
 
-static bool
+bool
 primary_template_instantiation_p (const_tree t)
 {
   if (!t)
@@ -2900,7 +2916,7 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     case UNION_TYPE:
     case ENUMERAL_TYPE:
       if (TYPE_TEMPLATE_INFO (t))
-       cp_walk_tree (&TREE_VALUE (TYPE_TEMPLATE_INFO (t)), 
+       cp_walk_tree (&TI_ARGS (TYPE_TEMPLATE_INFO (t)),
                      &find_parameter_packs_r, ppd, ppd->visited);
 
       *walk_subtrees = 0;
@@ -3150,6 +3166,8 @@ expand_template_argument_pack (tree args)
   for (in_arg = 0; in_arg < nargs; ++in_arg)
     {
       tree arg = TREE_VEC_ELT (args, in_arg);
+      if (arg == NULL_TREE)
+       return args;
       if (ARGUMENT_PACK_P (arg))
         {
           int num_packed = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg));
@@ -3793,12 +3811,11 @@ process_partial_specialization (tree decl)
                   || (!packed_args && i < nargs - 1))
                 {
                   if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
-                    error ("parameter pack argument %qE must be at the end of the template argument list", arg);
+                    error ("parameter pack argument %qE must be at the "
+                          "end of the template argument list", arg);
                   else
-                    error ("parameter pack argument %qT must be at the end of the template argument list", arg);
-
-                 if (packed_args)
-                   TREE_VEC_ELT (packed_args, j) = error_mark_node;
+                    error ("parameter pack argument %qT must be at the "
+                          "end of the template argument list", arg);
                 }
             }
 
@@ -4350,7 +4367,7 @@ push_template_decl_real (tree decl, bool is_friend)
          DECL_TI_TEMPLATE (decl) = new_tmpl;
          SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
          DECL_TEMPLATE_INFO (new_tmpl)
-           = tree_cons (tmpl, args, NULL_TREE);
+           = build_template_info (tmpl, args);
 
          register_specialization (new_tmpl,
                                   most_general_template (tmpl),
@@ -4469,7 +4486,7 @@ template arguments to %qD do not match original template %qD",
   if (DECL_TEMPLATE_INFO (tmpl))
     args = add_outermost_template_args (DECL_TI_ARGS (tmpl), args);
 
-  info = tree_cons (tmpl, args, NULL_TREE);
+  info = build_template_info (tmpl, args);
 
   if (DECL_IMPLICIT_TYPEDEF_P (decl))
     SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info);
@@ -4685,6 +4702,22 @@ convert_nontype_argument_function (tree type, tree expr)
   return fn;
 }
 
+/* Subroutine of convert_nontype_argument.
+   Check if EXPR of type TYPE is a valid pointer-to-member constant.
+   Emit an error otherwise.  */
+
+static bool
+check_valid_ptrmem_cst_expr (tree type, tree expr)
+{
+  STRIP_NOPS (expr);
+  if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST))
+    return true;
+  error ("%qE is not a valid template argument for type %qT",
+        expr, type);
+  error ("it must be a pointer-to-member of the form `&X::Y'");
+  return false;
+}
+
 /* Attempt to convert the non-type template parameter EXPR to the
    indicated TYPE.  If the conversion is successful, return the
    converted value.  If the conversion is unsuccessful, return
@@ -4911,6 +4944,27 @@ convert_nontype_argument (tree type, tree expr)
         shall be one of: [...]
 
         -- the address of an object or function with external linkage.  */
+      if (TREE_CODE (expr) == INDIRECT_REF
+         && TYPE_REF_OBJ_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
+       {
+         expr = TREE_OPERAND (expr, 0);
+         if (DECL_P (expr))
+           {
+             error ("%q#D is not a valid template argument for type %qT "
+                    "because a reference variable does not have a constant "
+                    "address", expr, type);
+             return NULL_TREE;
+           }
+       }
+
+      if (!DECL_P (expr))
+       {
+         error ("%qE is not a valid template argument for type %qT "
+                "because it is not an object with external linkage",
+                expr, type);
+         return NULL_TREE;
+       }
+
       if (!DECL_EXTERNAL_LINKAGE_P (expr))
        {
          error ("%qE is not a valid template argument for type %qT "
@@ -4984,6 +5038,11 @@ convert_nontype_argument (tree type, tree expr)
       if (expr == error_mark_node)
        return error_mark_node;
 
+      /* [temp.arg.nontype] bullet 1 says the pointer to member
+         expression must be a pointer-to-member constant.  */
+      if (!check_valid_ptrmem_cst_expr (type, expr))
+       return error_mark_node;
+
       /* There is no way to disable standard conversions in
         resolve_address_of_overloaded_function (called by
         instantiate_type). It is possible that the call succeeded by
@@ -5010,6 +5069,11 @@ convert_nontype_argument (tree type, tree expr)
      qualification conversions (_conv.qual_) are applied.  */
   else if (TYPE_PTRMEM_P (type))
     {
+      /* [temp.arg.nontype] bullet 1 says the pointer to member
+         expression must be a pointer-to-member constant.  */
+      if (!check_valid_ptrmem_cst_expr (type, expr))
+       return error_mark_node;
+
       expr = perform_qualification_conversions (type, expr);
       if (expr == error_mark_node)
        return expr;
@@ -5321,6 +5385,22 @@ convert_template_argument (tree parm,
   if (TREE_CODE (arg) == TYPE_PACK_EXPANSION)
     arg = PACK_EXPANSION_PATTERN (arg);
 
+  /* Deal with an injected-class-name used as a template template arg.  */
+  if (requires_tmpl_type && CLASS_TYPE_P (arg))
+    {
+      tree t = maybe_get_template_decl_from_type_decl (TYPE_NAME (arg));
+      if (TREE_CODE (t) == TEMPLATE_DECL)
+       {
+         if (complain & tf_warning_or_error)
+           pedwarn (input_location, OPT_pedantic, "injected-class-name %qD"
+                    " used as template template argument", TYPE_NAME (arg));
+         else if (flag_pedantic_errors)
+           t = arg;
+
+         arg = t;
+       }
+    }
+
   is_tmpl_type = 
     ((TREE_CODE (arg) == TEMPLATE_DECL
       && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
@@ -5402,7 +5482,7 @@ convert_template_argument (tree parm,
                                                  complain, in_decl,
                                                  args))
                {
-                 val = orig_arg;
+                 val = arg;
 
                  /* TEMPLATE_TEMPLATE_PARM node is preferred over
                     TEMPLATE_DECL.  */
@@ -5410,12 +5490,8 @@ convert_template_argument (tree parm,
                     {
                       if (DECL_TEMPLATE_TEMPLATE_PARM_P (val))
                         val = TREE_TYPE (val);
-                      else if (TREE_CODE (val) == TYPE_PACK_EXPANSION
-                               && DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
-                        {
-                          val = TREE_TYPE (arg);
-                          val = make_pack_expansion (val);
-                        }
+                     if (TREE_CODE (orig_arg) == TYPE_PACK_EXPANSION)
+                       val = make_pack_expansion (val);
                     }
                }
              else
@@ -5425,7 +5501,7 @@ convert_template_argument (tree parm,
                      error ("type/value mismatch at argument %d in "
                             "template parameter list for %qD",
                             i + 1, in_decl);
-                     error ("  expected a template of type %qD, got %qD",
+                     error ("  expected a template of type %qD, got %qT",
                             parm, orig_arg);
                    }
 
@@ -5941,15 +6017,43 @@ lookup_template_function (tree fns, tree arglist)
    TEMPLATE_DECL.  If DECL is a TYPE_DECL for current_class_type,
    or one of its enclosing classes, and that type is a template,
    return the associated TEMPLATE_DECL.  Otherwise, the original
-   DECL is returned.  */
+   DECL is returned.
+
+   Also handle the case when DECL is a TREE_LIST of ambiguous
+   injected-class-names from different bases.  */
 
 tree
 maybe_get_template_decl_from_type_decl (tree decl)
 {
+  if (decl == NULL_TREE)
+    return decl;
+
+  /* DR 176: A lookup that finds an injected-class-name (10.2
+     [class.member.lookup]) can result in an ambiguity in certain cases
+     (for example, if it is found in more than one base class). If all of
+     the injected-class-names that are found refer to specializations of
+     the same class template, and if the name is followed by a
+     template-argument-list, the reference refers to the class template
+     itself and not a specialization thereof, and is not ambiguous.  */
+  if (TREE_CODE (decl) == TREE_LIST)
+    {
+      tree t, tmpl = NULL_TREE;
+      for (t = decl; t; t = TREE_CHAIN (t))
+       {
+         tree elt = maybe_get_template_decl_from_type_decl (TREE_VALUE (t));
+         if (!tmpl)
+           tmpl = elt;
+         else if (tmpl != elt)
+           break;
+       }
+      if (tmpl && t == NULL_TREE)
+       return tmpl;
+      else
+       return decl;
+    }
+
   return (decl != NULL_TREE
-         && TREE_CODE (decl) == TYPE_DECL
-         && DECL_ARTIFICIAL (decl)
-         && CLASS_TYPE_P (TREE_TYPE (decl))
+         && DECL_SELF_REFERENCE_P (decl)
          && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl)))
     ? CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)) : decl;
 }
@@ -6324,7 +6428,6 @@ lookup_template_class (tree d1,
 
          type_decl = create_implicit_typedef (DECL_NAME (gen_tmpl), t);
          DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);
-         TYPE_STUB_DECL (t) = type_decl;
          DECL_SOURCE_LOCATION (type_decl)
            = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (template_type));
        }
@@ -6361,7 +6464,7 @@ lookup_template_class (tree d1,
          found = CLASSTYPE_TI_TEMPLATE (found);
        }
 
-      SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
+      SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
 
       elt.spec = t;
       slot = (spec_entry **) htab_find_slot_with_hash (type_specializations,
@@ -6437,7 +6540,7 @@ 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 (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
+      else if (for_each_template_parm (TI_ARGS (TYPE_TEMPLATE_INFO (t)),
                                       fn, data, pfd->visited, 
                                       pfd->include_nondeduced_p))
        return error_mark_node;
@@ -7293,17 +7396,24 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
 static void
 perform_typedefs_access_check (tree tmpl, tree targs)
 {
-  tree t;
+  location_t saved_location;
+  int i;
+  qualified_typedef_usage_t *iter;
 
   if (!tmpl
       || (!CLASS_TYPE_P (tmpl)
          && TREE_CODE (tmpl) != FUNCTION_DECL))
     return;
 
-  for (t = get_types_needing_access_check (tmpl); t; t = TREE_CHAIN (t))
+  saved_location = input_location;
+  for (i = 0;
+       VEC_iterate (qualified_typedef_usage_t,
+                   get_types_needing_access_check (tmpl),
+                   i, iter);
+       ++i)
     {
-      tree type_decl = TREE_PURPOSE (t);
-      tree type_scope = TREE_VALUE (t);
+      tree type_decl = iter->typedef_decl;
+      tree type_scope = iter->context;
 
       if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
        continue;
@@ -7313,9 +7423,13 @@ perform_typedefs_access_check (tree tmpl, tree targs)
       if (uses_template_parms (type_scope))
        type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE);
 
+      /* Make access check error messages point to the location
+         of the use of the typedef.  */
+      input_location = iter->locus;
       perform_or_defer_access_check (TYPE_BINFO (type_scope),
                                     type_decl, type_decl);
     }
+    input_location = saved_location;
 }
 
 tree
@@ -7325,13 +7439,14 @@ instantiate_class_template (tree type)
   tree typedecl;
   tree pbinfo;
   tree base_list;
+  unsigned int saved_maximum_field_alignment;
 
   if (type == error_mark_node)
     return error_mark_node;
 
   if (TYPE_BEING_DEFINED (type)
       || COMPLETE_TYPE_P (type)
-      || dependent_type_p (type))
+      || uses_template_parms (type))
     return type;
 
   /* Figure out which template is being instantiated.  */
@@ -7385,6 +7500,9 @@ instantiate_class_template (tree type)
   push_deferring_access_checks (dk_no_deferred);
 
   push_to_top_level ();
+  /* Use #pragma pack from the template context.  */
+  saved_maximum_field_alignment = maximum_field_alignment;
+  maximum_field_alignment = TYPE_PRECISION (pattern);
 
   SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
 
@@ -7800,6 +7918,7 @@ instantiate_class_template (tree type)
   perform_typedefs_access_check (pattern, args);
   perform_deferred_access_checks ();
   pop_nested_class ();
+  maximum_field_alignment = saved_maximum_field_alignment;
   pop_from_top_level ();
   pop_deferring_access_checks ();
   pop_tinst_level ();
@@ -8562,7 +8681,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
        TREE_CHAIN (r) = NULL_TREE;
 
-       DECL_TEMPLATE_INFO (r) = build_tree_list (t, args);
+       DECL_TEMPLATE_INFO (r) = build_template_info (t, args);
 
        if (TREE_CODE (decl) == TYPE_DECL)
          {
@@ -8791,7 +8910,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        if (gen_tmpl)
          {
            DECL_TEMPLATE_INFO (r)
-             = tree_cons (gen_tmpl, argvec, NULL_TREE);
+             = build_template_info (gen_tmpl, argvec);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
            register_specialization (r, gen_tmpl, argvec, false, hash);
 
@@ -9205,7 +9324,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_EXTERNAL (r) = 1;
 
            register_specialization (r, gen_tmpl, argvec, false, hash);
-           DECL_TEMPLATE_INFO (r) = tree_cons (tmpl, argvec, NULL_TREE);
+           DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
          }
        else if (cp_unevaluated_operand)
@@ -9814,7 +9933,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                      return error_mark_node;
 
                    TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
-                     = tree_cons (TYPE_TI_TEMPLATE (t), argvec, NULL_TREE);
+                     = build_template_info (TYPE_TI_TEMPLATE (t), argvec);
                  }
              }
            break;
@@ -9983,13 +10102,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          {
            /* The type of the implicit object parameter gets its
               cv-qualifiers from the FUNCTION_TYPE. */
-           tree method_type;
-           tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r),
-                                                     cp_type_quals (type));
            tree memptr;
-           method_type = build_method_type_directly (this_type,
-                                                     TREE_TYPE (type),
-                                                     TYPE_ARG_TYPES (type));
+           tree method_type = build_memfn_type (type, r, cp_type_quals (type));
            memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
            return cp_build_qualified_type_real (memptr, cp_type_quals (t),
                                                 complain);
@@ -10193,10 +10307,17 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree type;
 
-       type = finish_typeof (tsubst_expr 
-                             (TYPEOF_TYPE_EXPR (t), args,
-                              complain, in_decl,
-                              /*integral_constant_expression_p=*/false));
+       ++cp_unevaluated_operand;
+       ++c_inhibit_evaluation_warnings;
+
+       type = tsubst_expr (TYPEOF_TYPE_EXPR (t), args,
+                           complain, in_decl,
+                           /*integral_constant_expression_p=*/false);
+
+       --cp_unevaluated_operand;
+       --c_inhibit_evaluation_warnings;
+
+       type = finish_typeof (type);
        return cp_build_qualified_type_real (type,
                                             cp_type_quals (t)
                                             | cp_type_quals (type),
@@ -10284,7 +10405,7 @@ tsubst_baselink (tree baselink, tree object_type,
     qualifying_scope = tsubst (qualifying_scope, args,
                               complain, in_decl);
     fns = BASELINK_FUNCTIONS (baselink);
-    optype = BASELINK_OPTYPE (baselink);
+    optype = tsubst (BASELINK_OPTYPE (baselink), args, complain, in_decl);
     if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
       {
        template_id_p = true;
@@ -10295,6 +10416,8 @@ tsubst_baselink (tree baselink, tree object_type,
                                                complain, in_decl);
       }
     name = DECL_NAME (get_first_fn (fns));
+    if (IDENTIFIER_TYPENAME_P (name))
+      name = mangle_conv_op_name_for_type (optype);
     baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
 
     /* If lookup found a single function, mark it as used at this
@@ -10313,8 +10436,7 @@ tsubst_baselink (tree baselink, tree object_type,
                    BASELINK_FUNCTIONS (baselink),
                    template_args);
     /* Update the conversion operator type.  */
-    BASELINK_OPTYPE (baselink) 
-      = tsubst (optype, args, complain, in_decl);
+    BASELINK_OPTYPE (baselink) = optype;
 
     if (!object_type)
       object_type = current_class_type;
@@ -12478,7 +12600,7 @@ tsubst_copy_and_build (tree t,
 }
 
 /* Verify that the instantiated ARGS are valid. For type arguments,
-   make sure that the type is not variably modified. For non-type arguments,
+   make sure that the type's linkage is ok. For non-type arguments,
    make sure they are constants if they are integral or enumerations.
    Emit an error under control of COMPLAIN, and return TRUE on error.  */
 
@@ -12499,7 +12621,33 @@ check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain)
     }
   else if (TYPE_P (t))
     {
-      if (variably_modified_type_p (t, NULL_TREE))
+      /* [basic.link]: A name with no linkage (notably, the name
+        of a class or enumeration declared in a local scope)
+        shall not be used to declare an entity with linkage.
+        This implies that names with no linkage cannot be used as
+        template arguments
+
+        DR 757 relaxes this restriction for C++0x.  */
+      tree nt = (cxx_dialect > cxx98 ? NULL_TREE
+                : no_linkage_check (t, /*relaxed_p=*/false));
+
+      if (nt)
+       {
+         /* DR 488 makes use of a type with no linkage cause
+            type deduction to fail.  */
+         if (complain & tf_error)
+           {
+             if (TYPE_ANONYMOUS_P (nt))
+               error ("%qT is/uses anonymous type", t);
+             else
+               error ("template argument for %qD uses local type %qT",
+                      tmpl, t);
+           }
+         return true;
+       }
+      /* In order to avoid all sorts of complications, we do not
+        allow variably-modified types as template arguments.  */
+      else if (variably_modified_type_p (t, NULL_TREE))
        {
          if (complain & tf_error)
            error ("%qT is a variably modified type", t);
@@ -14801,6 +14949,35 @@ mark_decl_instantiated (tree result, int extern_p)
   DECL_INTERFACE_KNOWN (result) = 1;
 }
 
+/* Subroutine of more_specialized_fn: check whether TARGS is missing any
+   important template arguments.  If any are missing, we check whether
+   they're important by using error_mark_node for substituting into any
+   args that were used for partial ordering (the ones between ARGS and END)
+   and seeing if it bubbles up.  */
+
+static bool
+check_undeduced_parms (tree targs, tree args, tree end)
+{
+  bool found = false;
+  int i;
+  for (i = TREE_VEC_LENGTH (targs) - 1; i >= 0; --i)
+    if (TREE_VEC_ELT (targs, i) == NULL_TREE)
+      {
+       found = true;
+       TREE_VEC_ELT (targs, i) = error_mark_node;
+      }
+  if (found)
+    {
+      for (; args != end; args = TREE_CHAIN (args))
+       {
+         tree substed = tsubst (TREE_VALUE (args), targs, tf_none, NULL_TREE);
+         if (substed == error_mark_node)
+           return true;
+       }
+    }
+  return false;
+}
+
 /* Given two function templates PAT1 and PAT2, return:
 
    1 if PAT1 is more specialized than PAT2 as described in [temp.func.order].
@@ -14824,8 +15001,12 @@ mark_decl_instantiated (tree result, int extern_p)
    neither is more cv-qualified, they both are equal).  Unlike regular
    deduction, after all the arguments have been deduced in this way,
    we do *not* verify the deduced template argument values can be
-   substituted into non-deduced contexts, nor do we have to verify
-   that all template arguments have been deduced.  */
+   substituted into non-deduced contexts.
+
+   The logic can be a bit confusing here, because we look at deduce1 and
+   targs1 to see if pat2 is at least as specialized, and vice versa; if we
+   can find template arguments for pat1 to make arg1 look like arg2, that
+   means that arg2 is at least as specialized as arg1.  */
 
 int
 more_specialized_fn (tree pat1, tree pat2, int len)
@@ -14838,8 +15019,9 @@ more_specialized_fn (tree pat1, tree pat2, int len)
   tree tparms2 = DECL_INNERMOST_TEMPLATE_PARMS (pat2);
   tree args1 = TYPE_ARG_TYPES (TREE_TYPE (decl1));
   tree args2 = TYPE_ARG_TYPES (TREE_TYPE (decl2));
-  int better1 = 0;
-  int better2 = 0;
+  tree origs1, origs2;
+  bool lose1 = false;
+  bool lose2 = false;
 
   /* Remove the this parameter from non-static member functions.  If
      one is a non-static member function and the other is not a static
@@ -14878,6 +15060,9 @@ more_specialized_fn (tree pat1, tree pat2, int len)
 
   processing_template_decl++;
 
+  origs1 = args1;
+  origs2 = args2;
+
   while (len--
         /* Stop when an ellipsis is seen.  */
         && args1 != NULL_TREE && args2 != NULL_TREE)
@@ -15012,28 +15197,37 @@ more_specialized_fn (tree pat1, tree pat2, int len)
           deduce2 = !unify (tparms2, targs2, arg2, arg1, UNIFY_ALLOW_NONE);
         }
 
+      /* If we couldn't deduce arguments for tparms1 to make arg1 match
+        arg2, then arg2 is not as specialized as arg1.  */
       if (!deduce1)
-       better2 = -1;
+       lose2 = true;
       if (!deduce2)
-       better1 = -1;
-      if (better1 < 0 && better2 < 0)
-       /* We've failed to deduce something in either direction.
-          These must be unordered.  */
-       break;
-
-      if (deduce1 && deduce2 && quals1 >= 0 && quals2 >= 0)
+       lose1 = true;
+
+      /* "If, for a given type, deduction succeeds in both directions
+        (i.e., the types are identical after the transformations above)
+        and if the type from the argument template is more cv-qualified
+        than the type from the parameter template (as described above)
+        that type is considered to be more specialized than the other. If
+        neither type is more cv-qualified than the other then neither type
+        is more specialized than the other."
+
+         We check same_type_p explicitly because deduction can also succeed
+         in both directions when there is a nondeduced context.  */
+      if (deduce1 && deduce2
+         && quals1 != quals2 && quals1 >= 0 && quals2 >= 0
+         && same_type_p (arg1, arg2))
        {
-         /* Deduces in both directions, see if quals can
-            disambiguate.  Pretend the worse one failed to deduce. */
          if ((quals1 & quals2) == quals2)
-           deduce1 = 0;
+           lose2 = true;
          if ((quals1 & quals2) == quals1)
-           deduce2 = 0;
+           lose1 = true;
        }
-      if (deduce1 && !deduce2 && !better2)
-       better2 = 1;
-      if (deduce2 && !deduce1 && !better1)
-       better1 = 1;
+
+      if (lose1 && lose2)
+       /* We've failed to deduce something in either direction.
+          These must be unordered.  */
+       break;
 
       if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION
           || TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
@@ -15045,22 +15239,38 @@ more_specialized_fn (tree pat1, tree pat2, int len)
       args2 = TREE_CHAIN (args2);
     }
 
+  /* "In most cases, all template parameters must have values in order for
+     deduction to succeed, but for partial ordering purposes a template
+     parameter may remain without a value provided it is not used in the
+     types being used for partial ordering."
+
+     Thus, if we are missing any of the targs1 we need to substitute into
+     origs1, then pat2 is not as specialized as pat1.  This can happen when
+     there is a nondeduced context.  */
+  if (!lose2 && check_undeduced_parms (targs1, origs1, args1))
+    lose2 = true;
+  if (!lose1 && check_undeduced_parms (targs2, origs2, args2))
+    lose1 = true;
+
   processing_template_decl--;
 
   /* All things being equal, if the next argument is a pack expansion
      for one function but not for the other, prefer the
-     non-variadic function.  */
-  if ((better1 > 0) - (better2 > 0) == 0
+     non-variadic function.  FIXME this is bogus; see c++/41958.  */
+  if (lose1 == lose2
       && args1 && TREE_VALUE (args1)
       && args2 && TREE_VALUE (args2))
     {
-      if (TREE_CODE (TREE_VALUE (args1)) == TYPE_PACK_EXPANSION)
-        return TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION ? 0 : -1;
-      else if (TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION)
-        return 1;
+      lose1 = TREE_CODE (TREE_VALUE (args1)) == TYPE_PACK_EXPANSION;
+      lose2 = TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION;
     }
 
-  return (better1 > 0) - (better2 > 0);
+  if (lose1 == lose2)
+    return 0;
+  else if (!lose1)
+    return 1;
+  else
+    return -1;
 }
 
 /* Determine which of two partial specializations is more specialized.
@@ -17567,6 +17777,9 @@ resolve_typename_type (tree type, bool only_current_p)
      to look inside it.  */
   if (only_current_p && !currently_open_class (scope))
     return type;
+  /* If this is a typedef, we don't want to look inside (c++/11987).  */
+  if (typedef_variant_p (type))
+    return type;
   /* If SCOPE isn't the template itself, it will not have a valid
      TYPE_FIELDS list.  */
   if (same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope)))
@@ -17743,10 +17956,7 @@ make_args_non_dependent (VEC(tree,gc) *args)
 tree
 make_auto (void)
 {
-  tree au;
-
-  /* ??? Is it worth caching this for multiple autos at the same level?  */
-  au = cxx_make_type (TEMPLATE_TYPE_PARM);
+  tree au = cxx_make_type (TEMPLATE_TYPE_PARM);
   TYPE_NAME (au) = build_decl (BUILTINS_LOCATION,
                               TYPE_DECL, get_identifier ("auto"), au);
   TYPE_STUB_DECL (au) = TYPE_NAME (au);
@@ -17824,6 +18034,19 @@ do_auto_deduction (tree type, tree init, tree auto_node)
       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)))
+    {
+      error ("inconsistent deduction for %qT: %qT and then %qT",
+            auto_node, TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0));
+      return error_mark_node;
+    }
+  TREE_TYPE (auto_node) = TREE_VEC_ELT (targs, 0);
+
   if (processing_template_decl)
     targs = add_to_template_args (current_template_args (), targs);
   return tsubst (type, targs, tf_warning_or_error, NULL_TREE);
@@ -17883,28 +18106,29 @@ type_uses_auto (tree type)
   return NULL_TREE;
 }
 
-/* For a given template T, return the list of typedefs referenced
+/* For a given template T, return the vector of typedefs referenced
    in T for which access check is needed at T instantiation time.
    T is either  a FUNCTION_DECL or a RECORD_TYPE.
    Those typedefs were added to T by the function
    append_type_to_template_for_access_check.  */
 
-tree
+VEC(qualified_typedef_usage_t,gc)*
 get_types_needing_access_check (tree t)
 {
-  tree ti, result = NULL_TREE;
+  tree ti;
+  VEC(qualified_typedef_usage_t,gc) *result = NULL;
 
   if (!t || t == error_mark_node)
-    return t;
+    return NULL;
 
   if (!(ti = get_template_info (t)))
-    return NULL_TREE;
+    return NULL;
 
   if (CLASS_TYPE_P (t)
       || TREE_CODE (t) == FUNCTION_DECL)
     {
       if (!TI_TEMPLATE (ti))
-       return NULL_TREE;
+       return NULL;
 
       result = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti);
     }
@@ -17918,6 +18142,7 @@ get_types_needing_access_check (tree t)
    T is either a FUNCTION_DECL or a RECORD_TYPE.
    TYPE_DECL is a TYPE_DECL node representing a typedef.
    SCOPE is the scope through which TYPE_DECL is accessed.
+   LOCATION is the location of the usage point of TYPE_DECL.
 
    This function is a subroutine of
    append_type_to_template_for_access_check.  */
@@ -17925,8 +18150,10 @@ get_types_needing_access_check (tree t)
 static void
 append_type_to_template_for_access_check_1 (tree t,
                                            tree type_decl,
-                                           tree scope)
+                                           tree scope,
+                                           location_t location)
 {
+  qualified_typedef_usage_t typedef_usage;
   tree ti;
 
   if (!t || t == error_mark_node)
@@ -17943,14 +18170,20 @@ append_type_to_template_for_access_check_1 (tree t,
 
   gcc_assert (TI_TEMPLATE (ti));
 
-  TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti) =
-    tree_cons (type_decl, scope, TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti));
+  typedef_usage.typedef_decl = type_decl;
+  typedef_usage.context = scope;
+  typedef_usage.locus = location;
+
+  VEC_safe_push (qualified_typedef_usage_t, gc,
+                TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti),
+                &typedef_usage);
 }
 
 /* Append TYPE_DECL to the template TEMPL.
    TEMPL is either a class type, a FUNCTION_DECL or a a TEMPLATE_DECL.
    At TEMPL instanciation time, TYPE_DECL will be checked to see
    if it can be accessed through SCOPE.
+   LOCATION is the location of the usage point of TYPE_DECL.
 
    e.g. consider the following code snippet:
 
@@ -17961,7 +18194,7 @@ append_type_to_template_for_access_check_1 (tree t,
 
      template<class U> struct S
      {
-       C::myint mi;
+       C::myint mi; // <-- usage point of the typedef C::myint
      };
 
      S<char> s;
@@ -17978,25 +18211,25 @@ append_type_to_template_for_access_check_1 (tree t,
 void
 append_type_to_template_for_access_check (tree templ,
                                           tree type_decl,
-                                         tree scope)
+                                         tree scope,
+                                         location_t location)
 {
-  tree node;
+  qualified_typedef_usage_t *iter;
+  int i;
 
   gcc_assert (type_decl && (TREE_CODE (type_decl) == TYPE_DECL));
 
   /* Make sure we don't append the type to the template twice.  */
-  for (node = get_types_needing_access_check (templ);
-       node;
-       node = TREE_CHAIN (node))
-    {
-      tree decl = TREE_PURPOSE (node);
-      tree type_scope = TREE_VALUE (node);
-
-      if (decl == type_decl && type_scope == scope)
-       return;
-    }
+  for (i = 0;
+       VEC_iterate (qualified_typedef_usage_t,
+                   get_types_needing_access_check (templ),
+                   i, iter);
+       ++i)
+    if (iter->typedef_decl == type_decl && scope == iter->context)
+      return;
 
-  append_type_to_template_for_access_check_1 (templ, type_decl, scope);
+  append_type_to_template_for_access_check_1 (templ, type_decl,
+                                             scope, location);
 }
 
 /* Set up the hash tables for template instantiations.  */