OSDN Git Service

PR c++/28903
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index fbe01db..715b946 100644 (file)
@@ -104,7 +104,7 @@ static tree classtype_mangled_name (tree);
 static char* mangle_class_name_for_template (const char *, tree, tree);
 static tree tsubst_initializer_list (tree, tree);
 static tree get_class_bindings (tree, tree, tree);
-static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, 
+static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
                                   bool, bool);
 static void tsubst_enum        (tree, tree, tree);
 static tree add_to_template_args (tree, tree);
@@ -150,7 +150,6 @@ static tree get_template_base (tree, tree, tree, tree);
 static tree try_class_unification (tree, tree, tree, tree);
 static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
                                           tree, tree);
-static tree determine_specialization (tree, tree, tree *, int, int);
 static int template_args_equal (tree, tree);
 static void tsubst_default_arguments (tree);
 static tree for_each_template_parm_r (tree *, int *, void *);
@@ -160,7 +159,7 @@ static int invalid_nontype_parm_type_p (tree, tsubst_flags_t);
 static int eq_local_specializations (const void *, const void *);
 static bool dependent_type_p_r (tree);
 static tree tsubst (tree, tree, tsubst_flags_t, tree);
-static tree tsubst_expr        (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_expr        (tree, tree, tsubst_flags_t, tree, bool);
 static tree tsubst_copy        (tree, tree, tsubst_flags_t, tree);
 
 /* Make the current scope suitable for access checking when we are
@@ -338,6 +337,10 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
     {
       tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+
+      if (parm == error_mark_node)
+       continue;
+
       gcc_assert (DECL_P (parm));
 
       switch (TREE_CODE (parm))
@@ -659,7 +662,7 @@ check_explicit_instantiation_namespace (tree spec)
   tree ns;
 
   /* DR 275: An explicit instantiation shall appear in an enclosing
-     namespace of its template.  */ 
+     namespace of its template.  */
   ns = decl_namespace_context (spec);
   if (!is_ancestor (current_namespace, ns))
     pedwarn ("explicit instantiation of %qD in namespace %qD "
@@ -670,13 +673,20 @@ check_explicit_instantiation_namespace (tree spec)
 /* The TYPE is being declared.  If it is a template type, that means it
    is a partial specialization.  Do appropriate error-checking.  */
 
-void
+tree
 maybe_process_partial_specialization (tree type)
 {
   tree context;
 
   if (type == error_mark_node)
-    return;
+    return error_mark_node;
+
+  if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+    {
+      error ("name of class shadows template template parameter %qD",
+            TYPE_NAME (type));
+      return error_mark_node;
+    }
 
   context = TYPE_CONTEXT (type);
 
@@ -761,7 +771,12 @@ maybe_process_partial_specialization (tree type)
        }
     }
   else if (processing_specialization)
-    error ("explicit specialization of non-template %qT", type);
+    {
+      error ("explicit specialization of non-template %qT", type);
+      return error_mark_node;
+    }
+
+  return type;
 }
 
 /* Returns nonzero if we can optimize the retrieval of specializations
@@ -812,6 +827,9 @@ static tree
 retrieve_specialization (tree tmpl, tree args,
                         bool class_specializations_p)
 {
+  if (args == error_mark_node)
+    return NULL_TREE;
+
   gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
 
   /* There should be as many levels of arguments as there are
@@ -896,7 +914,7 @@ static tree
 retrieve_local_specialization (tree tmpl)
 {
   tree spec = (tree) htab_find_with_hash (local_specializations, tmpl,
-                                          htab_hash_pointer (tmpl));
+                                         htab_hash_pointer (tmpl));
   return spec ? TREE_PURPOSE (spec) : NULL_TREE;
 }
 
@@ -1157,7 +1175,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
            {
              error ("specialization of %qD after instantiation",
                     fn);
-             return spec;
+             return error_mark_node;
            }
          else
            {
@@ -1188,15 +1206,15 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
              DECL_INITIAL (fn) = NULL_TREE;
              duplicate_decls (spec, fn, is_friend);
              /* The call to duplicate_decls will have applied
-                [temp.expl.spec]: 
+                [temp.expl.spec]:
 
-                  An explicit specialization of a function template
+                  An explicit specialization of a function template
                   is inline only if it is explicitly declared to be,
                   and independently of whether its function template
                   is.
 
                to the primary function; now copy the inline bits to
-               the various clones.  */   
+               the various clones.  */
              FOR_EACH_CLONE (clone, fn)
                {
                  DECL_DECLARED_INLINE_P (clone)
@@ -1225,7 +1243,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
      template it is specializing.  */
   if (DECL_TEMPLATE_SPECIALIZATION (spec)
       && !check_specialization_namespace (tmpl))
-    DECL_CONTEXT (spec) = decl_namespace_context (tmpl);
+    DECL_CONTEXT (spec) = FROB_CONTEXT (decl_namespace_context (tmpl));
 
   if (!optimize_specialization_lookup_p (tmpl))
     DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
@@ -1321,6 +1339,11 @@ print_candidates (tree fns)
    template classes that appeared in the name of the function. See
    check_explicit_specialization for a more accurate description.
 
+   TSK indicates what kind of template declaration (if any) is being
+   declared.  TSK_TEMPLATE indicates that the declaration given by
+   DECL, though a FUNCTION_DECL, has template parameters, and is
+   therefore a template function.
+
    The template args (those explicitly specified and those deduced)
    are output in a newly created vector *TARGS_OUT.
 
@@ -1332,7 +1355,8 @@ determine_specialization (tree template_id,
                          tree decl,
                          tree* targs_out,
                          int need_member_template,
-                         int template_count)
+                         int template_count,
+                         tmpl_spec_kind tsk)
 {
   tree fns;
   tree targs;
@@ -1349,7 +1373,7 @@ determine_specialization (tree template_id,
 
   *targs_out = NULL_TREE;
 
-  if (template_id == error_mark_node)
+  if (template_id == error_mark_node || decl == error_mark_node)
     return error_mark_node;
 
   fns = TREE_OPERAND (template_id, 0);
@@ -1446,10 +1470,22 @@ determine_specialization (tree template_id,
          if (current_binding_level->kind == sk_template_parms
              && !current_binding_level->explicit_spec_p
              && (TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (fn))
-                 != TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS 
+                 != TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
                                      (current_template_parms))))
            continue;
 
+         /* Function templates cannot be specializations; there are
+            no partial specializations of functions.  Therefore, if
+            the type of DECL does not match FN, there is no
+            match.  */
+         if (tsk == tsk_template)
+           {
+             if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
+                            decl_arg_types))
+               candidates = tree_cons (NULL_TREE, fn, candidates);
+             continue;
+           }
+
          /* See whether this function might be a specialization of this
             template.  */
          targs = get_bindings (fn, decl, explicit_targs, /*check_ret=*/true);
@@ -1576,10 +1612,14 @@ determine_specialization (tree template_id,
   /* We have one, and exactly one, match.  */
   if (candidates)
     {
+      tree fn = TREE_VALUE (candidates);
+      /* DECL is a re-declaration of a template function.  */
+      if (TREE_CODE (fn) == TEMPLATE_DECL)
+       return fn;
       /* It was a specialization of an ordinary member function in a
         template class.  */
-      *targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates)));
-      return DECL_TI_TEMPLATE (TREE_VALUE (candidates));
+      *targs_out = copy_node (DECL_TI_ARGS (fn));
+      return DECL_TI_TEMPLATE (fn);
     }
 
   /* It was a specialization of a template.  */
@@ -2042,7 +2082,8 @@ check_explicit_specialization (tree declarator,
       tmpl = determine_specialization (declarator, decl,
                                       &targs,
                                       member_specialization,
-                                      template_count);
+                                      template_count,
+                                      tsk);
 
       if (!tmpl || tmpl == error_mark_node)
        /* We couldn't figure out what this declaration was
@@ -2088,8 +2129,8 @@ check_explicit_specialization (tree declarator,
            revert_static_member_fn (decl);
 
          /* If this is a specialization of a member template of a
-            template class.  In we want to return the TEMPLATE_DECL,
-            not the specialization of it.  */
+            template class, we want to return the TEMPLATE_DECL, not
+            the specialization of it.  */
          if (tsk == tsk_template)
            {
              SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
@@ -2118,24 +2159,18 @@ check_explicit_specialization (tree declarator,
             template it specializes.  */
          TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl);
          TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl);
-         /* The specialization has the same visibility as the
-            template it specializes.  */
-         if (DECL_VISIBILITY_SPECIFIED (gen_tmpl))
-           {
-             DECL_VISIBILITY_SPECIFIED (decl) = 1;
-             DECL_VISIBILITY (decl) = DECL_VISIBILITY (gen_tmpl);
-           }
+
          /* If DECL is a friend declaration, declared using an
             unqualified name, the namespace associated with DECL may
             have been set incorrectly.  For example, in:
-            
-              template <typename T> void f(T); 
-               namespace N {
-                struct S { friend void f<int>(int); }
-               }
-
-             we will have set the DECL_CONTEXT for the friend
-             declaration to N, rather than to the global namespace.  */
+
+              template <typename T> void f(T);
+              namespace N {
+                struct S { friend void f<int>(int); }
+              }
+
+            we will have set the DECL_CONTEXT for the friend
+            declaration to N, rather than to the global namespace.  */
          if (DECL_NAMESPACE_SCOPE_P (decl))
            DECL_CONTEXT (decl) = DECL_CONTEXT (tmpl);
 
@@ -2188,8 +2223,13 @@ comp_template_parms (tree parms1, tree parms2)
 
       for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
        {
-         tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
-         tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
+          tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
+          tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
+
+          /* If either of the template parameters are invalid, assume
+             they match for the sake of error recovery. */
+          if (parm1 == error_mark_node || parm2 == error_mark_node)
+            return 1;
 
          if (TREE_CODE (parm1) != TREE_CODE (parm2))
            return 0;
@@ -2312,30 +2352,34 @@ reduce_template_parm_level (tree index, tree type, int levels)
   return TEMPLATE_PARM_DESCENDANTS (index);
 }
 
