]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/pt.c
re PR debug/23336 (enum constants not visible to gdb because of -feliminate-unused...
[thirdparty/gcc.git] / gcc / cp / pt.c
index 614de414cc0c3135bfb103f3d409bc68d186cde5..30e6cd09a4b301df0ec7f89e1c965e31a9610394 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 *);
@@ -337,7 +336,12 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
               NULL);
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
     {
-      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+      tree parm;
+
+      if (TREE_VEC_ELT (parms, i) == error_mark_node)
+        continue;
+
+      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
       gcc_assert (DECL_P (parm));
 
       switch (TREE_CODE (parm))
@@ -659,7 +663,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 "
@@ -896,7 +900,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;
 }
 
@@ -1188,15 +1192,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 +1229,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 +1325,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 +1341,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 +1359,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 +1456,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 +1598,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 +2068,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 +2115,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 +2145,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 +2209,15 @@ 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 parm2;
+
+          if (TREE_VEC_ELT (t1, i) == error_mark_node
+              || TREE_VEC_ELT (t2, i) == error_mark_node)
+            continue;
+
+         parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
+          parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
 
          if (TREE_CODE (parm1) != TREE_CODE (parm2))
            return 0;
@@ -2312,19 +2340,17 @@ 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;
 
-  parm = next;
   gcc_assert (TREE_CODE (parm) == TREE_LIST);
   defval = TREE_PURPOSE (parm);
 
@@ -2348,7 +2374,7 @@ process_template_parm (tree list, tree next, bool is_non_type)
       SET_DECL_TEMPLATE_PARM_P (parm);
 
       if (TREE_TYPE (parm) == error_mark_node)
-       TREE_TYPE (parm) = void_type_node;
+       return chainon(list, error_mark_node);
       else
       {
        /* [temp.param]
@@ -2357,7 +2383,7 @@ process_template_parm (tree list, tree next, bool is_non_type)
           ignored when determining its type.  */
        TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
        if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
-         TREE_TYPE (parm) = void_type_node;
+         return chainon(list, error_mark_node);
       }
 
       /* A template parameter is not modifiable.  */
@@ -2824,6 +2850,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)
@@ -2888,18 +2918,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.  */
@@ -3011,7 +3046,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)
@@ -3459,6 +3494,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
@@ -3570,9 +3607,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
@@ -3598,7 +3635,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;
        }
 
@@ -3748,6 +3785,9 @@ coerce_template_template_parms (tree parm_parms,
 
   for (i = 0; i < nparms; ++i)
     {
+      if (TREE_VEC_ELT (parm_parms, i) == error_mark_node)
+        continue;
+
       parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
       arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
 
@@ -3815,11 +3855,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)
     {
@@ -3911,7 +3948,7 @@ convert_template_argument (tree parm,
 
              if (coerce_template_template_parms (parmparm, argparm,
                                                  complain, in_decl,
-                                                 inner_args))
+                                                 args))
                {
                  val = arg;
 
@@ -3940,7 +3977,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))
@@ -4010,7 +4047,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)
        {
@@ -4033,6 +4071,9 @@ coerce_template_parms (tree parms,
 
       /* Get the Ith template parameter.  */
       parm = TREE_VEC_ELT (parms, i);
+      if (parm == error_mark_node)
+        continue;
 
       /* Calculate the Ith argument.  */
       if (i < nargs)
@@ -4133,8 +4174,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;
+
+      if (TREE_VEC_ELT (parms, i) == error_mark_node)
+        continue;
+
+      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+      arg = TREE_VEC_ELT (arglist, i);
 
       if (i)
        ccat (',');
@@ -4442,7 +4489,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
@@ -4513,7 +4560,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);
 
@@ -4544,7 +4591,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);
 
@@ -4763,6 +4810,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);
@@ -5163,7 +5214,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);
     }
 
@@ -5390,8 +5442,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:
@@ -5435,6 +5500,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
@@ -5514,12 +5581,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);
     }
@@ -5737,15 +5804,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));
@@ -6020,9 +6087,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
@@ -6108,7 +6186,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;
@@ -6297,7 +6375,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;
 