-/* Process information from new template parameter NEXT and append it to the
+/* Process information from new template parameter PARM and append it to the
    LIST being built.  This new parameter is a non-type parameter iff
    IS_NON_TYPE is true.  */
 
 tree
-process_template_parm (tree list, tree next, bool is_non_type)
+process_template_parm (tree list, tree parm, bool is_non_type)
 {
-  tree parm;
   tree decl = 0;
   tree defval;
-  int idx;
+  tree err_parm_list;
+  int idx = 0;
 
-  parm = next;
   gcc_assert (TREE_CODE (parm) == TREE_LIST);
   defval = TREE_PURPOSE (parm);
 
   if (list)
     {
-      tree p = TREE_VALUE (tree_last (list));
+      tree p = tree_last (list);
+
+      if (p && TREE_VALUE (p) != error_mark_node)
+        {
+          p = TREE_VALUE (p);
+          if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
+            idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));
+          else
+            idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));
+        }
 
-      if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
-       idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));
-      else
-       idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));
       ++idx;
     }
   else
@@ -2347,18 +2391,31 @@ process_template_parm (tree list, tree next, bool is_non_type)
 
       SET_DECL_TEMPLATE_PARM_P (parm);
 
-      /* [temp.param]
-
-        The top-level cv-qualifiers on the template-parameter are
-        ignored when determining its type.  */
-      TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
+      if (TREE_TYPE (parm) == error_mark_node)
+        {
+          err_parm_list = build_tree_list (defval, parm);
+          TREE_VALUE (err_parm_list) = error_mark_node;
+          return chainon (list, err_parm_list);
+        }
+      else
+      {
+       /* [temp.param]
+
+          The top-level cv-qualifiers on the template-parameter are
+          ignored when determining its type.  */
+       TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
+       if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
+          {
+            err_parm_list = build_tree_list (defval, parm);
+            TREE_VALUE (err_parm_list) = error_mark_node;
+            return chainon (list, err_parm_list);
+          }
+      }
 
       /* A template parameter is not modifiable.  */
       TREE_CONSTANT (parm) = 1;
       TREE_INVARIANT (parm) = 1;
       TREE_READONLY (parm) = 1;
-      if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
-       TREE_TYPE (parm) = void_type_node;
       decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
       TREE_CONSTANT (decl) = 1;
       TREE_INVARIANT (decl) = 1;
@@ -2483,11 +2540,15 @@ current_template_args (void)
            {
              t = TREE_VALUE (t);
 
-             if (TREE_CODE (t) == TYPE_DECL
-                 || TREE_CODE (t) == TEMPLATE_DECL)
-               t = TREE_TYPE (t);
-             else
-               t = DECL_INITIAL (t);
+             if (t != error_mark_node)
+               {
+                 if (TREE_CODE (t) == TYPE_DECL
+                     || TREE_CODE (t) == TEMPLATE_DECL)
+                   t = TREE_TYPE (t);
+                 else
+                   t = DECL_INITIAL (t);
+               }
+
              TREE_VEC_ELT (a, i) = t;
            }
        }
@@ -2819,6 +2880,10 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
       for (i = 0; i < ntparms; ++i)
        {
          tree parm = TREE_VEC_ELT (inner_parms, i);
+
+          if (parm == error_mark_node)
+            continue;
+
          if (TREE_PURPOSE (parm))
            seen_def_arg_p = 1;
          else if (seen_def_arg_p)
@@ -2883,18 +2948,23 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
 
       ntparms = TREE_VEC_LENGTH (inner_parms);
       for (i = 0; i < ntparms; ++i)
-       if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
-         {
-           if (msg)
-             {
-               error (msg, decl);
-               msg = 0;
-             }
+        {
+          if (TREE_VEC_ELT (inner_parms, i) == error_mark_node)
+            continue;
 
-           /* Clear out the default argument so that we are not
-              confused later.  */
-           TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
-         }
+         if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
+           {
+             if (msg)
+               {
+                 error (msg, decl);
+                 msg = 0;
+               }
+
+             /* Clear out the default argument so that we are not
+                confused later.  */
+             TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
+           }
+        }
 
       /* At this point, if we're still interested in issuing messages,
         they must apply to classes surrounding the object declared.  */
@@ -2974,7 +3044,13 @@ push_template_decl_real (tree decl, bool is_friend)
     DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
 
   /* See if this is a primary template.  */
-  primary = template_parm_scope_p ();
+  if (is_friend && ctx)
+    /* A friend template that specifies a class context, i.e.
+         template <typename T> friend void A<T>::f();
+       is not primary.  */
+    primary = 0;
+  else
+    primary = template_parm_scope_p ();
 
   if (primary)
     {
@@ -3006,7 +3082,7 @@ push_template_decl_real (tree decl, bool is_friend)
                 template. ... Template allocation functions shall
                 have two or more parameters.  */
              error ("invalid template declaration of %qD", decl);
-             return decl;
+             return error_mark_node;
            }
        }
       else if (DECL_IMPLICIT_TYPEDEF_P (decl)
@@ -3280,16 +3356,26 @@ redeclare_class_template (tree type, tree parms)
 
   for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i)
     {
-      tree tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i));
-      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
-      tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
-      tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
+      tree tmpl_parm;
+      tree parm;
+      tree tmpl_default;
+      tree parm_default;
+
+      if (TREE_VEC_ELT (tmpl_parms, i) == error_mark_node
+          || TREE_VEC_ELT (parms, i) == error_mark_node)
+        continue;
+
+      tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i));
+      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+      tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
+      parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
 
       /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
         TEMPLATE_DECL.  */
-      if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
-         || (TREE_CODE (tmpl_parm) != TYPE_DECL
-             && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))
+      if (tmpl_parm != error_mark_node
+          && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+          || (TREE_CODE (tmpl_parm) != TYPE_DECL
+              && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))))
        {
          error ("template parameter %q+#D", tmpl_parm);
          error ("redeclared here as %q#D", parm);
@@ -3343,7 +3429,8 @@ fold_non_dependent_expr (tree expr)
                                    /*args=*/NULL_TREE,
                                    tf_error,
                                    /*in_decl=*/NULL_TREE,
-                                   /*function_p=*/false);
+                                   /*function_p=*/false,
+                                   /*integral_constant_expression_p=*/true);
       processing_template_decl = saved_processing_template_decl;
     }
   return expr;
@@ -3390,7 +3477,9 @@ convert_nontype_argument_function (tree type, tree expr)
   fn_no_ptr = fn;
   if (TREE_CODE (fn_no_ptr) == ADDR_EXPR)
     fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
-
+  if (TREE_CODE (fn_no_ptr) == BASELINK)
+    fn_no_ptr = BASELINK_FUNCTIONS (fn_no_ptr);
   /* [temp.arg.nontype]/1
 
      A template-argument for a non-type, non-template template-parameter
@@ -3454,6 +3543,8 @@ convert_nontype_argument (tree type, tree expr)
      instantiated -- but here we need the resolved form so that we can
      convert the argument.  */
   expr = fold_non_dependent_expr (expr);
+  if (error_operand_p (expr))
+    return error_mark_node;
   expr_type = TREE_TYPE (expr);
 
   /* HACK: Due to double coercion, we can get a
@@ -3565,9 +3656,9 @@ convert_nontype_argument (tree type, tree expr)
 
       if (!constant_address_p)
        {
-           error ("%qE is not a valid template argument for type %qT "
-                 "because it is not a constant pointer", expr, type);
-           return NULL_TREE;
+         error ("%qE is not a valid template argument for type %qT "
+                "because it is not a constant pointer", expr, type);
+         return NULL_TREE;
        }
     }
   /* [temp.arg.nontype]/5, bullet 3
@@ -3593,7 +3684,7 @@ convert_nontype_argument (tree type, tree expr)
       if (!real_lvalue_p (expr))
        {
          error ("%qE is not a valid template argument for type %qT "
-                "because it is not a lvalue", expr, type);
+                "because it is not an lvalue", expr, type);
          return NULL_TREE;
        }
 
@@ -3743,6 +3834,10 @@ coerce_template_template_parms (tree parm_parms,
 
   for (i = 0; i < nparms; ++i)
     {
+      if (TREE_VEC_ELT (parm_parms, i) == error_mark_node
+          || TREE_VEC_ELT (arg_parms, i) == error_mark_node)
+        continue;
+
       parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
       arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
 
@@ -3810,11 +3905,8 @@ convert_template_argument (tree parm,
                           tree in_decl)
 {
   tree val;
-  tree inner_args;
   int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
 
-  inner_args = INNERMOST_TEMPLATE_ARGS (args);
-
   if (TREE_CODE (arg) == TREE_LIST
       && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF)
     {
@@ -3906,7 +3998,7 @@ convert_template_argument (tree parm,
 
              if (coerce_template_template_parms (parmparm, argparm,
                                                  complain, in_decl,
-                                                 inner_args))
+                                                 args))
                {
                  val = arg;
 
@@ -3935,7 +4027,7 @@ convert_template_argument (tree parm,
        val = arg;
       /* We only form one instance of each template specialization.
         Therefore, if we use a non-canonical variant (i.e., a
-        typedef), any future messages referring to the type will use 
+        typedef), any future messages referring to the type will use
         the typedef, which is confusing if those future uses do not
         themselves also use the typedef.  */
       if (TYPE_P (val))
@@ -4005,7 +4097,8 @@ coerce_template_parms (tree parms,
       || (nargs < nparms
          && require_all_args
          && (!use_default_args
-             || !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)))))
+             || (TREE_VEC_ELT (parms, nargs) != error_mark_node
+                  && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
     {
       if (complain & tf_error)
        {
@@ -4028,6 +4121,12 @@ coerce_template_parms (tree parms,
 
       /* Get the Ith template parameter.  */
       parm = TREE_VEC_ELT (parms, i);
+      if (parm == error_mark_node)
+      {
+        TREE_VEC_ELT (new_inner_args, i) = error_mark_node;
+        continue;
+      }
 
       /* Calculate the Ith argument.  */
       if (i < nargs)
@@ -4128,8 +4227,14 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
   gcc_assert (nparms == TREE_VEC_LENGTH (arglist));
   for (i = 0; i < nparms; i++)
     {
-      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
-      tree arg = TREE_VEC_ELT (arglist, i);
+      tree parm;
+      tree arg;
+
+      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+      arg = TREE_VEC_ELT (arglist, i);
+
+      if (parm == error_mark_node)
+       continue;
 
       if (i)
        ccat (',');
@@ -4437,7 +4542,7 @@ lookup_template_class (tree d1,
        arglist = add_to_template_args (current_template_args (), arglist);
 
       arglist2 = coerce_template_parms (parmlist, arglist, template,
-                                       complain, 
+                                       complain,
                                        /*require_all_args=*/true,
                                        /*use_default_args=*/true);
       if (arglist2 == error_mark_node
@@ -4508,7 +4613,7 @@ lookup_template_class (tree d1,
            {
              tree a = coerce_template_parms (TREE_VALUE (t),
                                              arglist, template,
-                                             complain, 
+                                             complain,
                                              /*require_all_args=*/true,
                                              /*use_default_args=*/true);
 
@@ -4539,7 +4644,7 @@ lookup_template_class (tree d1,
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
                                   INNERMOST_TEMPLATE_ARGS (arglist),
                                   template,
-                                  complain, 
+                                  complain,
                                   /*require_all_args=*/true,
                                   /*use_default_args=*/true);
 
@@ -4758,6 +4863,10 @@ lookup_template_class (tree d1,
           code that generates debugging information will crash.  */
        DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1;
 
+      /* Possibly limit visibility based on template args.  */
+      TREE_PUBLIC (type_decl) = 1;
+      determine_visibility (type_decl);
+
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
     }
   timevar_pop (TV_NAME_LOOKUP);
@@ -5148,7 +5257,8 @@ tsubst_friend_function (tree decl, tree args)
         current cless with same name.  */
       push_nested_namespace (ns);
       fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
-                        tf_warning_or_error, NULL_TREE);
+                        tf_warning_or_error, NULL_TREE,
+                        /*integral_constant_expression_p=*/false);
       pop_nested_namespace (ns);
       arglist = tsubst (DECL_TI_ARGS (decl), args,
                        tf_warning_or_error, NULL_TREE);
@@ -5158,7 +5268,8 @@ tsubst_friend_function (tree decl, tree args)
       tmpl = determine_specialization (template_id, new_friend,
                                       &new_args,
                                       /*need_member_template=*/0,
-                                      TREE_VEC_LENGTH (args));
+                                      TREE_VEC_LENGTH (args),
+                                      tsk_none);
       return instantiate_template (tmpl, new_args, tf_error);
     }
 
@@ -5222,6 +5333,10 @@ tsubst_friend_function (tree decl, tree args)
       else
        new_friend_result_template_info = NULL_TREE;
 
+      /* Make the init_value nonzero so pushdecl knows this is a defn.  */
+      if (new_friend_is_defn)
+       DECL_INITIAL (new_friend) = error_mark_node;
+
       /* Inside pushdecl_namespace_level, we will push into the
         current namespace. However, the friend function should go
         into the namespace of the template.  */
@@ -5385,8 +5500,21 @@ tsubst_friend_class (tree friend_tmpl, tree args)
        push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
     }
 
-  /* First, we look for a class template.  */
-  tmpl = lookup_name (DECL_NAME (friend_tmpl));
+  /* Look for a class template declaration.  We look for hidden names
+     because two friend declarations of the same template are the
+     same.  For example, in:
+
+       struct A { 
+         template <typename> friend class F;
+       };
+       template <typename> struct B { 
+         template <typename> friend class F;
+       };
+
+     both F templates are the same.  */
+  tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0,
+                          /*block_p=*/true, 0, 
+                          LOOKUP_COMPLAIN | LOOKUP_HIDDEN);
 
   /* But, if we don't find one, it might be because we're in a
      situation like this:
@@ -5430,6 +5558,8 @@ tsubst_friend_class (tree friend_tmpl, tree args)
         case, the instantiation of the template class will cause the
         injection of this template into the global scope.  */
       tmpl = tsubst (friend_tmpl, args, tf_warning_or_error, NULL_TREE);
+      if (tmpl == error_mark_node)
+       return error_mark_node;
 
       /* The new TMPL is not an instantiation of anything, so we
         forget its origins.  We don't reset CLASSTYPE_TI_TEMPLATE for
@@ -5509,12 +5639,12 @@ instantiate_class_template (tree type)
         specialization.  We replace the innermost set of ARGS with
         the arguments appropriate for substitution.  For example,
         given:
-       
-           template <class T> struct S {};
+
+          template <class T> struct S {};
           template <class T> struct S<T*> {};
 
         and supposing that we are instantiating S<int*>, ARGS will
-         presently be {int*} -- but we need {int}.  */
+        presently be {int*} -- but we need {int}.  */
       pattern = TREE_TYPE (t);
       args = TREE_PURPOSE (t);
     }
@@ -5702,7 +5832,6 @@ instantiate_class_template (tree type)
              if (TREE_CODE (t) == TEMPLATE_DECL)
                --processing_template_decl;
              set_current_access_from_decl (r);
-             grok_special_member_properties (r);
              finish_member_declaration (r);
            }
          else
@@ -5733,15 +5862,15 @@ instantiate_class_template (tree type)
                           not occur unless the static data member is
                           itself used in a way that requires the
                           definition of the static data member to
-                          exist.  
+                          exist.
 
                         Therefore, we do not substitute into the
-                        initialized for the static data member here.  */
-                     finish_static_data_member_decl 
-                       (r, 
-                        /*init=*/NULL_TREE, 
+                        initialized for the static data member here.  */
+                     finish_static_data_member_decl
+                       (r,
+                        /*init=*/NULL_TREE,
                         /*init_const_expr_p=*/false,
-                        /*asmspec_tree=*/NULL_TREE, 
+                        /*asmspec_tree=*/NULL_TREE,
                         /*flags=*/0);
                      if (DECL_INITIALIZED_IN_CLASS_P (r))
                        check_static_variable_definition (r, TREE_TYPE (r));
@@ -5943,7 +6072,8 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     r = tsubst (t, args, complain, in_decl);
   else
     {
-      r = tsubst_expr (t, args, complain, in_decl);
+      r = tsubst_expr (t, args, complain, in_decl,
+                      /*integral_constant_expression_p=*/true);
       r = fold_non_dependent_expr (r);
     }
   return r;
@@ -6016,9 +6146,20 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
 
       for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i)
        {
-         tree tuple = TREE_VEC_ELT (TREE_VALUE (parms), i);
-         tree default_value = TREE_PURPOSE (tuple);
-         tree parm_decl = TREE_VALUE (tuple);
+          tree tuple;
+          tree default_value;
+          tree parm_decl;
+
+          if (parms == error_mark_node)
+            continue;
+
+          tuple = TREE_VEC_ELT (TREE_VALUE (parms), i);
+
+          if (tuple == error_mark_node)
+            continue;
+
+          default_value = TREE_PURPOSE (tuple);
+          parm_decl = TREE_VALUE (tuple);
 
          parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
          if (TREE_CODE (parm_decl) == PARM_DECL
@@ -6104,7 +6245,7 @@ tsubst_aggr_type (tree t,
                                         entering_scope, complain);
              r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
            }
-         
+
          skip_evaluation = saved_skip_evaluation;
 
          return r;
@@ -6150,8 +6291,16 @@ tsubst_default_argument (tree fn, tree type, tree arg)
     }
 
   push_deferring_access_checks(dk_no_deferred);
+  /* The default argument expression may cause implicitly defined
+     member functions to be synthesized, which will result in garbage
+     collection.  We must treat this situation as if we were within
+     the body of function so as to avoid collecting live data on the
+     stack.  */
+  ++function_depth;
   arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
-                    tf_warning_or_error, NULL_TREE);
+                    tf_warning_or_error, NULL_TREE,
+                    /*integral_constant_expression_p=*/false);
+  --function_depth;
   pop_deferring_access_checks();
 
   /* Restore the "this" pointer.  */
@@ -6286,7 +6435,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            tree new_type;
            ++processing_template_decl;
            new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-           --processing_template_decl; 
+           --processing_template_decl;
            if (new_type == error_mark_node)
              return error_mark_node;
 
@@ -6309,7 +6458,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_TI_TEMPLATE (new_decl) = r;
            TREE_TYPE (r) = TREE_TYPE (new_decl);
            DECL_TI_ARGS (r) = DECL_TI_ARGS (new_decl);
-           DECL_CONTEXT (r) = DECL_CONTEXT (new_decl); 
+           DECL_CONTEXT (r) = DECL_CONTEXT (new_decl);
          }
 
        SET_DECL_IMPLICIT_INSTANTIATION (r);
@@ -6548,13 +6697,24 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            if (PRIMARY_TEMPLATE_P (gen_tmpl))
              clone_function_decl (r, /*update_method_vec_p=*/0);
          }
-       else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
-         grok_op_properties (r, (complain & tf_error) != 0);
+       else if (IDENTIFIER_OPNAME_P (DECL_NAME (r))
+                && !grok_op_properties (r, (complain & tf_error) != 0))
+         return error_mark_node;
 
        if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
          SET_DECL_FRIEND_CONTEXT (r,
                                   tsubst (DECL_FRIEND_CONTEXT (t),
                                            args, complain, in_decl));
+
+       /* Possibly limit visibility based on template args.  */
+       DECL_VISIBILITY (r) = VISIBILITY_DEFAULT;
+       if (DECL_VISIBILITY_SPECIFIED (t))
+         {
+           DECL_VISIBILITY_SPECIFIED (r) = 0;
+           DECL_ATTRIBUTES (r)
+             = remove_attribute ("visibility", DECL_ATTRIBUTES (r));
+         }
+       determine_visibility (r);
       }
       break;
 