@@ -6320,7 +6398,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);
@@ -6566,6 +6644,16 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          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;
 
@@ -6648,7 +6736,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)
          {
@@ -6666,40 +6754,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;
+           spec = retrieve_local_specialization (t);
          }
-
-       /* 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);
-         }
-       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)
          {
@@ -6720,7 +6832,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
              {
                tree ve = DECL_VALUE_EXPR (t);
                ve = tsubst_expr (ve, args, complain, in_decl);
-               SET_DECL_VALUE_EXPR (r, ve);
+               SET_DECL_VALUE_EXPR (r, ve);
              }
          }
        else if (DECL_SELF_REFERENCE_P (t))
@@ -6738,6 +6850,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)
          {
@@ -7649,8 +7773,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))
@@ -7701,7 +7825,7 @@ 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));
@@ -7892,7 +8016,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)
@@ -8241,8 +8365,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
@@ -8403,8 +8525,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        }
       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 ();
 
@@ -8417,7 +8541,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
          tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
          if (FN_TRY_BLOCK_P (t))
-           finish_function_handler_sequence (stmt);
+           finish_function_handler_sequence (stmt, compound_stmt);
          else
            finish_handler_sequence (stmt);
        }
@@ -8425,20 +8549,18 @@ 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);
        finish_handler (stmt);
@@ -8454,7 +8576,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                args, complain, in_decl);
       stmt = begin_omp_parallel ();
       tsubst_expr (OMP_PARALLEL_BODY (t), args, complain, in_decl);
-      finish_omp_parallel (tmp, stmt);
+      OMP_PARALLEL_COMBINED (finish_omp_parallel (tmp, stmt))
+       = OMP_PARALLEL_COMBINED (t);
       break;
 
     case OMP_FOR:
@@ -8520,10 +8643,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        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));
+       finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1);
       }
       break;
 
@@ -8859,7 +8979,7 @@ tsubst_copy_and_build (tree t,
              }
            else
              qualified_p = false;
-           
+
            function = tsubst_copy_and_build (function, args, complain,
                                              in_decl,
                                              !qualified_p);
@@ -9100,7 +9220,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:
       {
@@ -9120,7 +9240,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:
@@ -9165,14 +9288,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;
            }
@@ -9210,6 +9333,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;
@@ -9269,9 +9393,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;
 
@@ -9597,10 +9730,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;
        }
 
@@ -10134,7 +10267,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;
 
          {
@@ -10157,8 +10290,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
@@ -10170,8 +10303,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,
@@ -10248,6 +10381,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))
@@ -10487,9 +10622,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,
@@ -10680,7 +10815,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
@@ -10703,7 +10838,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;
@@ -10828,7 +10963,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)
@@ -10845,13 +10980,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)
@@ -10893,7 +11028,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)
@@ -10950,11 +11085,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;
 
@@ -10964,7 +11099,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; };
@@ -11142,8 +11277,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)
        {
@@ -11213,7 +11348,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;
@@ -11305,11 +11440,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);
 }
 
@@ -11347,7 +11482,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);
 }
 
@@ -11645,7 +11780,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);
@@ -11710,9 +11845,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
@@ -11743,9 +11878,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;
@@ -11791,14 +11926,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
@@ -11810,7 +11945,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;
@@ -11819,10 +11954,9 @@ 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;
          cp_finish_decl (d, init, /*init_const_expr_p=*/false,
                          /*asmspec_tree=*/NULL_TREE,
                          LOOKUP_ONLYCONVERTING);
@@ -11889,11 +12023,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.  */
@@ -11901,7 +12044,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)
@@ -12024,7 +12167,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))
@@ -12046,7 +12189,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);
@@ -12439,7 +12582,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)
@@ -12530,32 +12674,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
@@ -12708,7 +12830,7 @@ type_dependent_expression_p (tree expression)
     }
 
   gcc_assert (TREE_CODE (expression) != TYPE_DECL);
-  
+
   return (dependent_type_p (TREE_TYPE (expression)));
 }
 
@@ -12758,6 +12880,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)
     {
@@ -12903,10 +13027,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;
@@ -12947,7 +13072,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