@@ -6601,10 +6761,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        TREE_TYPE (r) = type;
        cp_apply_type_quals_to_decl (cp_type_quals (type), r);
 
+       /* DECL_INITIAL gives the number of bits in a bit-field.  */
+       DECL_INITIAL (r)
+         = tsubst_expr (DECL_INITIAL (t), args,
+                        complain, in_decl,
+                        /*integral_constant_expression_p=*/true);
        /* We don't have to set DECL_CONTEXT here; it is set by
           finish_member_declaration.  */
-       DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args,
-                                       complain, in_decl);
        TREE_CHAIN (r) = NULL_TREE;
        if (VOID_TYPE_P (type))
          error ("instantiation of %q+D as type %qT", r, type);
@@ -6637,7 +6800,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        tree tmpl = NULL_TREE;
        tree ctx;
        tree type = NULL_TREE;
-       int local_p;
+       bool local_p;
 
        if (TREE_CODE (t) == TYPE_DECL)
          {
@@ -6655,40 +6818,64 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
              }
          }
 
-       /* Assume this is a non-local variable.  */
-       local_p = 0;
+       /* Check to see if we already have the specialization we
+          need.  */
+       spec = NULL_TREE;
+       if (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t))
+         {
+           /* T is a static data member or namespace-scope entity.
+              We have to substitute into namespace-scope variables
+              (even though such entities are never templates) because
+              of cases like:
+              
+                template <class T> void f() { extern T t; }
+
+              where the entity referenced is not known until
+              instantiation time.  */
+           local_p = false;
+           ctx = DECL_CONTEXT (t);
+           if (DECL_CLASS_SCOPE_P (t))
+             {
+               ctx = tsubst_aggr_type (ctx, args,
+                                       complain,
+                                       in_decl, /*entering_scope=*/1);
+               /* If CTX is unchanged, then T is in fact the
+                  specialization we want.  That situation occurs when
+                  referencing a static data member within in its own
+                  class.  We can use pointer equality, rather than
+                  same_type_p, because DECL_CONTEXT is always
+                  canonical.  */
+               if (ctx == DECL_CONTEXT (t))
+                 spec = t;
+             }
 
-       if (TYPE_P (CP_DECL_CONTEXT (t)))
-         ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
-                                 complain,
-                                 in_decl, /*entering_scope=*/1);
-       else if (DECL_NAMESPACE_SCOPE_P (t))
-         ctx = DECL_CONTEXT (t);
+           if (!spec)
+             {
+               tmpl = DECL_TI_TEMPLATE (t);
+               gen_tmpl = most_general_template (tmpl);
+               argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
+               spec = (retrieve_specialization 
+                       (gen_tmpl, argvec,
+                        /*class_specializations_p=*/false));
+             }
+         }
        else
          {
+           /* A local variable.  */
+           local_p = true;
            /* Subsequent calls to pushdecl will fill this in.  */
            ctx = NULL_TREE;
-           local_p = 1;
-         }
-
-       /* Check to see if we already have this specialization.  */
-       if (!local_p)
-         {
-           tmpl = DECL_TI_TEMPLATE (t);
-           gen_tmpl = most_general_template (tmpl);
-           argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
-           spec = retrieve_specialization (gen_tmpl, argvec,
-                                           /*class_specializations_p=*/false);
+           spec = retrieve_local_specialization (t);
          }
-       else
-         spec = retrieve_local_specialization (t);
-
+       /* If we already have the specialization we need, there is
+          nothing more to do.  */ 
        if (spec)
          {
            r = spec;
            break;
          }
 
+       /* Create a new node for the specialization we need.  */
        r = copy_decl (t);
        if (TREE_CODE (r) == VAR_DECL)
          {
@@ -6708,8 +6895,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            if (DECL_HAS_VALUE_EXPR_P (t))
              {
                tree ve = DECL_VALUE_EXPR (t);
-               ve = tsubst_expr (ve, args, complain, in_decl);
-               SET_DECL_VALUE_EXPR (r, ve);
+               ve = tsubst_expr (ve, args, complain, in_decl,
+                                 /*constant_expression_p=*/false);
+               SET_DECL_VALUE_EXPR (r, ve);
              }
          }
        else if (DECL_SELF_REFERENCE_P (t))
@@ -6727,6 +6915,18 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL))
          SET_DECL_RTL (r, NULL_RTX);
        DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0;
+       if (TREE_CODE (r) == VAR_DECL)
+         {
+           /* Possibly limit visibility based on template args.  */
+           DECL_VISIBILITY (r) = VISIBILITY_DEFAULT;
+           if (DECL_VISIBILITY_SPECIFIED (t))
+             {
+               DECL_VISIBILITY_SPECIFIED (r) = 0;
+               DECL_ATTRIBUTES (r)
+                 = remove_attribute ("visibility", DECL_ATTRIBUTES (r));
+             }
+           determine_visibility (r);
+         }
 
        if (!local_p)
          {
@@ -7016,11 +7216,20 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
 
-       /* The array dimension behaves like a non-type template arg,
-          in that we want to fold it as much as possible.  */
-       max = tsubst_template_arg (omax, args, complain, in_decl);
+       max = tsubst_expr (omax, args, complain, in_decl,
+                          /*integral_constant_expression_p=*/false);
+       max = fold_non_dependent_expr (max);
        max = fold_decl_constant_value (max);
 
+       if (TREE_CODE (max) != INTEGER_CST 
+           && TREE_CODE (max) != TEMPLATE_PARM_INDEX
+           && !at_function_scope_p ())
+         {
+           if (complain & tf_error)
+             error ("array bound is not an integer constant");
+           return error_mark_node;
+         }
+
        /* [temp.deduct]
 
           Type deduction may fail for any of the following
@@ -7033,7 +7242,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
             indicated by the state of complain), so that
             another substitution can be found.  */
          return error_mark_node;
-
        else if (TREE_CODE (max) == INTEGER_CST
                 && INT_CST_LT (max, integer_zero_node))
          {
@@ -7082,10 +7290,20 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          {
            if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
              {
+               int quals;
                gcc_assert (TYPE_P (arg));
+
+               /* cv-quals from the template are discarded when
+                  substituting in a function or reference type.  */
+               if (TREE_CODE (arg) == FUNCTION_TYPE
+                   || TREE_CODE (arg) == METHOD_TYPE
+                   || TREE_CODE (arg) == REFERENCE_TYPE)
+                 quals = cp_type_quals (arg);
+               else
+                 quals = cp_type_quals (arg) | cp_type_quals (t);
+                 
                return cp_build_qualified_type_real
-                 (arg, cp_type_quals (arg) | cp_type_quals (t),
-                  complain | tf_ignore_bad_quals);
+                 (arg, quals, complain | tf_ignore_bad_quals);
              }
            else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
              {
@@ -7492,7 +7710,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case ARRAY_REF:
       {
        tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
-       tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl);
+       tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl,
+                              /*integral_constant_expression_p=*/false);
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
@@ -7514,8 +7733,10 @@ 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));
+       type = finish_typeof (tsubst_expr 
+                             (TYPEOF_TYPE_EXPR (t), args,
+                              complain, in_decl,
+                              /*integral_constant_expression_p=*/false));
        return cp_build_qualified_type_real (type,
                                             cp_type_quals (t)
                                             | cp_type_quals (type),
@@ -7540,6 +7761,7 @@ tsubst_baselink (tree baselink, tree object_type,
     tree name;
     tree qualifying_scope;
     tree fns;
+    tree optype;
     tree template_args = 0;
     bool template_id_p = false;
 
@@ -7553,6 +7775,7 @@ tsubst_baselink (tree baselink, tree object_type,
        ambiguous now.  Therefore, we perform the lookup again.  */
     qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink));
     fns = BASELINK_FUNCTIONS (baselink);
+    optype = BASELINK_OPTYPE (baselink);
     if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
       {
        template_id_p = true;
@@ -7580,6 +7803,9 @@ tsubst_baselink (tree baselink, tree object_type,
        = build_nt (TEMPLATE_ID_EXPR,
                    BASELINK_FUNCTIONS (baselink),
                    template_args);
+    /* Update the conversion operator type.  */
+    BASELINK_OPTYPE (baselink) 
+      = tsubst (optype, args, complain, in_decl);
 
     if (!object_type)
       object_type = current_class_type;
@@ -7638,8 +7864,8 @@ tsubst_qualified_id (tree qualified_id, tree args,
     expr = name;
 
   if (dependent_type_p (scope))
-    return build_qualified_name (/*type=*/NULL_TREE, 
-                                scope, expr, 
+    return build_qualified_name (/*type=*/NULL_TREE,
+                                scope, expr,
                                 QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
 
   if (!BASELINK_P (name) && !DECL_P (expr))
@@ -7690,13 +7916,17 @@ tsubst_qualified_id (tree qualified_id, tree args,
     {
       expr = (adjust_result_of_qualified_name_lookup
              (expr, scope, current_class_type));
-      expr = (finish_qualified_id_expr 
+      expr = (finish_qualified_id_expr
              (scope, expr, done, address_p,
               QUALIFIED_NAME_IS_TEMPLATE (qualified_id),
               /*template_arg_p=*/false));
     }
 
-  if (TREE_CODE (expr) != SCOPE_REF)
+  /* Expressions do not generally have reference type.  */
+  if (TREE_CODE (expr) != SCOPE_REF
+      /* However, if we're about to form a pointer-to-member, we just
+        want the referenced member referenced.  */
+      && TREE_CODE (expr) != OFFSET_REF)
     expr = convert_from_reference (expr);
 
   return expr;
@@ -7881,7 +8111,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                complain, in_decl);
            name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
            name = build_qualified_name (/*type=*/NULL_TREE,
-                                        base, name, 
+                                        base, name,
                                         /*template_p=*/false);
          }
        else if (TREE_CODE (name) == BASELINK)
@@ -8105,7 +8335,8 @@ tsubst_omp_clauses (tree clauses, tree args, tsubst_flags_t complain,
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_SCHEDULE:
          OMP_CLAUSE_OPERAND (nc, 0)
-           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, in_decl);
+           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, 
+                          in_decl, /*integral_constant_expression_p=*/false);
          break;
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_ORDERED:
@@ -8134,7 +8365,8 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
 
   if (TREE_CODE (t) != TREE_LIST)
     return tsubst_copy_and_build (t, args, complain, in_decl,
-                                 /*function_p=*/false);
+                                 /*function_p=*/false,
+                                 /*integral_constant_expression_p=*/false);
 
   if (t == void_list_node)
     return t;
@@ -8156,8 +8388,13 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
    processing.  */
 
 static tree
-tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
+            bool integral_constant_expression_p)
 {
+#define RECUR(NODE)                            \
+  tsubst_expr ((NODE), args, complain, in_decl,        \
+              integral_constant_expression_p)
+
   tree stmt, tmp;
 
   if (t == NULL_TREE || t == error_mark_node)
@@ -8174,7 +8411,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree_stmt_iterator i;
        for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
-         tsubst_expr (tsi_stmt (i), args, complain, in_decl);
+         RECUR (tsi_stmt (i));
        break;
       }
 
@@ -8184,12 +8421,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case RETURN_EXPR:
-      finish_return_stmt (tsubst_expr (TREE_OPERAND (t, 0),
-                                      args, complain, in_decl));
+      finish_return_stmt (RECUR (TREE_OPERAND (t, 0)));
       break;
 
     case EXPR_STMT:
-      tmp = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl);
+      tmp = RECUR (EXPR_STMT_EXPR (t));
       if (EXPR_STMT_STMT_EXPR_RESULT (t))
        finish_stmt_expr_expr (tmp, cur_stmt_expr);
       else
@@ -8197,8 +8433,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case USING_STMT:
-      do_using_directive (tsubst_expr (USING_STMT_NAMESPACE (t),
-                                      args, complain, in_decl));
+      do_using_directive (RECUR (USING_STMT_NAMESPACE (t)));
       break;
 
     case DECL_EXPR:
@@ -8215,7 +8450,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            tree name = DECL_NAME (decl);
            tree decl;
 
-           scope = tsubst_expr (scope, args, complain, in_decl);
+           scope = RECUR (scope);
            decl = lookup_qualified_name (scope, name,
                                          /*is_type_p=*/false,
                                          /*complain=*/false);
@@ -8230,8 +8465,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            decl = tsubst (decl, args, complain, in_decl);
            if (decl != error_mark_node)
              {
-               if (init)
-                 DECL_INITIAL (decl) = error_mark_node;
                /* By marking the declaration as instantiated, we avoid
                   trying to instantiate it.  Since instantiate_decl can't
                   handle local variables, and since we've already done
@@ -8256,7 +8489,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                        init = cp_fname_init (name, &TREE_TYPE (decl));
                      }
                    else
-                     init = tsubst_expr (init, args, complain, in_decl);
+                     init = RECUR (init);
                    finish_decl (decl, init, NULL_TREE);
                  }
              }
@@ -8269,43 +8502,43 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case FOR_STMT:
       stmt = begin_for_stmt ();
-      tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl);
+                         RECUR (FOR_INIT_STMT (t));
       finish_for_init_stmt (stmt);
-      tmp = tsubst_expr (FOR_COND (t), args, complain, in_decl);
+      tmp = RECUR (FOR_COND (t));
       finish_for_cond (tmp, stmt);
-      tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl);
+      tmp = RECUR (FOR_EXPR (t));
       finish_for_expr (tmp, stmt);
-      tsubst_expr (FOR_BODY (t), args, complain, in_decl);
+      RECUR (FOR_BODY (t));
       finish_for_stmt (stmt);
       break;
 
     case WHILE_STMT:
       stmt = begin_while_stmt ();
-      tmp = tsubst_expr (WHILE_COND (t), args, complain, in_decl);
+      tmp = RECUR (WHILE_COND (t));
       finish_while_stmt_cond (tmp, stmt);
-      tsubst_expr (WHILE_BODY (t), args, complain, in_decl);
+      RECUR (WHILE_BODY (t));
       finish_while_stmt (stmt);
       break;
 
     case DO_STMT:
       stmt = begin_do_stmt ();
-      tsubst_expr (DO_BODY (t), args, complain, in_decl);
+      RECUR (DO_BODY (t));
       finish_do_body (stmt);
-      tmp = tsubst_expr (DO_COND (t), args, complain, in_decl);
+      tmp = RECUR (DO_COND (t));
       finish_do_stmt (tmp, stmt);
       break;
 
     case IF_STMT:
       stmt = begin_if_stmt ();
-      tmp = tsubst_expr (IF_COND (t), args, complain, in_decl);
+      tmp = RECUR (IF_COND (t));
       finish_if_stmt_cond (tmp, stmt);
-      tsubst_expr (THEN_CLAUSE (t), args, complain, in_decl);
+      RECUR (THEN_CLAUSE (t));
       finish_then_clause (stmt);
 
       if (ELSE_CLAUSE (t))
        {
          begin_else_clause (stmt);
-         tsubst_expr (ELSE_CLAUSE (t), args, complain, in_decl);
+         RECUR (ELSE_CLAUSE (t));
          finish_else_clause (stmt);
        }
 
@@ -8319,7 +8552,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        stmt = begin_compound_stmt (BIND_EXPR_TRY_BLOCK (t)
                                    ? BCS_TRY_BLOCK : 0);
 
-      tsubst_expr (BIND_EXPR_BODY (t), args, complain, in_decl);
+      RECUR (BIND_EXPR_BODY (t));
 
       if (BIND_EXPR_BODY_BLOCK (t))
        finish_function_body (stmt);
@@ -8337,16 +8570,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case SWITCH_STMT:
       stmt = begin_switch_stmt ();
-      tmp = tsubst_expr (SWITCH_STMT_COND (t), args, complain, in_decl);
+      tmp = RECUR (SWITCH_STMT_COND (t));
       finish_switch_cond (tmp, stmt);
-      tsubst_expr (SWITCH_STMT_BODY (t), args, complain, in_decl);
+      RECUR (SWITCH_STMT_BODY (t));
       finish_switch_stmt (stmt);
       break;
 
     case CASE_LABEL_EXPR:
-      finish_case_label (tsubst_expr (CASE_LOW (t), args, complain, in_decl),
-                        tsubst_expr (CASE_HIGH (t), args, complain,
-                                     in_decl));
+      finish_case_label (RECUR (CASE_LOW (t)),
+                        RECUR (CASE_HIGH (t)));
       break;
 
     case LABEL_EXPR:
@@ -8359,7 +8591,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        /* Computed goto's must be tsubst'd into.  On the other hand,
           non-computed gotos must not be; the identifier in question
           will have no binding.  */
-       tmp = tsubst_expr (tmp, args, complain, in_decl);
+       tmp = RECUR (tmp);
       else
        tmp = DECL_NAME (tmp);
       finish_goto_stmt (tmp);
@@ -8368,7 +8600,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case ASM_EXPR:
       tmp = finish_asm_stmt
        (ASM_VOLATILE_P (t),
-        tsubst_expr (ASM_STRING (t), args, complain, in_decl),
+        RECUR (ASM_STRING (t)),
         tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl),
         tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl),
         tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl));
@@ -8384,29 +8616,29 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       if (CLEANUP_P (t))
        {
          stmt = begin_try_block ();
-         tsubst_expr (TRY_STMTS (t), args, complain, in_decl);
+         RECUR (TRY_STMTS (t));
          finish_cleanup_try_block (stmt);
-         finish_cleanup (tsubst_expr (TRY_HANDLERS (t), args,
-                                      complain, in_decl),
-                         stmt);
+         finish_cleanup (RECUR (TRY_HANDLERS (t)), stmt);
        }
       else
        {
+         tree compound_stmt = NULL_TREE;
+
          if (FN_TRY_BLOCK_P (t))
-           stmt = begin_function_try_block ();
+           stmt = begin_function_try_block (&compound_stmt);
          else
            stmt = begin_try_block ();
 
-         tsubst_expr (TRY_STMTS (t), args, complain, in_decl);
+         RECUR (TRY_STMTS (t));
 
          if (FN_TRY_BLOCK_P (t))
            finish_function_try_block (stmt);
          else
            finish_try_block (stmt);
 
-         tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
+         RECUR (TRY_HANDLERS (t));
          if (FN_TRY_BLOCK_P (t))
-           finish_function_handler_sequence (stmt);
+           finish_function_handler_sequence (stmt, compound_stmt);
          else
            finish_handler_sequence (stmt);
        }
@@ -8414,22 +8646,20 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case HANDLER:
       {
-       tree decl;
+       tree decl = HANDLER_PARMS (t);
 
-       stmt = begin_handler ();
-       if (HANDLER_PARMS (t))
+       if (decl)
          {
-           decl = HANDLER_PARMS (t);
            decl = tsubst (decl, args, complain, in_decl);
            /* Prevent instantiate_decl from trying to instantiate
               this variable.  We've already done all that needs to be
               done.  */
-           DECL_TEMPLATE_INSTANTIATED (decl) = 1;
+           if (decl != error_mark_node)
+             DECL_TEMPLATE_INSTANTIATED (decl) = 1;
          }
-       else
-         decl = NULL_TREE;
+       stmt = begin_handler ();
        finish_handler_parms (decl, stmt);
-       tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
+       RECUR (HANDLER_BODY (t));
        finish_handler (stmt);
       }
       break;
@@ -8442,8 +8672,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t),
                                args, complain, in_decl);
       stmt = begin_omp_parallel ();
-      tsubst_expr (OMP_PARALLEL_BODY (t), args, complain, in_decl);
-      finish_omp_parallel (tmp, stmt);
+      RECUR (OMP_PARALLEL_BODY (t));
+      OMP_PARALLEL_COMBINED (finish_omp_parallel (tmp, stmt))
+       = OMP_PARALLEL_COMBINED (t);
       break;
 
     case OMP_FOR:
@@ -8454,19 +8685,19 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                      args, complain, in_decl);
        init = OMP_FOR_INIT (t);
        gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
-       decl = tsubst_expr (TREE_OPERAND (init, 0), args, complain, in_decl);
-       init = tsubst_expr (TREE_OPERAND (init, 1), args, complain, in_decl);
-       cond = tsubst_expr (OMP_FOR_COND (t), args, complain, in_decl);
-       incr = tsubst_expr (OMP_FOR_INCR (t), args, complain, in_decl);
+       decl = RECUR (TREE_OPERAND (init, 0));
+       init = RECUR (TREE_OPERAND (init, 1));
+       cond = RECUR (OMP_FOR_COND (t));
+       incr = RECUR (OMP_FOR_INCR (t));
 
        stmt = begin_omp_structured_block ();
 
        pre_body = push_stmt_list ();
-       tsubst_expr (OMP_FOR_PRE_BODY (t), args, complain, in_decl);
+       RECUR (OMP_FOR_PRE_BODY (t));
        pre_body = pop_stmt_list (pre_body);
 
        body = push_stmt_list ();
-       tsubst_expr (OMP_FOR_BODY (t), args, complain, in_decl);
+       RECUR (OMP_FOR_BODY (t));
        body = pop_stmt_list (body);
 
        t = finish_omp_for (EXPR_LOCATION (t), decl, init, cond, incr, body,
@@ -8482,7 +8713,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case OMP_SINGLE:
       tmp = tsubst_omp_clauses (OMP_CLAUSES (t), args, complain, in_decl);
       stmt = push_stmt_list ();
-      tsubst_expr (OMP_BODY (t), args, complain, in_decl);
+      RECUR (OMP_BODY (t));
       stmt = pop_stmt_list (stmt);
 
       t = copy_node (t);
@@ -8496,7 +8727,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case OMP_MASTER:
     case OMP_ORDERED:
       stmt = push_stmt_list ();
-      tsubst_expr (OMP_BODY (t), args, complain, in_decl);
+      RECUR (OMP_BODY (t));
       stmt = pop_stmt_list (stmt);
 
       t = copy_node (t);
@@ -8507,12 +8738,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case OMP_ATOMIC:
       {
        tree op0, op1;
-       op0 = tsubst_expr (TREE_OPERAND (t, 0), args, complain, in_decl);
-       op1 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl);
-       if (OMP_ATOMIC_DEPENDENT_P (t))
-         c_finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1);
-       else
-         add_stmt (build2 (OMP_ATOMIC, void_type_node, op0, op1));
+       op0 = RECUR (TREE_OPERAND (t, 0));
+       op1 = RECUR (TREE_OPERAND (t, 1));
+       finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1);
       }
       break;
 
@@ -8520,10 +8748,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
 
       return tsubst_copy_and_build (t, args, complain, in_decl,
-                                   /*function_p=*/false);
+                                   /*function_p=*/false,
+                                   integral_constant_expression_p);
     }
 
   return NULL_TREE;
+#undef RECUR
 }
 
 /* T is a postfix-expression that is not being used in a function
@@ -8539,7 +8769,8 @@ tsubst_non_call_postfix_expression (tree t, tree args,
                             /*done=*/false, /*address_p=*/false);
   else
     t = tsubst_copy_and_build (t, args, complain, in_decl,
-                              /*function_p=*/false);
+                              /*function_p=*/false,
+                              /*integral_constant_expression_p=*/false);
 
   return t;
 }
@@ -8552,10 +8783,13 @@ tsubst_copy_and_build (tree t,
                       tree args,
                       tsubst_flags_t complain,
                       tree in_decl,
-                      bool function_p)
+                      bool function_p,
+                      bool integral_constant_expression_p)
 {
-#define RECUR(NODE) \
-  tsubst_copy_and_build (NODE, args, complain, in_decl, /*function_p=*/false)
+#define RECUR(NODE)                                            \
+  tsubst_copy_and_build (NODE, args, complain, in_decl,        \
+                        /*function_p=*/false,                  \
+                        integral_constant_expression_p)
 
   tree op1;
 
@@ -8590,7 +8824,7 @@ tsubst_copy_and_build (tree t,
 
        decl = finish_id_expression (t, decl, NULL_TREE,
                                     &idk,
-                                    /*integral_constant_expression_p=*/false,
+                                    integral_constant_expression_p,
                                     /*allow_non_integral_constant_expression_p=*/false,
                                     &non_integral_constant_expression_p,
                                     /*template_p=*/false,
@@ -8627,7 +8861,7 @@ tsubst_copy_and_build (tree t,
          return build3 (COMPONENT_REF, TREE_TYPE (template),
                         object, template, NULL_TREE);
        else
-         return template;
+         return baselink_for_fns (template);
       }
 
     case INDIRECT_REF:
@@ -8653,29 +8887,41 @@ tsubst_copy_and_build (tree t,
         RECUR (TREE_OPERAND (t, 0)));
 
     case CAST_EXPR:
-      return build_functional_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
-
     case REINTERPRET_CAST_EXPR:
-      return build_reinterpret_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
-
     case CONST_CAST_EXPR:
-      return build_const_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
-
     case DYNAMIC_CAST_EXPR:
-      return build_dynamic_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
-
     case STATIC_CAST_EXPR:
-      return build_static_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
+      {
+       tree type;
+       tree op;
+
+       type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       if (integral_constant_expression_p
+           && !cast_valid_in_integral_constant_expression_p (type))
+         {
+           error ("a cast to a type other than an integral or "
+                  "enumeration type cannot appear in a constant-expression");
+           return error_mark_node; 
+         }
+
+       op = RECUR (TREE_OPERAND (t, 0));
+
+       switch (TREE_CODE (t))
+         {
+         case CAST_EXPR:
+           return build_functional_cast (type, op);
+         case REINTERPRET_CAST_EXPR:
+           return build_reinterpret_cast (type, op);
+         case CONST_CAST_EXPR:
+           return build_const_cast (type, op);
+         case DYNAMIC_CAST_EXPR:
+           return build_dynamic_cast (type, op);
+         case STATIC_CAST_EXPR:
+           return build_static_cast (type, op);
+         default:
+           gcc_unreachable ();
+         }
+      }
 
     case POSTDECREMENT_EXPR:
     case POSTINCREMENT_EXPR:
@@ -8766,7 +9012,9 @@ tsubst_copy_and_build (tree t,
       else
        {
          ++skip_evaluation;
-         op1 = RECUR (op1);
+         op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
+                                      /*function_p=*/false,
+                                      /*integral_constant_expression_p=*/false);
          --skip_evaluation;
        }
       if (TYPE_P (op1))
@@ -8848,10 +9096,12 @@ tsubst_copy_and_build (tree t,
              }
            else
              qualified_p = false;
-           
+
            function = tsubst_copy_and_build (function, args, complain,
                                              in_decl,
-                                             !qualified_p);
+                                             !qualified_p,
+                                             integral_constant_expression_p);
+
            if (BASELINK_P (function))
              qualified_p = true;
          }
@@ -9034,6 +9284,9 @@ tsubst_copy_and_build (tree t,
        tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
        bool process_index_p;
 
+       if (type == error_mark_node)
+         return error_mark_node;
+
        /* digest_init will do the wrong thing if we let it.  */
        if (type && TYPE_PTRMEMFUNC_P (type))
          return t;
@@ -9089,7 +9342,7 @@ tsubst_copy_and_build (tree t,
                                          in_decl));
 
     case OFFSETOF_EXPR:
-      return fold_offsetof (RECUR (TREE_OPERAND (t, 0)));
+      return finish_offsetof (RECUR (TREE_OPERAND (t, 0)));
 
     case STMT_EXPR:
       {
@@ -9097,7 +9350,8 @@ tsubst_copy_and_build (tree t,
        tree stmt_expr = begin_stmt_expr ();
 
        cur_stmt_expr = stmt_expr;
-       tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
+       tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl,
+                    integral_constant_expression_p);
        stmt_expr = finish_stmt_expr (stmt_expr, false);
        cur_stmt_expr = old_stmt_expr;
 
@@ -9109,7 +9363,10 @@ tsubst_copy_and_build (tree t,
       /* As in finish_id_expression, we resolve enumeration constants
         to their underlying values.  */
       if (TREE_CODE (t) == CONST_DECL)
-       return DECL_INITIAL (t);
+       {
+         used_types_insert (TREE_TYPE (t));
+         return DECL_INITIAL (t);
+       }
       return t;
 
     default:
@@ -9154,14 +9411,14 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
          if (nt)
            {
              /* DR 488 makes use of a type with no linkage cause
-                type deduction to fail.  */ 
+                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);
+                          tmpl, t);
                }
              result = true;
            }
@@ -9199,6 +9456,7 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
   tree fndecl;
   tree gen_tmpl;
   tree spec;
+  HOST_WIDE_INT saved_processing_template_decl;
 
   if (tmpl == error_mark_node)
     return error_mark_node;
@@ -9258,9 +9516,18 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
      deferring all checks until we have the FUNCTION_DECL.  */
   push_deferring_access_checks (dk_deferred);
 
-  /* Substitute template parameters.  */
+  /* Although PROCESSING_TEMPLATE_DECL may be true at this point
+     (because, for example, we have encountered a non-dependent
+     function call in the body of a template function and must now
+     determine which of several overloaded functions will be called),
+     within the instantiation itself we are not processing a
+     template.  */  
+  saved_processing_template_decl = processing_template_decl;
+  processing_template_decl = 0;
+  /* Substitute template parameters to obtain the specialization.  */
   fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
                   targ_ptr, complain, gen_tmpl);
+  processing_template_decl = saved_processing_template_decl;
   if (fndecl == error_mark_node)
     return error_mark_node;
 
@@ -9586,10 +9853,10 @@ type_unification_real (tree tparms,
          if (same_type_p (parm, type))
            continue;
          if (strict != DEDUCE_EXACT
-             && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg, 
+             && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg,
                                  flags))
            continue;
-         
+
          return 1;
        }
 
@@ -9639,7 +9906,12 @@ type_unification_real (tree tparms,
     for (i = 0; i < ntparms; i++)
       if (!TREE_VEC_ELT (targs, i))
        {
-         tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+         tree tparm;
+
+          if (TREE_VEC_ELT (tparms, i) == error_mark_node)
+            continue;
+
+          tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
 
          /* If this is an undeduced nontype parameter that depends on
             a type parameter, try another pass; its type may have been
@@ -10123,7 +10395,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          /* ARG must be constructed from a template class or a template
             template parameter.  */
          if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM
-             && (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg)))
+             && !CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (arg))
            return 1;
 
          {
@@ -10146,8 +10418,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
                            typename Block>
                  void operator+(float, View<Block> const&);
 
-                 template <typename Block, 
-                           unsigned int Dim = Block::dim>
+                 template <typename Block,
+                           unsigned int Dim = Block::dim>
                  struct Lvalue_proxy { operator float() const; };
 
                  void
@@ -10159,8 +10431,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
              Here, if Lvalue_proxy is permitted to bind to View, then
              the global operator+ will be used; if they are not, the
-             Lvalue_proxy will be converted to float.  */        
-           if (coerce_template_parms (argtmplvec, parmvec, 
+             Lvalue_proxy will be converted to float.  */
+           if (coerce_template_parms (argtmplvec, parmvec,
                                       TYPE_TI_TEMPLATE (parm),
                                       tf_none,
                                       /*require_all_args=*/true,
@@ -10237,6 +10509,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
     case TEMPLATE_PARM_INDEX:
       tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
+      if (tparm == error_mark_node)
+       return 1;
 
       if (TEMPLATE_PARM_LEVEL (parm)
          != template_decl_level (tparm))
@@ -10344,21 +10618,56 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
        {
          tree parm_max;
          tree arg_max;
-
-         parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm));
-         arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg));
+         bool parm_cst;
+         bool arg_cst;
 
          /* Our representation of array types uses "N - 1" as the
             TYPE_MAX_VALUE for an array with "N" elements, if "N" is
-            not an integer constant.  */
-         if (TREE_CODE (parm_max) == MINUS_EXPR)
+            not an integer constant.  We cannot unify arbitrarily
+            complex expressions, so we eliminate the MINUS_EXPRs
+            here.  */
+         parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm));
+         parm_cst = TREE_CODE (parm_max) == INTEGER_CST;
+         if (!parm_cst)
            {
-             arg_max = fold_build2 (PLUS_EXPR,
-                                    integer_type_node,
-                                    arg_max,
-                                    TREE_OPERAND (parm_max, 1));
+             gcc_assert (TREE_CODE (parm_max) == MINUS_EXPR);
              parm_max = TREE_OPERAND (parm_max, 0);
            }
+         arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg));
+         arg_cst = TREE_CODE (arg_max) == INTEGER_CST;
+         if (!arg_cst)
+           {
+             /* The ARG_MAX may not be a simple MINUS_EXPR, if we are
+                trying to unify the type of a variable with the type
+                of a template parameter.  For example:
+
+                   template <unsigned int N>
+                  void f (char (&) [N]);
+                  int g(); 
+                  void h(int i) {
+                     char a[g(i)];
+                    f(a); 
+                   }
+
+                Here, the type of the ARG will be "int [g(i)]", and
+                may be a SAVE_EXPR, etc.  */
+             if (TREE_CODE (arg_max) != MINUS_EXPR)
+               return 1;
+             arg_max = TREE_OPERAND (arg_max, 0);
+           }
+
+         /* If only one of the bounds used a MINUS_EXPR, compensate
+            by adding one to the other bound.  */
+         if (parm_cst && !arg_cst)
+           parm_max = fold_build2 (PLUS_EXPR,
+                                   integer_type_node,
+                                   parm_max,
+                                   integer_one_node);
+         else if (arg_cst && !parm_cst)
+           arg_max = fold_build2 (PLUS_EXPR,
+                                  integer_type_node,
+                                  arg_max,
+                                  integer_one_node);
 
          if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER))
            return 1;
@@ -10476,9 +10785,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
        return 1;
 
       /* CV qualifications for methods can never be deduced, they must
-        match exactly.  We need to check them explicitly here,
-        because type_unification_real treats them as any other
-        cvqualified parameter.  */
+        match exactly.  We need to check them explicitly here,
+        because type_unification_real treats them as any other
+        cvqualified parameter.  */
       if (TREE_CODE (parm) == METHOD_TYPE
          && (!check_cv_quals_for_unify
              (UNIFY_ALLOW_NONE,
@@ -10669,7 +10978,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
   tree args2 = TYPE_ARG_TYPES (TREE_TYPE (decl2));
   int better1 = 0;
   int better2 = 0;
-  
+
   /* Remove the this parameter from non-static member functions.  If
      one is a non-static member function and the other is not a static
      member function, remove the first parameter from that function
@@ -10692,7 +11001,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
          args1 = TREE_CHAIN (args1);
        }
     }
-    
+
   /* If only one is a conversion operator, they are unordered.  */
   if (DECL_CONV_FN_P (decl1) != DECL_CONV_FN_P (decl2))
     return 0;
@@ -10817,7 +11126,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
    specialized.
 
    See [temp.class.order] for information about determining which of
-   two templates is more specialized.  */ 
+   two templates is more specialized.  */
 
 static int
 more_specialized_class (tree pat1, tree pat2)
@@ -10834,13 +11143,13 @@ more_specialized_class (tree pat1, tree pat2)
      types in the arguments, and we need our dependency check functions
      to behave correctly.  */
   ++processing_template_decl;
-  targs = get_class_bindings (TREE_VALUE (pat1), 
+  targs = get_class_bindings (TREE_VALUE (pat1),
                              CLASSTYPE_TI_ARGS (tmpl1),
                              CLASSTYPE_TI_ARGS (tmpl2));
   if (targs)
     --winner;
 
-  targs = get_class_bindings (TREE_VALUE (pat2), 
+  targs = get_class_bindings (TREE_VALUE (pat2),
                              CLASSTYPE_TI_ARGS (tmpl2),
                              CLASSTYPE_TI_ARGS (tmpl1));
   if (targs)
@@ -10882,7 +11191,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
       converted_args
        = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
                                 explicit_args, NULL_TREE,
-                                tf_none, 
+                                tf_none,
                                 /*require_all_args=*/false,
                                 /*use_default_args=*/false);
       if (converted_args == error_mark_node)
@@ -10939,11 +11248,11 @@ get_class_bindings (tree tparms, tree spec_args, tree args)
                           innermost_deduced_args);
     }
   else
-    deduced_args = innermost_deduced_args; 
+    deduced_args = innermost_deduced_args;
 
-  if (unify (tparms, deduced_args, 
-            INNERMOST_TEMPLATE_ARGS (spec_args), 
-            INNERMOST_TEMPLATE_ARGS (args), 
+  if (unify (tparms, deduced_args,
+            INNERMOST_TEMPLATE_ARGS (spec_args),
+            INNERMOST_TEMPLATE_ARGS (args),
             UNIFY_ALLOW_NONE))
     return NULL_TREE;
 
@@ -10953,7 +11262,7 @@ get_class_bindings (tree tparms, tree spec_args, tree args)
 
   /* Verify that nondeduced template arguments agree with the type
      obtained from argument deduction.
-     
+
      For example:
 
        struct A { typedef int X; };
@@ -11131,8 +11440,8 @@ most_specialized_class (tree type, tree tmpl)
       tree spec_args;
 
       partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t));
-      spec_args = get_class_bindings (TREE_VALUE (t), 
-                                     partial_spec_args, 
+      spec_args = get_class_bindings (TREE_VALUE (t),
+                                     partial_spec_args,
                                      args);
       if (spec_args)
        {
@@ -11202,7 +11511,7 @@ do_decl_instantiation (tree decl, tree storage)
   tree result = NULL_TREE;
   int extern_p = 0;
 
-  if (!decl)
+  if (!decl || decl == error_mark_node)
     /* An error occurred, for which grokdeclarator has already issued
        an appropriate message.  */
     return;
@@ -11294,11 +11603,11 @@ do_decl_instantiation (tree decl, tree storage)
     }
   else
     error ("storage class %qD applied to template instantiation", storage);
-  
+
   check_explicit_instantiation_namespace (result);
   mark_decl_instantiated (result, extern_p);
   if (! extern_p)
-    instantiate_decl (result, /*defer_ok=*/1, 
+    instantiate_decl (result, /*defer_ok=*/1,
                      /*expl_inst_class_mem_p=*/false);
 }
 
@@ -11336,7 +11645,7 @@ instantiate_class_member (tree decl, int extern_p)
 {
   mark_decl_instantiated (decl, extern_p);
   if (! extern_p)
-    instantiate_decl (decl, /*defer_ok=*/1, 
+    instantiate_decl (decl, /*defer_ok=*/1,
                      /*expl_inst_class_mem_p=*/true);
 }
 
@@ -11561,7 +11870,8 @@ regenerate_decl_from_template (tree decl, tree tmpl)
   else if (TREE_CODE (decl) == VAR_DECL)
     DECL_INITIAL (decl) =
       tsubst_expr (DECL_INITIAL (code_pattern), args,
-                  tf_error, DECL_TI_TEMPLATE (decl));
+                  tf_error, DECL_TI_TEMPLATE (decl),
+                  /*integral_constant_expression_p=*/false);
   else
     gcc_unreachable ();
 
@@ -11634,7 +11944,7 @@ template_for_substitution (tree decl)
    explicitly instantiated class template.  */
 
 tree
-instantiate_decl (tree d, int defer_ok, 
+instantiate_decl (tree d, int defer_ok,
                  bool expl_inst_class_mem_p)
 {
   tree tmpl = DECL_TI_TEMPLATE (d);
@@ -11699,9 +12009,9 @@ instantiate_decl (tree d, int defer_ok,
   code_pattern = DECL_TEMPLATE_RESULT (td);
 
   /* We should never be trying to instantiate a member of a class
-     template or partial specialization.  */ 
+     template or partial specialization.  */
   gcc_assert (d != code_pattern);
+
   if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d))
       || DECL_TEMPLATE_SPECIALIZATION (td))
     /* In the case of a friend template whose definition is provided
@@ -11732,9 +12042,9 @@ instantiate_decl (tree d, int defer_ok,
 
   /* If D is a member of an explicitly instantiated class template,
      and no definition is available, treat it like an implicit
-     instantiation.  */ 
-  if (!pattern_defined && expl_inst_class_mem_p 
-      && DECL_EXPLICIT_INSTANTIATION (d)) 
+     instantiation.  */
+  if (!pattern_defined && expl_inst_class_mem_p
+      && DECL_EXPLICIT_INSTANTIATION (d))
     {
       DECL_NOT_REALLY_EXTERN (d) = 0;
       DECL_INTERFACE_KNOWN (d) = 0;
@@ -11780,14 +12090,14 @@ instantiate_decl (tree d, int defer_ok,
       && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
       /* ... we instantiate static data members whose values are
         needed in integral constant expressions.  */
-      && ! (TREE_CODE (d) == VAR_DECL 
+      && ! (TREE_CODE (d) == VAR_DECL
            && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (d)))
     goto out;
   /* Defer all other templates, unless we have been explicitly
      forbidden from doing so.  */
   if (/* If there is no definition, we cannot instantiate the
         template.  */
-      ! pattern_defined 
+      ! pattern_defined
       /* If it's OK to postpone instantiation, do so.  */
       || defer_ok
       /* If this is a static data member that will be defined
@@ -11799,7 +12109,7 @@ instantiate_decl (tree d, int defer_ok,
       /* The definition of the static data member is now required so
         we must substitute the initializer.  */
       if (TREE_CODE (d) == VAR_DECL
-         && !DECL_INITIAL (d) 
+         && !DECL_INITIAL (d)
          && DECL_INITIAL (code_pattern))
        {
          tree ns;
@@ -11808,10 +12118,10 @@ instantiate_decl (tree d, int defer_ok,
          ns = decl_namespace_context (d);
          push_nested_namespace (ns);
          push_nested_class (DECL_CONTEXT (d));
-         init = tsubst_expr (DECL_INITIAL (code_pattern), 
+         init = tsubst_expr (DECL_INITIAL (code_pattern),
                              args,
-                             tf_warning_or_error, NULL_TREE);
-         DECL_INITIAL (d) = init;
+                             tf_warning_or_error, NULL_TREE,
+                             /*integral_constant_expression_p=*/false);
          cp_finish_decl (d, init, /*init_const_expr_p=*/false,
                          /*asmspec_tree=*/NULL_TREE,
                          LOOKUP_ONLYCONVERTING);
@@ -11878,11 +12188,20 @@ instantiate_decl (tree d, int defer_ok,
 
   if (TREE_CODE (d) == VAR_DECL)
     {
+      tree init;
+
       /* Clear out DECL_RTL; whatever was there before may not be right
         since we've reset the type of the declaration.  */
       SET_DECL_RTL (d, NULL_RTX);
       DECL_IN_AGGR_P (d) = 0;
 
+      /* The initializer is placed in DECL_INITIAL by
+        regenerate_decl_from_template.  Pull it out so that
+        finish_decl can process it.  */
+      init = DECL_INITIAL (d);
+      DECL_INITIAL (d) = NULL_TREE;
+      DECL_INITIALIZED_P (d) = 0;
+
       /* Clear DECL_EXTERNAL so that cp_finish_decl will process the
         initializer.  That function will defer actual emission until
         we have a chance to determine linkage.  */
@@ -11890,7 +12209,7 @@ instantiate_decl (tree d, int defer_ok,
 
       /* Enter the scope of D so that access-checking works correctly.  */
       push_nested_class (DECL_CONTEXT (d));
-      finish_decl (d, DECL_INITIAL (d), NULL_TREE);
+      finish_decl (d, init, NULL_TREE);
       pop_nested_class ();
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
@@ -11933,7 +12252,8 @@ instantiate_decl (tree d, int defer_ok,
 
       /* Substitute into the body of the function.  */
       tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
-                  tf_warning_or_error, tmpl);
+                  tf_warning_or_error, tmpl,
+                  /*integral_constant_expression_p=*/false);
 
       /* We don't need the local specializations any more.  */
       htab_delete (local_specializations);
@@ -12013,7 +12333,7 @@ instantiate_pending_templates (int retries)
                         fn;
                         fn = TREE_CHAIN (fn))
                      if (! DECL_ARTIFICIAL (fn))
-                       instantiate_decl (fn, 
+                       instantiate_decl (fn,
                                          /*defer_ok=*/0,
                                          /*expl_inst_class_mem_p=*/false);
                  if (COMPLETE_TYPE_P (instantiation))
@@ -12035,7 +12355,7 @@ instantiate_pending_templates (int retries)
              if (!DECL_TEMPLATE_SPECIALIZATION (instantiation)
                  && !DECL_TEMPLATE_INSTANTIATED (instantiation))
                {
-                 instantiation 
+                 instantiation
                    = instantiate_decl (instantiation,
                                        /*defer_ok=*/0,
                                        /*expl_inst_class_mem_p=*/false);
@@ -12087,7 +12407,8 @@ tsubst_initializer_list (tree t, tree argvec)
        in_base_initializer = 1;
 
       init = tsubst_expr (TREE_VALUE (t), argvec, tf_warning_or_error,
-                         NULL_TREE);
+                         NULL_TREE, 
+                         /*integral_constant_expression_p=*/false);
       in_base_initializer = 0;
 
       if (decl)
@@ -12131,7 +12452,8 @@ tsubst_enum (tree tag, tree newtag, tree args)
       /* Note that in a template enum, the TREE_VALUE is the
         CONST_DECL, not the corresponding INTEGER_CST.  */
       value = tsubst_expr (DECL_INITIAL (decl),
-                          args, tf_warning_or_error, NULL_TREE);
+                          args, tf_warning_or_error, NULL_TREE,
+                          /*integral_constant_expression_p=*/true);
 
       /* Give this enumeration constant the correct access.  */
       set_current_access_from_decl (decl);
@@ -12428,7 +12750,8 @@ dependent_scope_ref_p (tree expression, bool criterion (tree))
 }
 
 /* Returns TRUE if the EXPRESSION is value-dependent, in the sense of
-   [temp.dep.constexpr] */
+   [temp.dep.constexpr].  EXPRESSION is already known to be a constant
+   expression.  */
 
 bool
 value_dependent_expression_p (tree expression)
@@ -12519,32 +12842,10 @@ value_dependent_expression_p (tree expression)
              || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
 
     case CALL_EXPR:
-      /* A CALL_EXPR is value-dependent if any argument is
-        value-dependent.  Why do we have to handle CALL_EXPRs in this
-        function at all?  First, some function calls, those for which
-        value_dependent_expression_p is true, man appear in constant
-        expressions.  Second, there appear to be bugs which result in
-        other CALL_EXPRs reaching this point. */
-      {
-       tree function = TREE_OPERAND (expression, 0);
-       tree args = TREE_OPERAND (expression, 1);
-
-       if (value_dependent_expression_p (function))
-         return true;
-
-       if (! args)
-         return false;
-
-       if (TREE_CODE (args) == TREE_LIST)
-         {
-           for (; args; args = TREE_CHAIN (args))
-             if (value_dependent_expression_p (TREE_VALUE (args)))
-               return true;
-           return false;
-         }
-
-       return value_dependent_expression_p (args);
-      }
+      /* A CALL_EXPR may appear in a constant expression if it is a
+        call to a builtin function, e.g., __builtin_constant_p.  All
+        such calls are value-dependent.  */
+      return true;
 
     default:
       /* A constant expression is value-dependent if any subexpression is
@@ -12600,7 +12901,8 @@ type_dependent_expression_p (tree expression)
     return false;
 
   /* An unresolved name is always dependent.  */
-  if (TREE_CODE (expression) == IDENTIFIER_NODE)
+  if (TREE_CODE (expression) == IDENTIFIER_NODE
+      || TREE_CODE (expression) == USING_DECL)
     return true;
 
   /* Some expression forms are never type-dependent.  */
@@ -12697,7 +12999,7 @@ type_dependent_expression_p (tree expression)
     }
 
   gcc_assert (TREE_CODE (expression) != TYPE_DECL);
-  
+
   return (dependent_type_p (TREE_TYPE (expression)));
 }
 
@@ -12747,6 +13049,8 @@ any_dependent_template_arguments_p (tree args)
 
   if (!args)
     return false;
+  if (args == error_mark_node)
+    return true;
 
   for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
     {
@@ -12892,10 +13196,11 @@ build_non_dependent_expr (tree expr)
     return expr;
   /* Preserve OVERLOADs; the functions must be available to resolve
      types.  */
-  inner_expr = (TREE_CODE (expr) == ADDR_EXPR ?
-               TREE_OPERAND (expr, 0) :
-               TREE_CODE (expr) == COMPONENT_REF ?
-               TREE_OPERAND (expr, 1) : expr);
+  inner_expr = expr;
+  if (TREE_CODE (inner_expr) == ADDR_EXPR)
+    inner_expr = TREE_OPERAND (inner_expr, 0);
+  if (TREE_CODE (inner_expr) == COMPONENT_REF)
+    inner_expr = TREE_OPERAND (inner_expr, 1);
   if (is_overloaded_fn (inner_expr)
       || TREE_CODE (inner_expr) == OFFSET_REF)
     return expr;
@@ -12936,7 +13241,7 @@ build_non_dependent_expr (tree expr)
 
   /* If the type is unknown, it can't really be non-dependent */
   gcc_assert (TREE_TYPE (expr) != unknown_type_node);
-  
+
   /* Otherwise, build a NON_DEPENDENT_EXPR.
 
      REFERENCE_TYPEs are not stripped for expressions in templates