Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / gcc / cp / decl.c
index db0c233..09296de 100644 (file)
@@ -1,7 +1,5 @@
 /* Process declarations and variables for C++ compiler.
-   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1988-2013 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -39,7 +37,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "decl.h"
 #include "intl.h"
-#include "output.h"
 #include "toplev.h"
 #include "hashtab.h"
 #include "tm_p.h"
@@ -54,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "pointer-set.h"
 #include "splay-tree.h"
 #include "plugin.h"
+#include "cgraph.h"
 
 /* Possible cases of bad specifiers type used by bad_specifiers. */
 enum bad_spec_place {
@@ -91,7 +89,7 @@ static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool);
 static int walk_namespaces_r (tree, walk_namespaces_fn, void *);
 static void maybe_deduce_size_from_array_init (tree, tree);
 static void layout_var_decl (tree);
-static tree check_initializer (tree, tree, int, VEC(tree,gc) **);
+static tree check_initializer (tree, tree, int, vec<tree, va_gc> **);
 static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
 static void save_function_data (tree);
 static void copy_type_enum (tree , tree);
@@ -170,6 +168,9 @@ tree global_scope_name;
    in the TREE_PURPOSE slot.  */
 tree static_aggregates;
 
+/* Like static_aggregates, but for thread_local variables.  */
+tree tls_aggregates;
+
 /* -- end of C++ */
 
 /* A node for the integer constant 2.  */
@@ -215,7 +216,7 @@ struct GTY(()) named_label_entry {
   tree names_in_scope;
   /* A vector of all decls from all binding levels that would be
      crossed by a backward branch to the label.  */
-  VEC(tree,gc) *bad_decls;
+  vec<tree, va_gc> *bad_decls;
 
   /* A list of uses of the label, before the label is defined.  */
   struct named_label_use_entry *uses;
@@ -238,7 +239,7 @@ int function_depth;
 /* To avoid unwanted recursion, finish_function defers all mark_used calls
    encountered during its execution until it finishes.  */
 bool defer_mark_used_calls;
-VEC(tree, gc) *deferred_mark_used_calls;
+vec<tree, va_gc> *deferred_mark_used_calls;
 
 /* States indicating how grokdeclarator() should handle declspecs marked
    with __attribute__((deprecated)).  An object declared as
@@ -255,10 +256,8 @@ typedef struct GTY(()) incomplete_var_d {
   tree incomplete_type;
 } incomplete_var;
 
-DEF_VEC_O(incomplete_var);
-DEF_VEC_ALLOC_O(incomplete_var,gc);
 
-static GTY(()) VEC(incomplete_var,gc) *incomplete_vars;
+static GTY(()) vec<incomplete_var, va_gc> *incomplete_vars;
 \f
 /* Returns the kind of template specialization we are currently
    processing, given that it's declaration contained N_CLASS_SCOPES
@@ -483,7 +482,7 @@ poplevel_named_label_1 (void **slot, void *data)
                                                     ? DECL_CHAIN (decl)
                                                     : TREE_CHAIN (decl)))
        if (decl_jump_unsafe (decl))
-         VEC_safe_push (tree, gc, ent->bad_decls, decl);
+         vec_safe_push (ent->bad_decls, decl);
 
       ent->binding_level = obl;
       ent->names_in_scope = obl->names;
@@ -553,7 +552,7 @@ poplevel (int keep, int reverse, int functionbody)
   unsigned ix;
   cp_label_binding *label_bind;
 
-  timevar_start (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
  restart:
 
   block = NULL_TREE;
@@ -564,8 +563,7 @@ poplevel (int keep, int reverse, int functionbody)
     functionbody = 0;
   subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
 
-  gcc_assert (!VEC_length(cp_class_binding,
-                         current_binding_level->class_shadowed));
+  gcc_assert (!vec_safe_length (current_binding_level->class_shadowed));
 
   /* We used to use KEEP == 2 to indicate that the new block should go
      at the beginning of the list of blocks at this binding level,
@@ -618,26 +616,32 @@ poplevel (int keep, int reverse, int functionbody)
   /* Before we remove the declarations first check for unused variables.  */
   if ((warn_unused_variable || warn_unused_but_set_variable)
       && !processing_template_decl)
-    for (decl = getdecls (); decl; decl = TREE_CHAIN (decl))
-      if (TREE_CODE (decl) == VAR_DECL
-         && (! TREE_USED (decl) || !DECL_READ_P (decl))
-         && ! DECL_IN_SYSTEM_HEADER (decl)
-         && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
-       {
-         if (! TREE_USED (decl))
-           warning (OPT_Wunused_variable, "unused variable %q+D", decl);
-         else if (DECL_CONTEXT (decl) == current_function_decl
-                  && TREE_TYPE (decl) != error_mark_node
-                  && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
-                  && errorcount == unused_but_set_errorcount
-                  && (!CLASS_TYPE_P (TREE_TYPE (decl))
-                      || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
-           {
-             warning (OPT_Wunused_but_set_variable,
-                      "variable %q+D set but not used", decl); 
-             unused_but_set_errorcount = errorcount;
-           }
-       }
+    for (tree d = getdecls (); d; d = TREE_CHAIN (d))
+      {
+       /* There are cases where D itself is a TREE_LIST.  See in
+          push_local_binding where the list of decls returned by
+          getdecls is built.  */
+       decl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d;
+       if (TREE_CODE (decl) == VAR_DECL
+           && (! TREE_USED (decl) || !DECL_READ_P (decl))
+           && ! DECL_IN_SYSTEM_HEADER (decl)
+           && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)
+           && TREE_TYPE (decl) != error_mark_node
+           && (!CLASS_TYPE_P (TREE_TYPE (decl))
+               || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+         {
+           if (! TREE_USED (decl))
+             warning (OPT_Wunused_variable, "unused variable %q+D", decl);
+           else if (DECL_CONTEXT (decl) == current_function_decl
+                    && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
+                    && errorcount == unused_but_set_errorcount)
+             {
+               warning (OPT_Wunused_but_set_variable,
+                        "variable %q+D set but not used", decl);
+               unused_but_set_errorcount = errorcount;
+             }
+         }
+      }
 
   /* Remove declarations for all the DECLs in this level.  */
   for (link = decls; link; link = TREE_CHAIN (link))
@@ -699,9 +703,9 @@ poplevel (int keep, int reverse, int functionbody)
              /* Add it to the list of dead variables in the next
                 outermost binding to that we can remove these when we
                 leave that binding.  */
-             VEC_safe_push (tree, gc,
-                            current_binding_level->level_chain->dead_vars_from_for,
-                            link);
+             vec_safe_push (
+                 current_binding_level->level_chain->dead_vars_from_for,
+                 link);
 
              /* Although we don't pop the cxx_binding, we do clear
                 its SCOPE since the scope is going away now.  */
@@ -730,8 +734,8 @@ poplevel (int keep, int reverse, int functionbody)
 
   /* Remove declarations for any `for' variables from inner scopes
      that we kept around.  */
-  FOR_EACH_VEC_ELT_REVERSE (tree, current_binding_level->dead_vars_from_for,
-                           ix, decl)
+  FOR_EACH_VEC_SAFE_ELT_REVERSE (current_binding_level->dead_vars_from_for,
+                                ix, decl)
     pop_binding (DECL_NAME (decl), decl);
 
   /* Restore the IDENTIFIER_TYPE_VALUEs.  */
@@ -740,9 +744,8 @@ poplevel (int keep, int reverse, int functionbody)
     SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
 
   /* Restore the IDENTIFIER_LABEL_VALUEs for local labels.  */
-  FOR_EACH_VEC_ELT_REVERSE (cp_label_binding,
-                           current_binding_level->shadowed_labels,
-                           ix, label_bind)
+  FOR_EACH_VEC_SAFE_ELT_REVERSE (current_binding_level->shadowed_labels,
+                                ix, label_bind)
     pop_local_label (label_bind->label, label_bind->prev_value);
 
   /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs
@@ -819,7 +822,7 @@ poplevel (int keep, int reverse, int functionbody)
   if (kind == sk_cleanup)
     goto restart;
 
-  timevar_stop (TV_NAME_LOOKUP);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return block;
 }
 
@@ -857,9 +860,9 @@ int
 wrapup_globals_for_namespace (tree name_space, void* data)
 {
   cp_binding_level *level = NAMESPACE_LEVEL (name_space);
-  VEC(tree,gc) *statics = level->static_decls;
-  tree *vec = VEC_address (tree, statics);
-  int len = VEC_length (tree, statics);
+  vec<tree, va_gc> *statics = level->static_decls;
+  tree *vec = statics->address ();
+  int len = statics->length ();
   int last_time = (data != 0);
 
   if (last_time)
@@ -908,10 +911,10 @@ push_local_name (tree decl)
 
   name = DECL_NAME (decl);
 
-  nelts = VEC_length (tree, local_names);
+  nelts = vec_safe_length (local_names);
   for (i = 0; i < nelts; i++)
     {
-      t = VEC_index (tree, local_names, i);
+      t = (*local_names)[i];
       if (DECL_NAME (t) == name)
        {
          if (!DECL_LANG_SPECIFIC (decl))
@@ -922,13 +925,13 @@ push_local_name (tree decl)
          else
            DECL_DISCRIMINATOR (decl) = 1;
 
-         VEC_replace (tree, local_names, i, decl);
+         (*local_names)[i] = decl;
          timevar_stop (TV_NAME_LOOKUP);
          return;
        }
     }
 
-  VEC_safe_push (tree, gc, local_names, decl);
+  vec_safe_push (local_names, decl);
   timevar_stop (TV_NAME_LOOKUP);
 }
 \f
@@ -960,6 +963,7 @@ decls_match (tree newdecl, tree olddecl)
       tree f2 = TREE_TYPE (olddecl);
       tree p1 = TYPE_ARG_TYPES (f1);
       tree p2 = TYPE_ARG_TYPES (f2);
+      tree r2;
 
       /* Specializations of different templates are different functions
         even if they have the same type.  */
@@ -977,18 +981,23 @@ decls_match (tree newdecl, tree olddecl)
                && DECL_EXTERN_C_P (olddecl)))
        return 0;
 
-#ifdef NO_IMPLICIT_EXTERN_C
       /* A new declaration doesn't match a built-in one unless it
         is also extern "C".  */
       if (DECL_IS_BUILTIN (olddecl)
          && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
        return 0;
-#endif
 
       if (TREE_CODE (f1) != TREE_CODE (f2))
        return 0;
 
-      if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
+      /* A declaration with deduced return type should use its pre-deduction
+        type for declaration matching.  */
+      if (FNDECL_USED_AUTO (olddecl))
+       r2 = DECL_STRUCT_FUNCTION (olddecl)->language->x_auto_return_pattern;
+      else
+       r2 = TREE_TYPE (f2);
+
+      if (same_type_p (TREE_TYPE (f1), r2))
        {
          if (!prototype_p (f2) && DECL_EXTERN_C_P (olddecl)
              && (DECL_BUILT_IN (olddecl)
@@ -1018,12 +1027,42 @@ decls_match (tree newdecl, tree olddecl)
          else
            types_match =
              compparms (p1, p2)
+             && type_memfn_rqual (f1) == type_memfn_rqual (f2)
              && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE
                  || comp_type_attributes (TREE_TYPE (newdecl),
                                           TREE_TYPE (olddecl)) != 0);
        }
       else
        types_match = 0;
+
+      /* The decls dont match if they correspond to two different versions
+        of the same function.   Disallow extern "C" functions to be
+        versions for now.  */
+      if (types_match
+         && !DECL_EXTERN_C_P (newdecl)
+         && !DECL_EXTERN_C_P (olddecl)
+         && targetm.target_option.function_versions (newdecl, olddecl))
+       {
+         /* Mark functions as versions if necessary.  Modify the mangled decl
+            name if necessary.  */
+         if (DECL_FUNCTION_VERSIONED (newdecl)
+             && DECL_FUNCTION_VERSIONED (olddecl))
+           return 0;
+         if (!DECL_FUNCTION_VERSIONED (newdecl))
+           {
+             DECL_FUNCTION_VERSIONED (newdecl) = 1;
+             if (DECL_ASSEMBLER_NAME_SET_P (newdecl))
+               mangle_decl (newdecl);
+           }
+         if (!DECL_FUNCTION_VERSIONED (olddecl))
+           {
+             DECL_FUNCTION_VERSIONED (olddecl) = 1;
+             if (DECL_ASSEMBLER_NAME_SET_P (olddecl))
+              mangle_decl (olddecl);
+           }
+         record_function_versions (olddecl, newdecl);
+         return 0;
+       }
     }
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
@@ -1456,6 +1495,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            {
              error ("declaration of template %q#D", newdecl);
              error ("conflicts with previous declaration %q+#D", olddecl);
+             return error_mark_node;
            }
          else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
                   && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
@@ -1482,11 +1522,19 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
              error ("previous declaration %q+#D here", olddecl);
              return NULL_TREE;
            }
-         else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
+         /* For function versions, params and types match, but they
+            are not ambiguous.  */
+         else if ((!DECL_FUNCTION_VERSIONED (newdecl)
+                   && !DECL_FUNCTION_VERSIONED (olddecl))
+                  && compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
                              TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
            {
              error ("new declaration %q#D", newdecl);
-             error ("ambiguates old declaration %q+#D", olddecl);
+             if (FNDECL_USED_AUTO (olddecl))
+               error_at (DECL_SOURCE_LOCATION (olddecl), "ambiguates old "
+                         "declaration with deduced return type");
+             else
+               error ("ambiguates old declaration %q+#D", olddecl);
               return error_mark_node;
            }
          else
@@ -1709,12 +1757,16 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
        }
 
-      if (DECL_DELETED_FN (newdecl))
+      if (!(DECL_TEMPLATE_INSTANTIATION (olddecl)
+           && DECL_TEMPLATE_SPECIALIZATION (newdecl)))
        {
-         error ("deleted definition of %qD", newdecl);
-         error ("after previous declaration %q+D", olddecl);
+         if (DECL_DELETED_FN (newdecl))
+           {
+             error ("deleted definition of %qD", newdecl);
+             error ("after previous declaration %q+D", olddecl);
+           }
+         DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
        }
-      DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
     }
 
   /* Deal with C++: must preserve virtual function table size.  */
@@ -2031,7 +2083,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          /* DECL_THUNKS is only valid for virtual functions,
             otherwise it is a DECL_FRIEND_CONTEXT.  */
          if (DECL_VIRTUAL_P (newdecl))
-           DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
+           SET_DECL_THUNKS (newdecl, DECL_THUNKS (olddecl));
        }
       /* Only variables have this field.  */
       else if (TREE_CODE (newdecl) == VAR_DECL
@@ -2142,39 +2194,40 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
          DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
        }
+      /* If redeclaring a builtin function, it stays built in
+        if newdecl is a gnu_inline definition, or if newdecl is just
+        a declaration.  */
+      if (DECL_BUILT_IN (olddecl)
+         && (new_defines_function ? GNU_INLINE_P (newdecl) : types_match))
+       {
+         DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
+         DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+         /* If we're keeping the built-in definition, keep the rtl,
+            regardless of declaration matches.  */
+         COPY_DECL_RTL (olddecl, newdecl);
+         if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
+           {
+             enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
+             switch (fncode)
+               {
+                 /* If a compatible prototype of these builtin functions
+                    is seen, assume the runtime implements it with the
+                    expected semantics.  */
+               case BUILT_IN_STPCPY:
+                 if (builtin_decl_explicit_p (fncode))
+                   set_builtin_decl_implicit_p (fncode, true);
+                 break;
+               default:
+                 break;
+               }
+           }
+       }
       if (new_defines_function)
        /* If defining a function declared with other language
           linkage, use the previously declared language linkage.  */
        SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
       else if (types_match)
        {
-         /* If redeclaring a builtin function, and not a definition,
-            it stays built in.  */
-         if (DECL_BUILT_IN (olddecl))
-           {
-             DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
-             DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
-             /* If we're keeping the built-in definition, keep the rtl,
-                regardless of declaration matches.  */
-             COPY_DECL_RTL (olddecl, newdecl);
-             if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
-               {
-                 enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
-                 switch (fncode)
-                   {
-                     /* If a compatible prototype of these builtin functions
-                        is seen, assume the runtime implements it with the
-                        expected semantics.  */
-                   case BUILT_IN_STPCPY:
-                     if (builtin_decl_explicit_p (fncode))
-                       set_builtin_decl_implicit_p (fncode, true);
-                     break;
-                   default:
-                     break;
-                   }
-               }
-           }
-
          DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
          /* Don't clear out the arguments if we're just redeclaring a
             function.  */
@@ -2250,6 +2303,18 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
   else if (DECL_PRESERVE_P (newdecl))
     DECL_PRESERVE_P (olddecl) = 1;
 
+  /* Merge the DECL_FUNCTION_VERSIONED information.  newdecl will be copied
+     to olddecl and deleted.  */
+  if (TREE_CODE (newdecl) == FUNCTION_DECL
+      && DECL_FUNCTION_VERSIONED (olddecl))
+    {
+      /* Set the flag for newdecl so that it gets copied to olddecl.  */
+      DECL_FUNCTION_VERSIONED (newdecl) = 1;
+      /* newdecl will be purged after copying to olddecl and is no longer
+         a version.  */
+      delete_function_version (newdecl);
+    }
+
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
       int function_size;
@@ -2414,6 +2479,10 @@ redeclaration_error_message (tree newdecl, tree olddecl)
            }
        }
 
+      check_abi_tag_redeclaration
+       (olddecl, lookup_attribute ("abi_tag", DECL_ATTRIBUTES (olddecl)),
+        lookup_attribute ("abi_tag", DECL_ATTRIBUTES (newdecl)));
+
       return NULL;
     }
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
@@ -2468,7 +2537,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       if ((cxx_dialect != cxx98) 
           && TREE_CODE (ot) == FUNCTION_DECL && DECL_FRIEND_P (ot)
           && !check_default_tmpl_args (nt, DECL_TEMPLATE_PARMS (newdecl), 
-                                       /*is_primary=*/1, /*is_partial=*/0,
+                                       /*is_primary=*/true,
+                                      /*is_partial=*/false,
                                        /*is_friend_decl=*/2))
         return G_("redeclaration of friend %q#D "
                  "may not have default template arguments");
@@ -2626,16 +2696,15 @@ tree
 declare_local_label (tree id)
 {
   tree decl;
-  cp_label_binding *bind;
+  cp_label_binding bind;
 
   /* Add a new entry to the SHADOWED_LABELS list so that when we leave
      this scope we can restore the old value of IDENTIFIER_TYPE_VALUE.  */
-  bind = VEC_safe_push (cp_label_binding, gc,
-                       current_binding_level->shadowed_labels, NULL);
-  bind->prev_value = IDENTIFIER_LABEL_VALUE (id);
+  bind.prev_value = IDENTIFIER_LABEL_VALUE (id);
 
   decl = make_label_decl (id, /*local_p=*/1);
-  bind->label = decl;
+  bind.label = decl;
+  vec_safe_push (current_binding_level->shadowed_labels, bind);
 
   return decl;
 }
@@ -2660,8 +2729,7 @@ decl_jump_unsafe (tree decl)
 
   type = strip_array_types (type);
 
-  if (type_has_nontrivial_default_init (TREE_TYPE (decl))
-      || DECL_NONTRIVIALLY_INITIALIZED_P (decl))
+  if (DECL_NONTRIVIALLY_INITIALIZED_P (decl))
     return 2;
 
   if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
@@ -2819,14 +2887,14 @@ check_goto (tree decl)
     }
 
   if (ent->in_try_scope || ent->in_catch_scope
-      || ent->in_omp_scope || !VEC_empty (tree, ent->bad_decls))
+      || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls))
     {
       permerror (input_location, "jump to label %q+D", decl);
       permerror (input_location, "  from here");
       identified = true;
     }
 
-  FOR_EACH_VEC_ELT (tree, ent->bad_decls, ix, bad)
+  FOR_EACH_VEC_SAFE_ELT (ent->bad_decls, ix, bad)
     {
       int u = decl_jump_unsafe (bad);
 
@@ -3222,13 +3290,15 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
        name = TREE_OPERAND (fullname, 0) = DECL_NAME (name);
       else if (TREE_CODE (name) == OVERLOAD)
        {
-         error ("%qD is not a type", name);
+         if (complain & tf_error)
+           error ("%qD is not a type", name);
          return error_mark_node;
        }
     }
   if (TREE_CODE (name) == TEMPLATE_DECL)
     {
-      error ("%qD used without template parameters", name);
+      if (complain & tf_error)
+       error ("%qD used without template parameters", name);
       return error_mark_node;
     }
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
@@ -3294,9 +3364,9 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
               context, name, t);
       return error_mark_node;
     }
-  
-  if (complain & tf_error)
-    perform_or_defer_access_check (TYPE_BINFO (context), t, t);
+
+  if (!perform_or_defer_access_check (TYPE_BINFO (context), t, t, complain))
+    return error_mark_node;
 
   /* If we are currently parsing a template and if T is a typedef accessed
      through CONTEXT then we need to remember and check access of T at
@@ -3311,7 +3381,9 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   
   if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
     t = TREE_TYPE (t);
-  
+
+  maybe_record_typedef_use (t);
+
   return t;
 }
 
@@ -3366,8 +3438,9 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
          return error_mark_node;
        }
 
-      if (complain & tf_error)
-       perform_or_defer_access_check (TYPE_BINFO (context), tmpl, tmpl);
+      if (!perform_or_defer_access_check (TYPE_BINFO (context), tmpl, tmpl,
+                                         complain))
+       return error_mark_node;
 
       return tmpl;
     }
@@ -3644,10 +3717,6 @@ cxx_init_decl_processing (void)
   init_list_type_node = make_node (LANG_TYPE);
   record_unknown_type (init_list_type_node, "init list");
 
-  dependent_lambda_return_type_node = make_node (LANG_TYPE);
-  record_unknown_type (dependent_lambda_return_type_node,
-                      "undeduced lambda return type");
-
   {
     /* Make sure we get a unique function type, so we can give
        its pointer type a name.  (This wins for gdb.) */
@@ -3809,7 +3878,6 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep)
 
   /* As we're using pushdecl_with_scope, we must set the context.  */
   DECL_CONTEXT (decl) = current_function_decl;
-  DECL_PRETTY_FUNCTION_P (decl) = type_dep;
 
   TREE_STATIC (decl) = 1;
   TREE_READONLY (decl) = 1;
@@ -4113,16 +4181,35 @@ fixup_anonymous_aggr (tree t)
     }
 }
 
+/* Warn for an attribute located at LOCATION that appertains to the
+   class type CLASS_TYPE that has not been properly placed after its
+   class-key, in it class-specifier.  */
+
+void
+warn_misplaced_attr_for_class_type (source_location location,
+                                   tree class_type)
+{
+  gcc_assert (TAGGED_TYPE_P (class_type));
+
+  warning_at (location, OPT_Wattributes,
+             "attribute ignored in declaration "
+             "of %q#T", class_type);
+  inform (location,
+         "attribute for %q#T must follow the %qs keyword",
+         class_type, class_key_or_enum_as_string (class_type));
+}
+
 /* Make sure that a declaration with no declarator is well-formed, i.e.
    just declares a tagged type or anonymous union.
 
    Returns the type declared; or NULL_TREE if none.  */
 
 tree
-check_tag_decl (cp_decl_specifier_seq *declspecs)
+check_tag_decl (cp_decl_specifier_seq *declspecs,
+               bool explicit_type_instantiation_p)
 {
-  int saw_friend = declspecs->specs[(int)ds_friend] != 0;
-  int saw_typedef = declspecs->specs[(int)ds_typedef] != 0;
+  int saw_friend = decl_spec_seq_has_spec_p (declspecs, ds_friend);
+  int saw_typedef = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
   /* If a class, struct, or enum type is declared by the DECLSPECS
      (i.e, if a class-specifier, enum-specifier, or non-typename
      elaborated-type-specifier appears in the DECLSPECS),
@@ -4135,7 +4222,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
   else if (declspecs->redefined_builtin_type)
     {
       if (!in_system_header)
-       permerror (input_location, "redeclaration of C++ built-in type %qT",
+       permerror (declspecs->locations[ds_redefined_builtin_type_spec],
+                  "redeclaration of C++ built-in type %qT",
                   declspecs->redefined_builtin_type);
       return NULL_TREE;
     }
@@ -4185,49 +4273,64 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
       SET_ANON_AGGR_TYPE_P (declared_type);
 
       if (TREE_CODE (declared_type) != UNION_TYPE && !in_system_header)
-       pedwarn (input_location, OPT_pedantic, "ISO C++ prohibits anonymous structs");
+       pedwarn (input_location, OPT_Wpedantic, "ISO C++ prohibits anonymous structs");
     }
 
   else
     {
-      if (declspecs->specs[(int)ds_inline]
-         || declspecs->specs[(int)ds_virtual])
+      if (decl_spec_seq_has_spec_p (declspecs, ds_inline)
+         || decl_spec_seq_has_spec_p (declspecs, ds_virtual))
        error ("%qs can only be specified for functions",
-              declspecs->specs[(int)ds_inline]
+              decl_spec_seq_has_spec_p (declspecs, ds_inline)
               ? "inline" : "virtual");
       else if (saw_friend
               && (!current_class_type
                   || current_scope () != current_class_type))
        error ("%<friend%> can only be specified inside a class");
-      else if (declspecs->specs[(int)ds_explicit])
+      else if (decl_spec_seq_has_spec_p (declspecs, ds_explicit))
        error ("%<explicit%> can only be specified for constructors");
       else if (declspecs->storage_class)
        error ("a storage class can only be specified for objects "
               "and functions");
-      else if (declspecs->specs[(int)ds_const]
-              || declspecs->specs[(int)ds_volatile]
-              || declspecs->specs[(int)ds_restrict]
-              || declspecs->specs[(int)ds_thread])
+      else if (decl_spec_seq_has_spec_p (declspecs, ds_const)
+              || decl_spec_seq_has_spec_p (declspecs, ds_volatile)
+              || decl_spec_seq_has_spec_p (declspecs, ds_restrict)
+              || decl_spec_seq_has_spec_p (declspecs, ds_thread))
        error ("qualifiers can only be specified for objects "
               "and functions");
       else if (saw_typedef)
        warning (0, "%<typedef%> was ignored in this declaration");
-      else if (declspecs->specs[(int) ds_constexpr])
+      else if (decl_spec_seq_has_spec_p (declspecs,  ds_constexpr))
         error ("%<constexpr%> cannot be used for type declarations");
     }
 
-  if (declspecs->attributes && declared_type)
+  if (declspecs->attributes && warn_attributes && declared_type)
     {
-      location_t loc = input_location;
+      location_t loc;
       if (!CLASS_TYPE_P (declared_type)
          || !CLASSTYPE_TEMPLATE_INSTANTIATION (declared_type))
-       /* For a non-template class, use the name location; for a template
-          class (an explicit instantiation), use the current location.  */
-       input_location = location_of (declared_type);
-      warning (0, "attribute ignored in declaration of %q#T", declared_type);
-      warning (0, "attribute for %q#T must follow the %qs keyword",
-              declared_type, class_key_or_enum_as_string (declared_type));
-      input_location = loc;
+       /* For a non-template class, use the name location.  */
+       loc = location_of (declared_type);
+      else
+       /* For a template class (an explicit instantiation), use the
+          current location.  */
+       loc = input_location;
+
+      if (explicit_type_instantiation_p)
+       /* [dcl.attr.grammar]/4:
+
+              No attribute-specifier-seq shall appertain to an explicit
+              instantiation.  */
+       {
+         warning_at (loc, OPT_Wattributes,
+                     "attribute ignored in explicit instantiation %q#T",
+                     declared_type);
+         inform (loc,
+                 "no attribute can be applied to "
+                 "an explicit instantiation");
+       }
+      else
+       warn_misplaced_attr_for_class_type (loc, declared_type);
     }
 
   return declared_type;
@@ -4249,7 +4352,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
 tree
 shadow_tag (cp_decl_specifier_seq *declspecs)
 {
-  tree t = check_tag_decl (declspecs);
+  tree t = check_tag_decl (declspecs,
+                          /*explicit_type_instantiation_p=*/false);
 
   if (!t)
     return NULL_TREE;
@@ -4447,11 +4551,6 @@ start_decl (const cp_declarator *declarator,
                               context, DECL_NAME (decl));
                  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
                }
-             if (processing_specialization
-                 && template_class_depth (context) == 0
-                 && CLASSTYPE_TEMPLATE_SPECIALIZATION (context))
-               error ("template header not allowed in member definition "
-                      "of explicitly specialized class");
              /* Static data member are tricky; an in-class initialization
                 still doesn't provide a definition, so the in-class
                 declaration will have DECL_EXTERNAL set, but will have an
@@ -4461,7 +4560,7 @@ start_decl (const cp_declarator *declarator,
                error ("duplicate initialization of %qD", decl);
              if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false))
                decl = field;
-              if (declspecs->specs[(int) ds_constexpr]
+              if (decl_spec_seq_has_spec_p (declspecs, ds_constexpr)
                   && !DECL_DECLARED_CONSTEXPR_P (field))
                 error ("%qD declared %<constexpr%> outside its class", field);
            }
@@ -4516,18 +4615,6 @@ start_decl (const cp_declarator *declarator,
   if (decl == error_mark_node)
     return error_mark_node;
 
-  /* Tell the back end to use or not use .common as appropriate.  If we say
-     -fconserve-space, we want this to save .data space, at the expense of
-     wrong semantics.  If we say -fno-conserve-space, we want this to
-     produce errors about redefs; to do this we force variables into the
-     data segment.  */
-  if (flag_conserve_space
-      && TREE_CODE (decl) == VAR_DECL
-      && TREE_PUBLIC (decl)
-      && !DECL_THREAD_LOCAL_P (decl)
-      && !have_global_bss_p ())
-    DECL_COMMON (decl) = 1;
-
   if (TREE_CODE (decl) == VAR_DECL
       && DECL_NAMESPACE_SCOPE_P (decl) && !TREE_PUBLIC (decl) && !was_public
       && !DECL_THIS_STATIC (decl) && !DECL_ARTIFICIAL (decl))
@@ -4657,7 +4744,7 @@ grok_reference_init (tree decl, tree type, tree init, int flags)
   if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
       && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
     /* Note: default conversion is only called in very special cases.  */
-    init = decay_conversion (init);
+    init = decay_conversion (init, tf_warning_or_error);
 
   /* Convert INIT to the reference type TYPE.  This may involve the
      creation of a temporary, whose lifetime must be the same as that
@@ -4678,7 +4765,7 @@ grok_reference_init (tree decl, tree type, tree init, int flags)
    is valid, i.e., does not have a designated initializer.  */
 
 static bool
-check_array_designated_initializer (const constructor_elt *ce,
+check_array_designated_initializer (constructor_elt *ce,
                                    unsigned HOST_WIDE_INT index)
 {
   /* Designated initializers for array elements are not supported.  */
@@ -4687,9 +4774,21 @@ check_array_designated_initializer (const constructor_elt *ce,
       /* The parser only allows identifiers as designated
         initializers.  */
       if (ce->index == error_mark_node)
-       error ("name used in a GNU-style designated "
-              "initializer for an array");
-      else if (TREE_CODE (ce->index) == INTEGER_CST)
+       {
+         error ("name used in a GNU-style designated "
+                "initializer for an array");
+         return false;
+       }
+      else if (TREE_CODE (ce->index) == IDENTIFIER_NODE)
+       {
+         error ("name %qD used in a GNU-style designated "
+                "initializer for an array", ce->index);
+         return false;
+       }
+
+      ce->index = cxx_constant_value (ce->index);
+
+      if (TREE_CODE (ce->index) == INTEGER_CST)
        {
          /* A C99 designator is OK if it matches the current index.  */
          if (TREE_INT_CST_LOW (ce->index) == index)
@@ -4698,11 +4797,8 @@ check_array_designated_initializer (const constructor_elt *ce,
            sorry ("non-trivial designated initializers not supported");
        }
       else
-       {
-         gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
-         error ("name %qD used in a GNU-style designated "
-                "initializer for an array", ce->index);
-       }
+       gcc_unreachable ();
+
       return false;
     }
 
@@ -4734,10 +4830,10 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
         initializer.  */
       if (initializer && TREE_CODE (initializer) == CONSTRUCTOR)
        {
-         VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initializer);
+         vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (initializer);
          constructor_elt *ce;
          HOST_WIDE_INT i;
-         FOR_EACH_VEC_ELT (constructor_elt, v, i, ce)
+         FOR_EACH_VEC_SAFE_ELT (v, i, ce)
            if (!check_array_designated_initializer (ce, i))
              failure = 1;
        }
@@ -4749,14 +4845,12 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
          if (failure == 1)
            {
              error ("initializer fails to determine size of %qD", decl);
-             TREE_TYPE (decl) = error_mark_node;
            }
          else if (failure == 2)
            {
              if (do_default)
                {
                  error ("array size missing in %qD", decl);
-                 TREE_TYPE (decl) = error_mark_node;
                }
              /* If a `static' var's size isn't known, make it extern as
                 well as static, so it does not get allocated.  If it's not
@@ -4768,7 +4862,6 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
          else if (failure == 3)
            {
              error ("zero-size array %qD", decl);
-             TREE_TYPE (decl) = error_mark_node;
            }
        }
 
@@ -4999,6 +5092,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
        ++index)
     {
       tree elt_init;
+      constructor_elt *old_cur = d->cur;
 
       check_array_designated_initializer (d->cur, index);
       elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
@@ -5009,6 +5103,10 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
                              size_int (index), elt_init);
       if (!TREE_CONSTANT (elt_init))
        TREE_CONSTANT (new_init) = false;
+
+      /* This can happen with an invalid initializer (c++/54501).  */
+      if (d->cur == old_cur && !sized_array_p)
+       break;
     }
 
   return new_init;
@@ -5097,10 +5195,14 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
   while (d->cur != d->end)
     {
       tree field_init;
+      constructor_elt *old_cur = d->cur;
 
       /* Handle designated initializers, as an extension.  */
       if (d->cur->index)
        {
+         if (d->cur->index == error_mark_node)
+           return error_mark_node;
+
          if (TREE_CODE (d->cur->index) == INTEGER_CST)
            {
              if (complain & tf_error)
@@ -5109,7 +5211,11 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
              return error_mark_node;
            }
 
-         field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
+         if (TREE_CODE (d->cur->index) == FIELD_DECL)
+           /* We already reshaped this.  */
+           gcc_assert (d->cur->index == field);
+         else
+           field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
 
          if (!field || TREE_CODE (field) != FIELD_DECL)
            {
@@ -5129,6 +5235,15 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
       if (field_init == error_mark_node)
        return error_mark_node;
 
+      if (d->cur == old_cur && d->cur->index)
+       {
+         /* This can happen with an invalid initializer for a flexible
+            array member (c++/54441).  */
+         if (complain & tf_error)
+           error ("invalid initializer for %q#D", field);
+         return error_mark_node;
+       }
+
       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init);
 
       /* [dcl.init.aggr]
@@ -5199,7 +5314,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
        }
       else if (first_initializer_p && d->cur != d->end)
        {
-         VEC(constructor_elt, gc) *v = 0;
+         vec<constructor_elt, va_gc> *v = 0;
          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, d->cur->value);
          if (has_designator_problem (d, complain))
@@ -5251,7 +5366,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
         valid aggregate initialization.  */
       && !first_initializer_p
       && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))
-         || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL)))
+         || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL,
+                             complain)))
     {
       d->cur++;
       return init;
@@ -5272,10 +5388,9 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
         element (as allowed by [dcl.init.string]).  */
       if (!first_initializer_p
          && TREE_CODE (str_init) == CONSTRUCTOR
-         && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (str_init)) == 1)
+         && vec_safe_length (CONSTRUCTOR_ELTS (str_init)) == 1)
        {
-         str_init = VEC_index (constructor_elt,
-                               CONSTRUCTOR_ELTS (str_init), 0)->value;
+         str_init = (*CONSTRUCTOR_ELTS (str_init))[0].value;
        }
 
       /* If it's a string literal, then it's the initializer for the array
@@ -5343,15 +5458,15 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
      struct S { int a; int b; };
      struct S a[] = { 1, 2, 3, 4 };
 
-   Here INIT will hold a VEC of four elements, rather than a
-   VEC of two elements, each itself a VEC of two elements.  This
+   Here INIT will hold a vector of four elements, rather than a
+   vector of two elements, each itself a vector of two elements.  This
    routine transforms INIT from the former form into the latter.  The
    revised CONSTRUCTOR node is returned.  */
 
 tree
 reshape_init (tree type, tree init, tsubst_flags_t complain)
 {
-  VEC(constructor_elt, gc) *v;
+  vec<constructor_elt, va_gc> *v;
   reshape_iter d;
   tree new_init;
 
@@ -5361,12 +5476,12 @@ reshape_init (tree type, tree init, tsubst_flags_t complain)
 
   /* An empty constructor does not need reshaping, and it is always a valid
      initializer.  */
-  if (VEC_empty (constructor_elt, v))
+  if (vec_safe_is_empty (v))
     return init;
 
   /* Recurse on this CONSTRUCTOR.  */
-  d.cur = VEC_index (constructor_elt, v, 0);
-  d.end = d.cur + VEC_length (constructor_elt, v);
+  d.cur = &(*v)[0];
+  d.end = d.cur + v->length ();
 
   new_init = reshape_init_r (type, &d, true, complain);
   if (new_init == error_mark_node)
@@ -5436,7 +5551,7 @@ build_aggr_init_full_exprs (tree decl, tree init, int flags)
    evaluated dynamically to initialize DECL.  */
 
 static tree
-check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups)
+check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups)
 {
   tree type = TREE_TYPE (decl);
   tree init_code = NULL;
@@ -5476,7 +5591,7 @@ check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups)
 
   if (init && BRACE_ENCLOSED_INITIALIZER_P (init))
     {
-      int init_len = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init));
+      int init_len = vec_safe_length (CONSTRUCTOR_ELTS (init));
       if (SCALAR_TYPE_P (type))
        {
          if (init_len == 0)
@@ -5562,6 +5677,11 @@ check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups)
        {
          init_code = build_aggr_init_full_exprs (decl, init, flags);
 
+         /* A constructor call is a non-trivial initializer even if
+            it isn't explicitly written.  */
+         if (TREE_SIDE_EFFECTS (init_code))
+           DECL_NONTRIVIALLY_INITIALIZED_P (decl) = true;
+
          /* If this is a constexpr initializer, expand_default_init will
             have returned an INIT_EXPR rather than a CALL_EXPR.  In that
             case, pull the initializer back out and pass it down into
@@ -5589,7 +5709,7 @@ check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups)
                       && (!init || TREE_CODE (init) == TREE_LIST))
                {
                  init = build_functional_cast (type, init, tf_none);
-                 if (init != error_mark_node)
+                 if (TREE_CODE (init) == TARGET_EXPR)
                    TARGET_EXPR_DIRECT_INIT_P (init) = true;
                }
              init_code = NULL_TREE;
@@ -5878,7 +5998,7 @@ initialize_local_var (tree decl, tree init)
    back end.  */
 
 void
-initialize_artificial_var (tree decl, VEC(constructor_elt,gc) *v)
+initialize_artificial_var (tree decl, vec<constructor_elt, va_gc> *v)
 {
   tree init;
   gcc_assert (DECL_ARTIFICIAL (decl));
@@ -5904,15 +6024,14 @@ type_dependent_init_p (tree init)
   else if (TREE_CODE (init) == CONSTRUCTOR)
   /* A brace-enclosed initializer, e.g.: int i = { 3 }; ? */
     {
-      VEC(constructor_elt, gc) *elts;
+      vec<constructor_elt, va_gc> *elts;
       size_t nelts;
       size_t i;
 
       elts = CONSTRUCTOR_ELTS (init);
-      nelts = VEC_length (constructor_elt, elts);
+      nelts = vec_safe_length (elts);
       for (i = 0; i < nelts; ++i)
-       if (type_dependent_init_p (VEC_index (constructor_elt,
-                                             elts, i)->value))
+       if (type_dependent_init_p ((*elts)[i].value))
          return true;
     }
   else
@@ -5934,15 +6053,14 @@ value_dependent_init_p (tree init)
   else if (TREE_CODE (init) == CONSTRUCTOR)
   /* A brace-enclosed initializer, e.g.: int i = { 3 }; ? */
     {
-      VEC(constructor_elt, gc) *elts;
+      vec<constructor_elt, va_gc> *elts;
       size_t nelts;
       size_t i;
 
       elts = CONSTRUCTOR_ELTS (init);
-      nelts = VEC_length (constructor_elt, elts);
+      nelts = vec_safe_length (elts);
       for (i = 0; i < nelts; ++i)
-       if (value_dependent_init_p (VEC_index (constructor_elt,
-                                              elts, i)->value))
+       if (value_dependent_init_p ((*elts)[i].value))
          return true;
     }
   else
@@ -5968,7 +6086,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
                tree asmspec_tree, int flags)
 {
   tree type;
-  VEC(tree,gc) *cleanups = NULL;
+  vec<tree, va_gc> *cleanups = NULL;
   const char *asmspec = NULL;
   int was_readonly = 0;
   bool var_definition_p = false;
@@ -6004,12 +6122,22 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       && (DECL_INITIAL (decl) || init))
     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
-  auto_node = type_uses_auto (type);
-  if (auto_node)
+  if (TREE_CODE (decl) != FUNCTION_DECL
+      && (auto_node = type_uses_auto (type)))
     {
       tree d_init;
       if (init == NULL_TREE)
        {
+         if (DECL_LANG_SPECIFIC (decl)
+             && DECL_TEMPLATE_INSTANTIATION (decl)
+             && !DECL_TEMPLATE_INSTANTIATED (decl))
+           {
+             /* init is null because we're deferring instantiating the
+                initializer until we need it.  Well, we need it now.  */
+             instantiate_decl (decl, /*defer_ok*/true, /*expl*/false);
+             return;
+           }
+
          error ("declaration of %q#D has no initializer", decl);
          TREE_TYPE (decl) = error_mark_node;
          return;
@@ -6023,6 +6151,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
                                                   auto_node);
       if (type == error_mark_node)
        return;
+      cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
     }
 
   if (!ensure_literal_type_for_constexpr_object (decl))
@@ -6118,8 +6247,15 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          release_tree_vector (cleanups);
        }
       else if (!DECL_PRETTY_FUNCTION_P (decl))
-       /* Deduce array size even if the initializer is dependent.  */
-       maybe_deduce_size_from_array_init (decl, init);
+       {
+         /* Deduce array size even if the initializer is dependent.  */
+         maybe_deduce_size_from_array_init (decl, init);
+         /* And complain about multiple initializers.  */
+         if (init && TREE_CODE (init) == TREE_LIST && TREE_CHAIN (init)
+             && !MAYBE_CLASS_TYPE_P (type))
+           init = build_x_compound_expr_from_list (init, ELK_INIT,
+                                                   tf_warning_or_error);
+       }
 
       if (init)
        DECL_INITIAL (decl) = init;
@@ -6164,13 +6300,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (TREE_CODE (decl) == VAR_DECL)
     {
-      /* Only variables with trivial initialization and destruction can
-        have thread-local storage.  */
-      if (DECL_THREAD_LOCAL_P (decl)
-         && (type_has_nontrivial_default_init (TREE_TYPE (decl))
-             || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
-       error ("%qD cannot be thread-local because it has non-trivial "
-              "type %qT", decl, TREE_TYPE (decl));
       /* If this is a local variable that will need a mangled name,
         register it now.  We must do this before processing the
         initializer for the variable, since the initialization might
@@ -6187,7 +6316,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
            /* Normally local_decls is populated during GIMPLE lowering,
               but [cd]tors are never actually compiled directly.  We need
               to put statics on the list so we can deal with the label
-              address extension.  */
+              address extension.  FIXME.  */
            add_local_decl (cfun, decl);
        }
 
@@ -6216,13 +6345,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
            }
          cleanups = make_tree_vector ();
          init = check_initializer (decl, init, flags, &cleanups);
-         /* Thread-local storage cannot be dynamically initialized.  */
-         if (DECL_THREAD_LOCAL_P (decl) && init)
-           {
-             error ("%qD is thread-local and so cannot be dynamically "
-                    "initialized", decl);
-             init = NULL_TREE;
-           }
 
          /* Check that the initializer for a static data member was a
             constant.  Although we check in the parser that the
@@ -6387,7 +6509,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (cleanups)
     {
       unsigned i; tree t;
-      FOR_EACH_VEC_ELT (tree, cleanups, i, t)
+      FOR_EACH_VEC_ELT (*cleanups, i, t)
        push_cleanup (decl, t, false);
       release_tree_vector (cleanups);
     }
@@ -6500,7 +6622,6 @@ get_atexit_node (void)
       fn_type = build_function_type_list (integer_type_node,
                                          argtype0, argtype1, argtype2,
                                          NULL_TREE);
-      fn_ptr_type = build_pointer_type (fn_type);
       if (use_aeabi_atexit)
        name = "__aeabi_atexit";
       else
@@ -6526,11 +6647,29 @@ get_atexit_node (void)
   atexit_fndecl = build_library_fn_ptr (name, fn_type);
   mark_used (atexit_fndecl);
   pop_lang_context ();
-  atexit_node = decay_conversion (atexit_fndecl);
+  atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
 
   return atexit_node;
 }
 
+/* Like get_atexit_node, but for thread-local cleanups.  */
+
+static tree
+get_thread_atexit_node (void)
+{
+  /* The declaration for `__cxa_thread_atexit' is:
+
+     int __cxa_thread_atexit (void (*)(void *), void *, void *) */
+  tree fn_type = build_function_type_list (integer_type_node,
+                                          get_atexit_fn_ptr_type (),
+                                          ptr_type_node, ptr_type_node,
+                                          NULL_TREE);
+
+  /* Now, build the function declaration.  */
+  tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type);
+  return decay_conversion (atexit_fndecl, tf_warning_or_error);
+}
+
 /* Returns the __dso_handle VAR_DECL.  */
 
 static tree
@@ -6622,23 +6761,26 @@ tree
 register_dtor_fn (tree decl)
 {
   tree cleanup;
+  tree addr;
   tree compound_stmt;
   tree fcall;
   tree type;
-  bool use_dtor;
-  tree arg0, arg1 = NULL_TREE, arg2 = NULL_TREE;
+  bool ob_parm, dso_parm, use_dtor;
+  tree arg0, arg1, arg2;
+  tree atex_node;
 
   type = TREE_TYPE (decl);
   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
     return void_zero_node;
 
-  /* If we're using "__cxa_atexit" (or "__aeabi_atexit"), and DECL is
-     a class object, we can just pass the destructor to
-     "__cxa_atexit"; we don't have to build a temporary function to do
-     the cleanup.  */
-  use_dtor = (flag_use_cxa_atexit 
-             && !targetm.cxx.use_atexit_for_cxa_atexit ()
-             && CLASS_TYPE_P (type));
+  /* If we're using "__cxa_atexit" (or "__cxa_thread_atexit" or
+     "__aeabi_atexit"), and DECL is a class object, we can just pass the
+     destructor to "__cxa_atexit"; we don't have to build a temporary
+     function to do the cleanup.  */
+  dso_parm = (flag_use_cxa_atexit
+             && !targetm.cxx.use_atexit_for_cxa_atexit ());
+  ob_parm = (DECL_THREAD_LOCAL_P (decl) || dso_parm);
+  use_dtor = ob_parm && CLASS_TYPE_P (type);
   if (use_dtor)
     {
       int idx;
@@ -6646,9 +6788,10 @@ register_dtor_fn (tree decl)
       /* Find the destructor.  */
       idx = lookup_fnfields_1 (type, complete_dtor_identifier);
       gcc_assert (idx >= 0);
-      cleanup = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), idx);
+      cleanup = (*CLASSTYPE_METHOD_VEC (type))[idx];
       /* Make sure it is accessible.  */
-      perform_or_defer_access_check (TYPE_BINFO (type), cleanup, cleanup);
+      perform_or_defer_access_check (TYPE_BINFO (type), cleanup, cleanup,
+                                    tf_warning_or_error);
     }
   else
     {
@@ -6678,35 +6821,49 @@ register_dtor_fn (tree decl)
   /* Call atexit with the cleanup function.  */
   mark_used (cleanup);
   cleanup = build_address (cleanup);
-  if (flag_use_cxa_atexit && !targetm.cxx.use_atexit_for_cxa_atexit ())
+
+  if (DECL_THREAD_LOCAL_P (decl))
+    atex_node = get_thread_atexit_node ();
+  else
+    atex_node = get_atexit_node ();
+
+  if (use_dtor)
     {
-      tree addr;
+      /* We must convert CLEANUP to the type that "__cxa_atexit"
+        expects.  */
+      cleanup = build_nop (get_atexit_fn_ptr_type (), cleanup);
+      /* "__cxa_atexit" will pass the address of DECL to the
+        cleanup function.  */
+      mark_used (decl);
+      addr = build_address (decl);
+      /* The declared type of the parameter to "__cxa_atexit" is
+        "void *".  For plain "T*", we could just let the
+        machinery in cp_build_function_call convert it -- but if the
+        type is "cv-qualified T *", then we need to convert it
+        before passing it in, to avoid spurious errors.  */
+      addr = build_nop (ptr_type_node, addr);
+    }
+  else
+    /* Since the cleanup functions we build ignore the address
+       they're given, there's no reason to pass the actual address
+       in, and, in general, it's cheaper to pass NULL than any
+       other value.  */
+    addr = null_pointer_node;
+
+  if (dso_parm)
+    arg2 = cp_build_addr_expr (get_dso_handle_node (),
+                              tf_warning_or_error);
+  else if (ob_parm)
+    /* Just pass NULL to the dso handle parm if we don't actually
+       have a DSO handle on this target.  */
+    arg2 = null_pointer_node;
+  else
+    arg2 = NULL_TREE;
 
-      if (use_dtor)
-       {
-         /* We must convert CLEANUP to the type that "__cxa_atexit"
-            expects.  */
-         cleanup = build_nop (get_atexit_fn_ptr_type (), cleanup);
-         /* "__cxa_atexit" will pass the address of DECL to the
-            cleanup function.  */
-         mark_used (decl);
-         addr = build_address (decl);
-         /* The declared type of the parameter to "__cxa_atexit" is
-            "void *".  For plain "T*", we could just let the
-            machinery in cp_build_function_call convert it -- but if the
-            type is "cv-qualified T *", then we need to convert it
-            before passing it in, to avoid spurious errors.  */
-         addr = build_nop (ptr_type_node, addr);
-       }
-      else
-       /* Since the cleanup functions we build ignore the address
-          they're given, there's no reason to pass the actual address
-          in, and, in general, it's cheaper to pass NULL than any
-          other value.  */
-       addr = null_pointer_node;
-      arg2 = cp_build_addr_expr (get_dso_handle_node (),
-                                tf_warning_or_error);
-      if (targetm.cxx.use_aeabi_atexit ())
+  if (ob_parm)
+    {
+      if (!DECL_THREAD_LOCAL_P (decl)
+         && targetm.cxx.use_aeabi_atexit ())
        {
          arg1 = cleanup;
          arg0 = addr;
@@ -6718,8 +6875,11 @@ register_dtor_fn (tree decl)
        }
     }
   else
-    arg0 = cleanup;
-  return cp_build_function_call_nary (get_atexit_node (), tf_warning_or_error,
+    {
+      arg0 = cleanup;
+      arg1 = NULL_TREE;
+    }
+  return cp_build_function_call_nary (atex_node, tf_warning_or_error,
                                      arg0, arg1, arg2, NULL_TREE);
 }
 
@@ -6738,6 +6898,26 @@ expand_static_init (tree decl, tree init)
       && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
     return;
 
+  if (DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
+      && !DECL_FUNCTION_SCOPE_P (decl))
+    {
+      if (init)
+       error ("non-local variable %qD declared %<__thread%> "
+              "needs dynamic initialization", decl);
+      else
+       error ("non-local variable %qD declared %<__thread%> "
+              "has a non-trivial destructor", decl);
+      static bool informed;
+      if (!informed)
+       {
+         inform (DECL_SOURCE_LOCATION (decl),
+                 "C++11 %<thread_local%> allows dynamic initialization "
+                 "and destruction");
+         informed = true;
+       }
+      return;
+    }
+
   if (DECL_FUNCTION_SCOPE_P (decl))
     {
       /* Emit code to perform this initialization but once.  */
@@ -6745,6 +6925,9 @@ expand_static_init (tree decl, tree init)
       tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
       tree guard, guard_addr;
       tree flag, begin;
+      /* We don't need thread-safety code for thread-local vars.  */
+      bool thread_guard = (flag_threadsafe_statics
+                          && !DECL_THREAD_LOCAL_P (decl));
 
       /* Emit code to perform this initialization but once.  This code
         looks like:
@@ -6783,7 +6966,7 @@ expand_static_init (tree decl, tree init)
       /* This optimization isn't safe on targets with relaxed memory
         consistency.  On such targets we force synchronization in
         __cxa_guard_acquire.  */
-      if (!targetm.relaxed_ordering || !flag_threadsafe_statics)
+      if (!targetm.relaxed_ordering || !thread_guard)
        {
          /* Begin the conditional initialization.  */
          if_stmt = begin_if_stmt ();
@@ -6791,7 +6974,7 @@ expand_static_init (tree decl, tree init)
          then_clause = begin_compound_stmt (BCS_NO_SCOPE);
        }
 
-      if (flag_threadsafe_statics)
+      if (thread_guard)
        {
          tree vfntype = NULL_TREE;
          tree acquire_name, release_name, abort_name;
@@ -6849,20 +7032,22 @@ expand_static_init (tree decl, tree init)
 
       finish_expr_stmt (init);
 
-      if (flag_threadsafe_statics)
+      if (thread_guard)
        {
          finish_compound_stmt (inner_then_clause);
          finish_then_clause (inner_if_stmt);
          finish_if_stmt (inner_if_stmt);
        }
 
-      if (!targetm.relaxed_ordering || !flag_threadsafe_statics)
+      if (!targetm.relaxed_ordering || !thread_guard)
        {
          finish_compound_stmt (then_clause);
          finish_then_clause (if_stmt);
          finish_if_stmt (if_stmt);
        }
     }
+  else if (DECL_THREAD_LOCAL_P (decl))
+    tls_aggregates = tree_cons (init, decl, tls_aggregates);
   else
     static_aggregates = tree_cons (init, decl, static_aggregates);
 }
@@ -6891,13 +7076,13 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
         we should just call reshape_init here?  */
       if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
          && TREE_CODE (initial_value) == CONSTRUCTOR
-         && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (initial_value)))
+         && !vec_safe_is_empty (CONSTRUCTOR_ELTS (initial_value)))
        {
-         VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value);
-         tree value = VEC_index (constructor_elt, v, 0)->value;
+         vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (initial_value);
+         tree value = (*v)[0].value;
 
          if (TREE_CODE (value) == STRING_CST
-             && VEC_length (constructor_elt, v) == 1)
+             && v->length () == 1)
            initial_value = value;
        }
 
@@ -7151,6 +7336,7 @@ grokfndecl (tree ctype,
            int virtualp,
            enum overload_flags flags,
            cp_cv_quals quals,
+           cp_ref_qualifier rqual,
            tree raises,
            int check,
            int friendp,
@@ -7167,6 +7353,8 @@ grokfndecl (tree ctype,
   int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
   tree t;
 
+  if (rqual)
+    type = build_ref_qualified_type (type, rqual);
   if (raises)
     type = build_exception_variant (type, raises);
 
@@ -7308,7 +7496,7 @@ grokfndecl (tree ctype,
 
   if (ctype == NULL_TREE && DECL_MAIN_P (decl))
     {
-      if (processing_template_decl)
+      if (PROCESSING_REAL_TEMPLATE_DECL_P())
        error ("cannot declare %<::main%> to be a template");
       if (inlinep)
        error ("cannot declare %<::main%> to be inline");
@@ -7370,13 +7558,25 @@ grokfndecl (tree ctype,
     DECL_DECLARED_CONSTEXPR_P (decl) = true;
 
   DECL_EXTERNAL (decl) = 1;
-  if (quals && TREE_CODE (type) == FUNCTION_TYPE)
+  if (TREE_CODE (type) == FUNCTION_TYPE)
     {
-      error (ctype
-             ? G_("static member function %qD cannot have cv-qualifier")
-             : G_("non-member function %qD cannot have cv-qualifier"),
-            decl);
-      quals = TYPE_UNQUALIFIED;
+      if (quals)
+       {
+         error (ctype
+                ? G_("static member function %qD cannot have cv-qualifier")
+                : G_("non-member function %qD cannot have cv-qualifier"),
+                decl);
+         quals = TYPE_UNQUALIFIED;
+       }
+
+      if (rqual)
+       {
+         error (ctype
+                ? G_("static member function %qD cannot have ref-qualifier")
+                : G_("non-member function %qD cannot have ref-qualifier"),
+                decl);
+         rqual = REF_QUAL_NONE;
+       }
     }
 
   if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))
@@ -7406,13 +7606,13 @@ grokfndecl (tree ctype,
          suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl));
          if (long_long_unsigned_p)
            {
-             if (cpp_interpret_int_suffix (suffix, strlen (suffix)))
+             if (cpp_interpret_int_suffix (parse_in, suffix, strlen (suffix)))
                warning (0, "integer suffix %<%s%>"
                            " shadowed by implementation", suffix);
            }
          else if (long_double_p)
            {
-             if (cpp_interpret_float_suffix (suffix, strlen (suffix)))
+             if (cpp_interpret_float_suffix (parse_in, suffix, strlen (suffix)))
                warning (0, "floating point suffix %<%s%>"
                            " shadowed by implementation", suffix);
            }
@@ -7439,6 +7639,13 @@ grokfndecl (tree ctype,
   if (ctype != NULL_TREE)
     grokclassfn (ctype, decl, flags);
 
+  /* 12.4/3  */
+  if (cxx_dialect >= cxx0x
+      && DECL_DESTRUCTOR_P (decl)
+      && !TYPE_BEING_DEFINED (DECL_CONTEXT (decl))
+      && !processing_template_decl)
+    deduce_noexcept_on_destructor (decl);
+
   decl = check_explicit_specialization (orig_declarator, decl,
                                        template_count,
                                        2 * funcdef_flag +
@@ -7665,8 +7872,12 @@ grokvardecl (tree type,
       TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
     }
 
-  if (declspecs->specs[(int)ds_thread])
-    DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+  if (decl_spec_seq_has_spec_p (declspecs, ds_thread))
+    {
+      DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+      if (declspecs->gnu_thread_keyword_p)
+       DECL_GNU_TLS_P (decl) = true;
+    }
 
   /* If the type of the decl has no linkage, make sure that we'll
      notice that in mark_used.  */
@@ -7803,7 +8014,8 @@ build_ptrmem_type (tree class_type, tree member_type)
   if (TREE_CODE (member_type) == METHOD_TYPE)
     {
       cp_cv_quals quals = type_memfn_quals (member_type);
-      member_type = build_memfn_type (member_type, class_type, quals);
+      cp_ref_qualifier rqual = type_memfn_rqual (member_type);
+      member_type = build_memfn_type (member_type, class_type, quals, rqual);
       return build_ptrmemfunc_type (build_pointer_type (member_type));
     }
   else
@@ -7861,7 +8073,7 @@ check_static_variable_definition (tree decl, tree type)
           "static member %qD",
           decl);
   else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
-    pedwarn (input_location, OPT_pedantic, "ISO C++ forbids initialization of member constant "
+    pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids initialization of member constant "
             "%qD of non-integral type %qT", decl, type);
 
   return 0;
@@ -7898,6 +8110,36 @@ stabilize_vla_size (tree size)
   struct pointer_set_t *pset = pointer_set_create ();
   /* Break out any function calls into temporary variables.  */
   cp_walk_tree (&size, stabilize_save_expr_r, pset, pset);
+  pointer_set_destroy (pset);
+}
+
+/* Helper function for compute_array_index_type.  Look for SIZEOF_EXPR
+   not inside of SAVE_EXPR and fold them.  */
+
+static tree
+fold_sizeof_expr_r (tree *expr_p, int *walk_subtrees, void *data)
+{
+  tree expr = *expr_p;
+  if (TREE_CODE (expr) == SAVE_EXPR || TYPE_P (expr))
+    *walk_subtrees = 0;
+  else if (TREE_CODE (expr) == SIZEOF_EXPR)
+    {
+      *(bool *)data = true;
+      if (SIZEOF_EXPR_TYPE_P (expr))
+       expr = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (expr, 0)),
+                                          SIZEOF_EXPR, false);
+      else if (TYPE_P (TREE_OPERAND (expr, 0)))
+       expr = cxx_sizeof_or_alignof_type (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
+                                          false);
+      else
+        expr = cxx_sizeof_or_alignof_expr (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
+                                          false);
+      if (expr == error_mark_node)
+        expr = size_one_node;
+      *expr_p = expr;
+      *walk_subtrees = 0;
+    }
+  return NULL;
 }
 
 /* Given the SIZE (i.e., number of elements) in an array, compute an
@@ -7907,7 +8149,6 @@ stabilize_vla_size (tree size)
 tree
 compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
 {
-  tree type;
   tree itype;
   tree osize = size;
   tree abi_1_itype = NULL_TREE;
@@ -7915,10 +8156,10 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
   if (error_operand_p (size))
     return error_mark_node;
 
-  type = TREE_TYPE (size);
-  /* type_dependent_expression_p? */
-  if (!dependent_type_p (type))
+  if (!type_dependent_expression_p (size))
     {
+      tree type = TREE_TYPE (size);
+
       mark_rvalue_use (size);
 
       if (cxx_dialect < cxx0x && TREE_CODE (size) == NOP_EXPR
@@ -7927,7 +8168,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
           NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case.  */;
       else
        {
-         size = fold_non_dependent_expr (size);
+         size = fold_non_dependent_expr_sfinae (size, complain);
 
          if (CLASS_TYPE_P (type)
              && CLASSTYPE_LITERAL_P (type))
@@ -7980,7 +8221,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
   /* We can only call value_dependent_expression_p on integral constant
      expressions; treat non-constant expressions as dependent, too.  */
   if (processing_template_decl
-      && (dependent_type_p (type)
+      && (type_dependent_expression_p (size)
          || !TREE_CONSTANT (size) || value_dependent_expression_p (size)))
     {
       /* We cannot do any checking for a SIZE that isn't known to be
@@ -8034,9 +8275,9 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
          else if (in_system_header)
            /* Allow them in system headers because glibc uses them.  */;
          else if (name)
-           pedwarn (input_location, OPT_pedantic, "ISO C++ forbids zero-size array %qD", name);
+           pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array %qD", name);
          else
-           pedwarn (input_location, OPT_pedantic, "ISO C++ forbids zero-size array");
+           pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array");
        }
     }
   else if (TREE_CONSTANT (size)
@@ -8086,15 +8327,29 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
       processing_template_decl = 0;
       itype = cp_build_binary_op (input_location,
                                  MINUS_EXPR,
-                                 cp_convert (ssizetype, size),
-                                 cp_convert (ssizetype, integer_one_node),
-                                 tf_warning_or_error);
+                                 cp_convert (ssizetype, size, complain),
+                                 cp_convert (ssizetype, integer_one_node,
+                                             complain),
+                                 complain);
       itype = fold (itype);
       processing_template_decl = saved_processing_template_decl;
 
       if (!TREE_CONSTANT (itype))
-       /* A variable sized array.  */
-       itype = variable_size (itype);
+       {
+         /* A variable sized array.  */
+         itype = variable_size (itype);
+         if (TREE_CODE (itype) != SAVE_EXPR)
+           {
+             /* Look for SIZEOF_EXPRs in itype and fold them, otherwise
+                they might survive till gimplification.  */
+             tree newitype = itype;
+             bool found = false;
+             cp_walk_tree_without_duplicates (&newitype,
+                                              fold_sizeof_expr_r, &found);
+             if (found)
+               itype = variable_size (fold (newitype));
+           }
+       }
       /* Make sure that there was no overflow when creating to a signed
         index type.  (For example, on a 32-bit machine, an array with
         size 2^32 - 1 is too big.)  */
@@ -8162,7 +8417,7 @@ create_array_type_for_decl (tree name, tree type, tree size)
   /* 8.3.4/1: If the type of the identifier of D contains the auto
      type-specifier, the program is ill-formed.  */
   if (pedantic && type_uses_auto (type))
-    pedwarn (input_location, OPT_pedantic,
+    pedwarn (input_location, OPT_Wpedantic,
             "declaration of %qD as array of %<auto%>", name);
 
   /* If there are some types which cannot be array elements,
@@ -8318,7 +8573,7 @@ reset_type_linkage (tree type)
     binding_table_foreach (CLASSTYPE_NESTED_UTDS (type), bt_reset_linkage, NULL);
 }
 static void
-bt_reset_linkage (binding_entry b, void *data ATTRIBUTE_UNUSED)
+bt_reset_linkage (binding_entry b, void */*data*/)
 {
   reset_type_linkage (b->type);
 }
@@ -8370,7 +8625,7 @@ bt_reset_linkage (binding_entry b, void *data ATTRIBUTE_UNUSED)
 
 tree
 grokdeclarator (const cp_declarator *declarator,
-               const cp_decl_specifier_seq *declspecs,
+               cp_decl_specifier_seq *declspecs,
                enum decl_context decl_context,
                int initialized,
                tree* attrlist)
@@ -8382,7 +8637,6 @@ grokdeclarator (const cp_declarator *declarator,
   int explicit_int = 0;
   int explicit_char = 0;
   int defaulted_int = 0;
-  tree dependent_name = NULL_TREE;
 
   tree typedef_decl = NULL_TREE;
   const char *name = NULL;
@@ -8410,6 +8664,9 @@ grokdeclarator (const cp_declarator *declarator,
   /* virt-specifiers that apply to the declarator, for a declaration of
      a member function.  */
   cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
+  /* ref-qualifier that applies to the declarator, for a declaration of
+     a member function.  */
+  cp_ref_qualifier rqual = REF_QUAL_NONE;
   /* cv-qualifiers that apply to the type specified by the DECLSPECS.  */
   int type_quals;
   tree raises = NULL_TREE;
@@ -8436,16 +8693,16 @@ grokdeclarator (const cp_declarator *declarator,
   bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
   bool template_type_arg = false;
   bool template_parm_flag = false;
-  bool constexpr_p = declspecs->specs[(int) ds_constexpr];
+  bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
   const char *errmsg;
 
-  signed_p = declspecs->specs[(int)ds_signed];
-  unsigned_p = declspecs->specs[(int)ds_unsigned];
-  short_p = declspecs->specs[(int)ds_short];
-  long_p = declspecs->specs[(int)ds_long];
-  longlong = declspecs->specs[(int)ds_long] >= 2;
+  signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
+  unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned);
+  short_p = decl_spec_seq_has_spec_p (declspecs, ds_short);
+  long_p = decl_spec_seq_has_spec_p (declspecs, ds_long);
+  longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long);
   explicit_int128 = declspecs->explicit_int128_p;
-  thread_p = declspecs->specs[(int)ds_thread];
+  thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);
 
   if (decl_context == FUNCDEF)
     funcdef_flag = true, decl_context = NORMAL;
@@ -8520,7 +8777,7 @@ grokdeclarator (const cp_declarator *declarator,
                      }
                    else if (innermost_code != cdk_function
                             && current_class_type
-                            && !UNIQUELY_DERIVED_FROM_P (ctype,
+                            && !uniquely_derived_from_p (ctype,
                                                          current_class_type))
                      {
                        error ("type %qT is not derived from type %qT",
@@ -8646,7 +8903,7 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (dname && IDENTIFIER_OPNAME_P (dname))
     {
-      if (declspecs->specs[(int)ds_typedef])
+      if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
        {
          error ("declaration of %qD as %<typedef%>", dname);
          return error_mark_node;
@@ -8684,7 +8941,7 @@ grokdeclarator (const cp_declarator *declarator,
   if (name == NULL)
     name = decl_context == PARM ? "parameter" : "type name";
 
-  if (constexpr_p && declspecs->specs[(int)ds_typedef])
+  if (constexpr_p && decl_spec_seq_has_spec_p (declspecs, ds_typedef))
     {
       error ("%<constexpr%> cannot appear in a typedef declaration");
       return error_mark_node;
@@ -8774,7 +9031,7 @@ grokdeclarator (const cp_declarator *declarator,
       else if (! is_main)
        permerror (input_location, "ISO C++ forbids declaration of %qs with no type", name);
       else if (pedantic)
-       pedwarn (input_location, OPT_pedantic,
+       pedwarn (input_location, OPT_Wpedantic,
                 "ISO C++ forbids declaration of %qs with no type", name);
       else
        warning (OPT_Wreturn_type,
@@ -8793,7 +9050,7 @@ grokdeclarator (const cp_declarator *declarator,
          explicit_int128 = false;
        }
       else if (pedantic && ! in_system_header)
-       pedwarn (input_location, OPT_pedantic,
+       pedwarn (input_location, OPT_Wpedantic,
                 "ISO C++ does not support %<__int128%> for %qs", name);
     }
 
@@ -8844,7 +9101,7 @@ grokdeclarator (const cp_declarator *declarator,
          ok = 1;
          if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic)
            {
-             pedwarn (input_location, OPT_pedantic, 
+             pedwarn (input_location, OPT_Wpedantic, 
                       "long, short, signed or unsigned used invalidly for %qs",
                       name);
              if (flag_pedantic_errors)
@@ -8910,7 +9167,7 @@ grokdeclarator (const cp_declarator *declarator,
   else if (short_p)
     type = short_integer_type_node;
 
-  if (declspecs->specs[(int)ds_complex])
+  if (decl_spec_seq_has_spec_p (declspecs, ds_complex))
     {
       if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
        error ("complex invalid for %qs", name);
@@ -8934,16 +9191,27 @@ grokdeclarator (const cp_declarator *declarator,
     }
 
   type_quals = TYPE_UNQUALIFIED;
-  if (declspecs->specs[(int)ds_const])
+  if (decl_spec_seq_has_spec_p (declspecs, ds_const))
     type_quals |= TYPE_QUAL_CONST;
-  if (declspecs->specs[(int)ds_volatile])
+  if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
     type_quals |= TYPE_QUAL_VOLATILE;
-  if (declspecs->specs[(int)ds_restrict])
+  if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
     type_quals |= TYPE_QUAL_RESTRICT;
   if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED)
     error ("qualifiers are not allowed on declaration of %<operator %T%>",
           ctor_return_type);
 
+  /* If we're using the injected-class-name to form a compound type or a
+     declaration, replace it with the underlying class so we don't get
+     redundant typedefs in the debug output.  But if we are returning the
+     type unchanged, leave it alone so that it's available to
+     maybe_get_template_decl_from_type_decl.  */
+  if (CLASS_TYPE_P (type)
+      && DECL_SELF_REFERENCE_P (TYPE_NAME (type))
+      && type == TREE_TYPE (TYPE_NAME (type))
+      && (declarator || type_quals))
+    type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
+
   type_quals |= cp_type_quals (type);
   type = cp_build_qualified_type_real
     (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
@@ -8952,9 +9220,9 @@ grokdeclarator (const cp_declarator *declarator,
   type_quals = cp_type_quals (type);
 
   staticp = 0;
-  inlinep = !! declspecs->specs[(int)ds_inline];
-  virtualp = !! declspecs->specs[(int)ds_virtual];
-  explicitp = !! declspecs->specs[(int)ds_explicit];
+  inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline);
+  virtualp =  decl_spec_seq_has_spec_p (declspecs, ds_virtual);
+  explicitp = decl_spec_seq_has_spec_p (declspecs, ds_explicit);
 
   storage_class = declspecs->storage_class;
   if (storage_class == sc_static)
@@ -8966,18 +9234,12 @@ grokdeclarator (const cp_declarator *declarator,
       storage_class = sc_none;
       staticp = 0;
     }
-  friendp = !! declspecs->specs[(int)ds_friend];
-
-  if (dependent_name && !friendp)
-    {
-      error ("%<%T::%D%> is not a valid declarator", ctype, dependent_name);
-      return error_mark_node;
-    }
+  friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
 
   /* Issue errors about use of storage classes for parameters.  */
   if (decl_context == PARM)
     {
-      if (declspecs->specs[(int)ds_typedef])
+      if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
        {
          error ("typedef declaration invalid in parameter declaration");
          return error_mark_node;
@@ -9021,7 +9283,7 @@ grokdeclarator (const cp_declarator *declarator,
       && ((storage_class
           && storage_class != sc_extern
           && storage_class != sc_static)
-         || declspecs->specs[(int)ds_typedef]))
+         || decl_spec_seq_has_spec_p (declspecs, ds_typedef)))
     {
       error ("multiple storage classes in declaration of %qs", name);
       thread_p = false;
@@ -9035,7 +9297,7 @@ grokdeclarator (const cp_declarator *declarator,
          && (storage_class == sc_register
              || storage_class == sc_auto))
        ;
-      else if (declspecs->specs[(int)ds_typedef])
+      else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
        ;
       else if (decl_context == FIELD
               /* C++ allows static class elements.  */
@@ -9073,9 +9335,15 @@ grokdeclarator (const cp_declarator *declarator,
           && storage_class != sc_extern
           && storage_class != sc_static)
     {
-      error ("function-scope %qs implicitly auto and declared %<__thread%>",
-            name);
-      thread_p = false;
+      if (declspecs->gnu_thread_keyword_p)
+       pedwarn (input_location, 0, "function-scope %qs implicitly auto and "
+                "declared %<__thread%>", name);
+
+      /* When thread_local is applied to a variable of block scope the
+        storage-class-specifier static is implied if it does not appear
+        explicitly.  */
+      storage_class = declspecs->storage_class = sc_static;
+      staticp = 1;
     }
 
   if (storage_class && friendp)
@@ -9107,6 +9375,15 @@ grokdeclarator (const cp_declarator *declarator,
        }
     }
 
+  if (declspecs->std_attributes)
+    {
+      /* Apply the c++11 attributes to the type preceding them.  */
+      source_location saved_loc = input_location;
+      input_location = declspecs->locations[ds_std_attribute];
+      decl_attributes (&type, declspecs->std_attributes, 0);
+      input_location = saved_loc;
+    }
+
   /* Determine the type of the entity declared by recurring on the
      declarator.  */
   for (; declarator; declarator = declarator->declarator)
@@ -9144,6 +9421,13 @@ grokdeclarator (const cp_declarator *declarator,
        case cdk_array:
          type = create_array_type_for_decl (dname, type,
                                             declarator->u.array.bounds);
+         if (declarator->std_attributes)
+           /* [dcl.array]/1:
+
+              The optional attribute-specifier-seq appertains to the
+              array.  */
+           returned_attrs = chainon (returned_attrs,
+                                     declarator->std_attributes);
          break;
 
        case cdk_function:
@@ -9182,11 +9466,18 @@ grokdeclarator (const cp_declarator *declarator,
                error ("%qs declared as function returning an array", name);
                return error_mark_node;
              }
+           /* When decl_context == NORMAL we emit a better error message
+              later in abstract_virtuals_error.  */
+           if (decl_context == TYPENAME && ABSTRACT_CLASS_TYPE_P (type))
+             error ("%qs declared as function returning an abstract "
+                    "class type", name);
 
            /* Pick up type qualifiers which should be applied to `this'.  */
            memfn_quals = declarator->u.function.qualifiers;
            /* Pick up virt-specifiers.  */
             virt_specifiers = declarator->u.function.virt_specifiers;
+           /* And ref-qualifier, too */
+           rqual = declarator->u.function.ref_qualifier;
            /* Pick up the exception specifications.  */
            raises = declarator->u.function.exception_specification;
            /* If the exception-specification is ill-formed, let's pretend
@@ -9205,9 +9496,13 @@ grokdeclarator (const cp_declarator *declarator,
                  {
                    if (!declarator->u.function.late_return_type)
                      {
-                       error ("%qs function uses %<auto%> type specifier without"
-                              " trailing return type", name);
-                       return error_mark_node;
+                       if (current_class_type
+                           && LAMBDA_TYPE_P (current_class_type))
+                         /* OK for C++11 lambdas.  */;
+                       else if (cxx_dialect < cxx1y)
+                         pedwarn (input_location, 0, "%qs function uses "
+                                  "%<auto%> type specifier without trailing "
+                                  "return type", name);
                      }
                    else if (!is_auto (type))
                      {
@@ -9250,12 +9545,13 @@ grokdeclarator (const cp_declarator *declarator,
                   therefore returns a void type.  */
 
                /* ISO C++ 12.4/2.  A destructor may not be declared
-                  const or volatile.  A destructor may not be
-                  static.
+                  const or volatile.  A destructor may not be static.
+                  A destructor may not be declared with ref-qualifier.
 
                   ISO C++ 12.1.  A constructor may not be declared
                   const or volatile.  A constructor may not be
-                  virtual.  A constructor may not be static.  */
+                  virtual.  A constructor may not be static.
+                  A constructor may not be declared with ref-qualifier. */
                if (staticp == 2)
                  error ((flags == DTOR_FLAG)
                         ? G_("destructor cannot be static member function")
@@ -9268,6 +9564,15 @@ grokdeclarator (const cp_declarator *declarator,
                    memfn_quals = TYPE_UNQUALIFIED;
                  }
 
+               if (rqual)
+                 {
+                   maybe_warn_cpp0x (CPP0X_REF_QUALIFIER);
+                   error ((flags == DTOR_FLAG)
+                          ? "destructors may not be ref-qualified"
+                          : "constructors may not be ref-qualified");
+                   rqual = REF_QUAL_NONE;
+                 }
+
                if (decl_context == FIELD
                    && !member_function_or_else (ctype,
                                                 current_class_type,
@@ -9331,6 +9636,13 @@ grokdeclarator (const cp_declarator *declarator,
              }
 
            type = build_function_type (type, arg_types);
+           if (declarator->std_attributes)
+             /* [dcl.fct]/2:
+
+                The optional attribute-specifier-seq appertains to
+                the function type.  */
+             decl_attributes (&type, declarator->std_attributes,
+                              0);
          }
          break;
 
@@ -9380,14 +9692,18 @@ grokdeclarator (const cp_declarator *declarator,
              memfn_quals |= type_memfn_quals (type);
              type = build_memfn_type (type,
                                       declarator->u.pointer.class_type,
-                                      memfn_quals);
+                                      memfn_quals,
+                                      rqual);
              if (type == error_mark_node)
                return error_mark_node;
+
+             rqual = REF_QUAL_NONE;
              memfn_quals = TYPE_UNQUALIFIED;
            }
 
          if (TREE_CODE (type) == FUNCTION_TYPE
-             && type_memfn_quals (type) != TYPE_UNQUALIFIED)
+             && (type_memfn_quals (type) != TYPE_UNQUALIFIED
+                 || type_memfn_rqual (type) != REF_QUAL_NONE))
             error (declarator->kind == cdk_reference
                    ? G_("cannot declare reference to qualified function type %qT")
                    : G_("cannot declare pointer to qualified function type %qT"),
@@ -9493,6 +9809,17 @@ grokdeclarator (const cp_declarator *declarator,
                                           declarator->u.pointer.qualifiers);
              type_quals = cp_type_quals (type);
            }
+
+         /* Apply C++11 attributes to the pointer, and not to the
+            type pointed to.  This is unlike what is done for GNU
+            attributes above.  It is to comply with [dcl.ptr]/1:
+
+                [the optional attribute-specifier-seq (7.6.1) appertains
+                 to the pointer and not to the object pointed to].  */
+         if (declarator->std_attributes)
+           decl_attributes (&type, declarator->std_attributes,
+                            0);
+
          ctype = NULL_TREE;
          break;
 
@@ -9545,36 +9872,9 @@ grokdeclarator (const cp_declarator *declarator,
       && declarator->u.id.qualifying_scope
       && MAYBE_CLASS_TYPE_P (declarator->u.id.qualifying_scope))
     {
-      tree t;
-
       ctype = declarator->u.id.qualifying_scope;
       ctype = TYPE_MAIN_VARIANT (ctype);
-      t = ctype;
-      while (t != NULL_TREE && CLASS_TYPE_P (t))
-       {
-         /* You're supposed to have one `template <...>' for every
-            template class, but you don't need one for a full
-            specialization.  For example:
-
-              template <class T> struct S{};
-              template <> struct S<int> { void f(); };
-              void S<int>::f () {}
-
-            is correct; there shouldn't be a `template <>' for the
-            definition of `S<int>::f'.  */
-         if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
-             && !any_dependent_template_arguments_p (CLASSTYPE_TI_ARGS (t)))
-           /* T is an explicit (not partial) specialization.  All
-              containing classes must therefore also be explicitly
-              specialized.  */
-           break;
-         if ((CLASSTYPE_USE_TEMPLATE (t) || CLASSTYPE_IS_TEMPLATE (t))
-             && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
-           template_count += 1;
-
-         t = TYPE_MAIN_DECL (t);
-         t = DECL_CONTEXT (t);
-       }
+      template_count = num_template_headers_for_class (ctype);
 
       if (ctype == current_class_type)
        {
@@ -9623,7 +9923,7 @@ grokdeclarator (const cp_declarator *declarator,
              return error_mark_node;
            }
        }
-      else if (declspecs->specs[(int)ds_typedef]
+      else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)
               && current_class_type)
        {
          error ("cannot declare member %<%T::%s%> within %qT",
@@ -9645,6 +9945,13 @@ grokdeclarator (const cp_declarator *declarator,
        attrlist = &returned_attrs;
     }
 
+  if (declarator
+      && declarator->kind == cdk_id
+      && declarator->std_attributes)
+    /* [dcl.meaning]/1: The optional attribute-specifier-seq following
+       a declarator-id appertains to the entity that is declared.  */
+    *attrlist = chainon (*attrlist, declarator->std_attributes);
+
   /* Handle parameter packs. */
   if (parameter_pack_p)
     {
@@ -9655,12 +9962,12 @@ grokdeclarator (const cp_declarator *declarator,
         error ("non-parameter %qs cannot be a parameter pack", name);
     }
 
-  /* Did array size calculations overflow?  */
-
+  /* Did array size calculations overflow or does the array cover more
+     than half of the address-space?  */
   if (TREE_CODE (type) == ARRAY_TYPE
       && COMPLETE_TYPE_P (type)
       && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
-      && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
+      && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
     {
       error ("size of array %qs is too large", name);
       /* If we proceed with the array type as it is, we'll eventually
@@ -9694,7 +10001,8 @@ grokdeclarator (const cp_declarator *declarator,
          error ("non-member %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
        }
-      else if (decl_context == TYPENAME || declspecs->specs[(int)ds_typedef])
+      else if (decl_context == TYPENAME
+              || decl_spec_seq_has_spec_p (declspecs, ds_typedef))
        {
          error ("non-object member %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
@@ -9724,7 +10032,7 @@ grokdeclarator (const cp_declarator *declarator,
     }
 
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
-  if (declspecs->specs[(int)ds_typedef] && decl_context != TYPENAME)
+  if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) && decl_context != TYPENAME)
     {
       tree decl;
 
@@ -9742,12 +10050,13 @@ grokdeclarator (const cp_declarator *declarator,
         example "f S::*" declares a pointer to a const-qualified
         member function of S.  We record the cv-qualification in the
         function type.  */
-      if (memfn_quals && TREE_CODE (type) == FUNCTION_TYPE)
+      if ((rqual || memfn_quals) && TREE_CODE (type) == FUNCTION_TYPE)
         {
-          type = apply_memfn_quals (type, memfn_quals);
+          type = apply_memfn_quals (type, memfn_quals, rqual);
           
           /* We have now dealt with these qualifiers.  */
           memfn_quals = TYPE_UNQUALIFIED;
+         rqual = REF_QUAL_NONE;
         }
 
       if (type_uses_auto (type))
@@ -9779,7 +10088,8 @@ grokdeclarator (const cp_declarator *declarator,
               clones.  */
            DECL_ABSTRACT (decl) = 1;
        }
-      else if (constructor_name_p (unqualified_id, current_class_type))
+      else if (current_class_type
+              && constructor_name_p (unqualified_id, current_class_type))
        permerror (input_location, "ISO C++ forbids nested type %qD with same name "
                   "as enclosing class",
                   unqualified_id);
@@ -9835,7 +10145,7 @@ grokdeclarator (const cp_declarator *declarator,
                      memfn_quals != TYPE_UNQUALIFIED,
                      inlinep, friendp, raises != NULL_TREE);
 
-      if (declspecs->specs[(int)ds_alias])
+      if (decl_spec_seq_has_spec_p (declspecs, ds_alias))
        /* Acknowledge that this was written:
             `using analias = atype;'.  */
        TYPE_DECL_ALIAS_P (decl) = 1;
@@ -9876,8 +10186,10 @@ grokdeclarator (const cp_declarator *declarator,
       if (decl_context != TYPENAME)
        {
          /* A cv-qualifier-seq shall only be part of the function type
-            for a non-static member function. [8.3.5/4 dcl.fct] */
-         if (type_memfn_quals (type) != TYPE_UNQUALIFIED
+            for a non-static member function. A ref-qualifier shall only
+            .... /same as above/ [dcl.fct] */
+         if ((type_memfn_quals (type) != TYPE_UNQUALIFIED
+              || type_memfn_rqual (type) != REF_QUAL_NONE)
              && (current_class_type == NULL_TREE || staticp) )
            {
              error (staticp
@@ -9891,6 +10203,7 @@ grokdeclarator (const cp_declarator *declarator,
          /* The qualifiers on the function type become the qualifiers on
             the non-static member function. */
          memfn_quals |= type_memfn_quals (type);
+         rqual = type_memfn_rqual (type);
          type_quals = TYPE_UNQUALIFIED;
        }
     }
@@ -9948,17 +10261,19 @@ grokdeclarator (const cp_declarator *declarator,
              type = void_type_node;
            }
        }
-      else if (memfn_quals)
+      else if (memfn_quals || rqual)
        {
          if (ctype == NULL_TREE
              && TREE_CODE (type) == METHOD_TYPE)
            ctype = TYPE_METHOD_BASETYPE (type);
 
          if (ctype)
-           type = build_memfn_type (type, ctype, memfn_quals);
-         /* Core issue #547: need to allow this in template type args.  */
-         else if (template_type_arg && TREE_CODE (type) == FUNCTION_TYPE)
-           type = apply_memfn_quals (type, memfn_quals);
+           type = build_memfn_type (type, ctype, memfn_quals, rqual);
+         /* Core issue #547: need to allow this in template type args.
+            Allow it in general in C++11 for alias-declarations.  */
+         else if ((template_type_arg || cxx_dialect >= cxx11)
+                  && TREE_CODE (type) == FUNCTION_TYPE)
+           type = apply_memfn_quals (type, memfn_quals, rqual);
          else
            error ("invalid qualifiers on non-member function type");
        }
@@ -10027,7 +10342,7 @@ grokdeclarator (const cp_declarator *declarator,
       cp_cv_quals real_quals = memfn_quals;
       if (constexpr_p && sfk != sfk_constructor && sfk != sfk_destructor)
        real_quals |= TYPE_QUAL_CONST;
-      type = build_memfn_type (type, ctype, real_quals);
+      type = build_memfn_type (type, ctype, real_quals, rqual);
     }
 
   {
@@ -10043,7 +10358,8 @@ grokdeclarator (const cp_declarator *declarator,
       }
     else if (decl_context == FIELD)
       {
-       if (!staticp && type_uses_auto (type))
+       if (!staticp && TREE_CODE (type) != METHOD_TYPE
+           && type_uses_auto (type))
          {
            error ("non-static data member declared %<auto%>");
            type = error_mark_node;
@@ -10158,7 +10474,7 @@ grokdeclarator (const cp_declarator *declarator,
                               ? unqualified_id : dname,
                               parms,
                               unqualified_id,
-                              virtualp, flags, memfn_quals, raises,
+                              virtualp, flags, memfn_quals, rqual, raises,
                               friendp ? -1 : 0, friendp, publicp,
                                inlinep | (2 * constexpr_p),
                               sfk,
@@ -10248,7 +10564,8 @@ grokdeclarator (const cp_declarator *declarator,
              {
                /* C++ allows static class members.  All other work
                   for this is done by grokfield.  */
-               decl = build_lang_decl (VAR_DECL, unqualified_id, type);
+               decl = build_lang_decl_loc (declarator->id_loc,
+                                           VAR_DECL, unqualified_id, type);
                set_linkage_for_static_data_member (decl);
                /* Even if there is an in-class initialization, DECL
                   is considered undefined until an out-of-class
@@ -10256,7 +10573,11 @@ grokdeclarator (const cp_declarator *declarator,
                DECL_EXTERNAL (decl) = 1;
 
                if (thread_p)
-                 DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+                 {
+                   DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+                   if (declspecs->gnu_thread_keyword_p)
+                     DECL_GNU_TLS_P (decl) = true;
+                 }
 
                if (constexpr_p && !initialized)
                  {
@@ -10323,7 +10644,14 @@ grokdeclarator (const cp_declarator *declarator,
        else if (storage_class == sc_register)
          error ("storage class %<register%> invalid for function %qs", name);
        else if (thread_p)
-         error ("storage class %<__thread%> invalid for function %qs", name);
+         {
+           if (declspecs->gnu_thread_keyword_p)
+             error ("storage class %<__thread%> invalid for function %qs",
+                    name);
+           else
+             error ("storage class %<thread_local%> invalid for function %qs",
+                    name);
+         }
 
         if (virt_specifiers)
           error ("virt-specifiers in %qs not allowed outside a class definition", name);
@@ -10332,15 +10660,15 @@ grokdeclarator (const cp_declarator *declarator,
           and `extern' makes no difference.  */
        if (! toplevel_bindings_p ()
            && (storage_class == sc_static
-               || declspecs->specs[(int)ds_inline])
+               || decl_spec_seq_has_spec_p (declspecs, ds_inline))
            && pedantic)
          {
            if (storage_class == sc_static)
-             pedwarn (input_location, OPT_pedantic, 
+             pedwarn (input_location, OPT_Wpedantic, 
                       "%<static%> specified invalid for function %qs "
                       "declared out of global scope", name);
            else
-             pedwarn (input_location, OPT_pedantic, 
+             pedwarn (input_location, OPT_Wpedantic, 
                       "%<inline%> specifier invalid for function %qs "
                       "declared out of global scope", name);
          }
@@ -10362,13 +10690,12 @@ grokdeclarator (const cp_declarator *declarator,
              }
          }
 
-       /* Record presence of `static'.  */
+       /* Record whether the function is public.  */
        publicp = (ctype != NULL_TREE
-                  || storage_class == sc_extern
                   || storage_class != sc_static);
 
        decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
-                          virtualp, flags, memfn_quals, raises,
+                          virtualp, flags, memfn_quals, rqual, raises,
                           1, friendp,
                           publicp, inlinep | (2 * constexpr_p), sfk,
                            funcdef_flag,
@@ -10434,7 +10761,7 @@ grokdeclarator (const cp_declarator *declarator,
              }
            if (storage_class == sc_extern && pedantic)
              {
-               pedwarn (input_location, OPT_pedantic, 
+               pedwarn (input_location, OPT_Wpedantic, 
                         "cannot explicitly declare member %q#D to have "
                         "extern linkage", decl);
                storage_class = sc_none;
@@ -10534,7 +10861,7 @@ local_variable_p (const_tree t)
 
 static tree
 local_variable_p_walkfn (tree *tp, int *walk_subtrees,
-                        void *data ATTRIBUTE_UNUSED)
+                        void * /*data*/)
 {
   if (local_variable_p (*tp)
       && (!DECL_ARTIFICIAL (*tp) || DECL_NAME (*tp) == this_identifier))
@@ -10582,29 +10909,16 @@ check_default_argument (tree decl, tree arg)
 
      A default argument expression is implicitly converted to the
      parameter type.  */
-  if (!TREE_TYPE (arg)
-      || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL))
-    {
-      if (decl)
-       error ("default argument for %q#D has type %qT",
-              decl, TREE_TYPE (arg));
-      else
-       error ("default argument for parameter of type %qT has type %qT",
-              decl_type, TREE_TYPE (arg));
-
-      return error_mark_node;
-    }
+  ++cp_unevaluated_operand;
+  perform_implicit_conversion_flags (decl_type, arg, tf_warning_or_error,
+                                    LOOKUP_IMPLICIT);
+  --cp_unevaluated_operand;
 
   if (warn_zero_as_null_pointer_constant
-      && c_inhibit_evaluation_warnings == 0
-      && (TYPE_PTR_P (decl_type) || TYPE_PTR_TO_MEMBER_P (decl_type))
+      && TYPE_PTR_OR_PTRMEM_P (decl_type)
       && null_ptr_cst_p (arg)
-      && !NULLPTR_TYPE_P (TREE_TYPE (arg)))
-    {
-      warning (OPT_Wzero_as_null_pointer_constant,
-              "zero as null pointer constant");
-      return nullptr_node;
-    }
+      && maybe_warn_zero_as_null_pointer_constant (arg, input_location))
+    return nullptr_node;
 
   /* [dcl.fct.default]
 
@@ -11412,7 +11726,7 @@ grok_op_properties (tree decl, bool complain)
            if (operator_code == POSTINCREMENT_EXPR
                || operator_code == POSTDECREMENT_EXPR)
              {
-               pedwarn (input_location, OPT_pedantic, "%qD cannot have default arguments", 
+               pedwarn (input_location, OPT_Wpedantic, "%qD cannot have default arguments", 
                         decl);
              }
            else
@@ -11479,9 +11793,10 @@ check_elaborated_type_specifier (enum tag_types tag_code,
             type, tag_name (tag_code));
       return error_mark_node;
     }
-  /* Accept bound template template parameters.  */
+  /* Accept template template parameters.  */
   else if (allow_template_p
-          && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+          && (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
+              || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM))
     ;
   /*   [dcl.type.elab]
 
@@ -11569,7 +11884,9 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
   else
     decl = lookup_type_scope (name, scope);
 
-  if (decl && DECL_CLASS_TEMPLATE_P (decl))
+  if (decl
+      && (DECL_CLASS_TEMPLATE_P (decl)
+         || DECL_TEMPLATE_TEMPLATE_PARM_P (decl)))
     decl = DECL_TEMPLATE_RESULT (decl);
 
   if (decl && TREE_CODE (decl) == TYPE_DECL)
@@ -11635,11 +11952,12 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
 
 static tree
 xref_tag_1 (enum tag_types tag_code, tree name,
-            tag_scope scope, bool template_header_p)
+            tag_scope orig_scope, bool template_header_p)
 {
   enum tree_code code;
   tree t;
   tree context = NULL_TREE;
+  tag_scope scope;
 
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
@@ -11659,6 +11977,11 @@ xref_tag_1 (enum tag_types tag_code, tree name,
       gcc_unreachable ();
     }
 
+  if (orig_scope == ts_lambda)
+    scope = ts_current;
+  else
+    scope = orig_scope;
+
   /* In case of anonymous name, xref_tag is only called to
      make type node and push name.  Name lookup is not required.  */
   if (ANON_AGGRNAME_P (name))
@@ -11674,6 +11997,9 @@ xref_tag_1 (enum tag_types tag_code, tree name,
       && template_class_depth (current_class_type)
       && template_header_p)
     {
+      if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
+       return t;
+
       /* Since SCOPE is not TS_CURRENT, we are not looking at a
         definition of this tag.  Since, in addition, we are currently
         processing a (member) template declaration of a template
@@ -11729,6 +12055,10 @@ xref_tag_1 (enum tag_types tag_code, tree name,
        {
          t = make_class_type (code);
          TYPE_CONTEXT (t) = context;
+         if (orig_scope == ts_lambda)
+           /* Remember that we're declaring a lambda to avoid bogus errors
+              in push_template_decl.  */
+           CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
          t = pushtag (name, t, scope);
        }
     }
@@ -11834,7 +12164,14 @@ xref_basetypes (tree ref, tree base_list)
     {
       tree basetype = TREE_VALUE (*basep);
 
-      if (!(processing_template_decl && uses_template_parms (basetype))
+      /* The dependent_type_p call below should really be dependent_scope_p
+        so that we give a hard error about using an incomplete type as a
+        base, but we allow it with a pedwarn for backward
+        compatibility.  */
+      if (processing_template_decl
+         && CLASS_TYPE_P (basetype) && TYPE_BEING_DEFINED (basetype))
+       cxx_incomplete_type_diagnostic (NULL_TREE, basetype, DK_PEDWARN);
+      if (!dependent_type_p (basetype)
          && !complete_type_or_else (basetype, NULL))
        /* An incomplete type.  Remove it from the list.  */
        *basep = TREE_CHAIN (*basep);
@@ -11844,7 +12181,7 @@ xref_basetypes (tree ref, tree base_list)
          if (TREE_TYPE (*basep))
            max_vbases++;
          if (CLASS_TYPE_P (basetype))
-           max_vbases += VEC_length (tree, CLASSTYPE_VBASECLASSES (basetype));
+           max_vbases += vec_safe_length (CLASSTYPE_VBASECLASSES (basetype));
          basep = &TREE_CHAIN (*basep);
        }
     }
@@ -11872,7 +12209,7 @@ xref_basetypes (tree ref, tree base_list)
 
   if (max_bases)
     {
-      BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, max_bases);
+      vec_alloc (BINFO_BASE_ACCESSES (binfo), max_bases);
       /* An aggregate cannot have baseclasses.  */
       CLASSTYPE_NON_AGGREGATE (ref) = 1;
 
@@ -11894,7 +12231,7 @@ xref_basetypes (tree ref, tree base_list)
 
   if (max_vbases)
     {
-      CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, gc, max_vbases);
+      vec_alloc (CLASSTYPE_VBASECLASSES (ref), max_vbases);
 
       if (TYPE_FOR_JAVA (ref))
         {
@@ -11972,7 +12309,7 @@ xref_basetypes (tree ref, tree base_list)
       BINFO_BASE_ACCESS_APPEND (binfo, access);
     }
 
-  if (VEC_length (tree, CLASSTYPE_VBASECLASSES (ref)) < max_vbases)
+  if (vec_safe_length (CLASSTYPE_VBASECLASSES (ref)) < max_vbases)
     /* If we didn't get max_vbases vbases, we must have shared at
        least one of them, and are therefore diamond shaped.  */
     CLASSTYPE_DIAMOND_SHAPED_P (ref) = 1;
@@ -12450,8 +12787,6 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
        {
          if (TYPE_VALUES (enumtype))
            {
-             HOST_WIDE_INT hi;
-             unsigned HOST_WIDE_INT lo;
              tree prev_value;
              bool overflowed;
 
@@ -12467,15 +12802,13 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
                value = error_mark_node;
              else
                {
-                 overflowed = add_double (TREE_INT_CST_LOW (prev_value),
-                                          TREE_INT_CST_HIGH (prev_value),
-                                          1, 0, &lo, &hi);
+                 double_int di = TREE_INT_CST (prev_value)
+                                 .add_with_sign (double_int_one,
+                                                 false, &overflowed);
                  if (!overflowed)
                    {
-                     double_int di;
                      tree type = TREE_TYPE (prev_value);
-                     bool pos = (TYPE_UNSIGNED (type) || hi >= 0);
-                     di.low = lo; di.high = hi;
+                     bool pos = TYPE_UNSIGNED (type) || !di.is_negative ();
                      if (!double_int_fits_to_tree_p (type, di))
                        {
                          unsigned int itk;
@@ -12518,15 +12851,14 @@ incremented enumerator value is too large for %<long%>");
          does not fit, the program is ill-formed [C++0x dcl.enum].  */
       if (ENUM_UNDERLYING_TYPE (enumtype)
           && value
-          && TREE_CODE (value) == INTEGER_CST
-          && !int_fits_type_p (value, ENUM_UNDERLYING_TYPE (enumtype)))
+          && TREE_CODE (value) == INTEGER_CST)
         {
-          error ("enumerator value %E is too large for underlying type %<%T%>",
-                 value, ENUM_UNDERLYING_TYPE (enumtype));
+         if (!int_fits_type_p (value, ENUM_UNDERLYING_TYPE (enumtype)))
+           error ("enumerator value %E is too large for underlying type %<%T%>",
+                  value, ENUM_UNDERLYING_TYPE (enumtype));
 
-          /* Silently convert the value so that we can continue.  */
-          value = perform_implicit_conversion (ENUM_UNDERLYING_TYPE (enumtype),
-                                               value, tf_none);
+          /* Convert the value to the appropriate type.  */
+          value = convert (ENUM_UNDERLYING_TYPE (enumtype), value);
         }
     }
 
@@ -12552,16 +12884,9 @@ incremented enumerator value is too large for %<long%>");
     course, if we're processing a template, there may be no value.  */
   type = value ? TREE_TYPE (value) : NULL_TREE;
 
-  if (context && context == current_class_type)
-    /* This enum declaration is local to the class.  We need the full
-       lang_decl so that we can record DECL_CLASS_CONTEXT, for example.  */
-    decl = build_lang_decl_loc (loc, CONST_DECL, name, type);
-  else
-    /* It's a global enum, or it's local to a function.  (Note local to
-       a function could mean local to a class method.  */
-    decl = build_decl (loc, CONST_DECL, name, type);
+  decl = build_decl (loc, CONST_DECL, name, type);
   
-  DECL_CONTEXT (decl) = FROB_CONTEXT (context);
+  DECL_CONTEXT (decl) = enumtype;
   TREE_CONSTANT (decl) = 1;
   TREE_READONLY (decl) = 1;
   DECL_INITIAL (decl) = value;
@@ -12610,7 +12935,8 @@ check_function_type (tree decl, tree current_function_parms)
   /* In a function definition, arg types must be complete.  */
   require_complete_types_for_parms (current_function_parms);
 
-  if (dependent_type_p (return_type))
+  if (dependent_type_p (return_type)
+      || type_uses_auto (return_type))
     return;
   if (!COMPLETE_OR_VOID_TYPE_P (return_type)
       || (TYPE_FOR_JAVA (return_type) && MAYBE_CLASS_TYPE_P (return_type)))
@@ -12781,6 +13107,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   /* Build the return declaration for the function.  */
   restype = TREE_TYPE (fntype);
+
   if (DECL_RESULT (decl1) == NULL_TREE)
     {
       tree resdecl;
@@ -12852,6 +13179,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
            DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));
        }
       fntype = TREE_TYPE (decl1);
+      restype = TREE_TYPE (fntype);
 
       /* If #pragma weak applies, mark the decl appropriately now.
         The pragma only applies to global functions.  Because
@@ -12889,6 +13217,12 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   current_stmt_tree ()->stmts_are_full_exprs_p = 1;
   current_binding_level = bl;
 
+  if (!processing_template_decl && type_uses_auto (restype))
+    {
+      FNDECL_USED_AUTO (decl1) = true;
+      current_function_auto_return_pattern = restype;
+    }
+
   /* Start the statement-tree, start the tree now.  */
   DECL_SAVED_TREE (decl1) = push_stmt_list ();
 
@@ -13267,11 +13601,12 @@ finish_destructor_body (void)
       an implicit definition), non-placement operator delete shall
       be looked up in the scope of the destructor's class and if
       found shall be accessible and unambiguous.  */
-      exprstmt = build_op_delete_call(DELETE_EXPR, current_class_ptr,
-                                     virtual_size,
-                                     /*global_p=*/false,
-                                     /*placement=*/NULL_TREE,
-                                     /*alloc_fn=*/NULL_TREE);
+      exprstmt = build_op_delete_call (DELETE_EXPR, current_class_ptr,
+                                      virtual_size,
+                                      /*global_p=*/false,
+                                      /*placement=*/NULL_TREE,
+                                      /*alloc_fn=*/NULL_TREE,
+                                      tf_warning_or_error);
 
       if_stmt = begin_if_stmt ();
       finish_if_stmt_cond (build2 (BIT_AND_EXPR, integer_type_node,
@@ -13443,16 +13778,9 @@ finish_function (int flags)
      there's no need to add any extra bits.  */
   if (!DECL_CLONED_FUNCTION_P (fndecl))
     {
+      /* Make it so that `main' always returns 0 by default.  */
       if (DECL_MAIN_P (current_function_decl))
-       {
-         /* Make it so that `main' always returns 0 by default (or
-            1 for VMS).  */
-#if VMS_TARGET
-         finish_return_stmt (integer_one_node);
-#else
-         finish_return_stmt (integer_zero_node);
-#endif
-       }
+       finish_return_stmt (integer_zero_node);
 
       if (use_eh_spec_block (current_function_decl))
        finish_eh_spec_block (TYPE_RAISES_EXCEPTIONS
@@ -13502,6 +13830,24 @@ finish_function (int flags)
      of curly braces for a function.  */
   gcc_assert (stmts_are_full_exprs_p ());
 
+  /* If there are no return statements in a function with auto return type,
+     the return type is void.  But if the declared type is something like
+     auto*, this is an error.  */
+  if (!processing_template_decl && FNDECL_USED_AUTO (fndecl)
+      && TREE_TYPE (fntype) == current_function_auto_return_pattern)
+    {
+      if (!is_auto (current_function_auto_return_pattern)
+         && !current_function_returns_value && !current_function_returns_null)
+       {
+         error ("no return statements in function returning %qT",
+                current_function_auto_return_pattern);
+         inform (input_location, "only plain %<auto%> return type can be "
+                 "deduced to %<void%>");
+       }
+      apply_deduced_return_type (fndecl, void_type_node);
+      fntype = TREE_TYPE (fndecl);
+    }
+
   /* Save constexpr function body before it gets munged by
      the NRV transformation.   */
   maybe_save_function_definition (fndecl);
@@ -13556,7 +13902,8 @@ finish_function (int flags)
       && !TREE_NO_WARNING (fndecl)
       /* Structor return values (if any) are set by the compiler.  */
       && !DECL_CONSTRUCTOR_P (fndecl)
-      && !DECL_DESTRUCTOR_P (fndecl))
+      && !DECL_DESTRUCTOR_P (fndecl)
+      && targetm.warn_func_return (fndecl))
     {
       warning (OPT_Wreturn_type,
               "no return statement in function returning non-void");
@@ -13644,9 +13991,9 @@ finish_function (int flags)
       unsigned int i;
       tree decl;
 
-      FOR_EACH_VEC_ELT (tree, deferred_mark_used_calls, i, decl)
+      FOR_EACH_VEC_SAFE_ELT (deferred_mark_used_calls, i, decl)
        mark_used (decl);
-      VEC_free (tree, gc, deferred_mark_used_calls);
+      vec_free (deferred_mark_used_calls);
     }
 
   return fndecl;
@@ -13756,10 +14103,8 @@ maybe_register_incomplete_var (tree var)
          || (TYPE_LANG_SPECIFIC (inner_type)
              && TYPE_BEING_DEFINED (inner_type)))
        {
-         incomplete_var *iv
-           = VEC_safe_push (incomplete_var, gc, incomplete_vars, NULL);
-         iv->decl = var;
-         iv->incomplete_type = inner_type;
+         incomplete_var iv = {var, inner_type};
+         vec_safe_push (incomplete_vars, iv);
        }
     }
 }
@@ -13774,7 +14119,7 @@ complete_vars (tree type)
   unsigned ix;
   incomplete_var *iv;
 
-  for (ix = 0; VEC_iterate (incomplete_var, incomplete_vars, ix, iv); )
+  for (ix = 0; vec_safe_iterate (incomplete_vars, ix, &iv); )
     {
       if (same_type_p (type, iv->incomplete_type))
        {
@@ -13785,7 +14130,7 @@ complete_vars (tree type)
          complete_type (type);
          cp_apply_type_quals_to_decl (cp_type_quals (type), var);
          /* Remove this entry from the list.  */
-         VEC_unordered_remove (incomplete_var, incomplete_vars, ix);
+         incomplete_vars->unordered_remove (ix);
        }
       else
        ix++;
@@ -13906,8 +14251,9 @@ static_fn_type (tree memfntype)
     return memfntype;
   gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE);
   args = TYPE_ARG_TYPES (memfntype);
+  cp_ref_qualifier rqual = type_memfn_rqual (memfntype);
   fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args));
-  fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype));
+  fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype), rqual);
   fntype = (cp_build_type_attribute_variant
            (fntype, TYPE_ATTRIBUTES (memfntype)));
   fntype = (build_exception_variant
@@ -13923,9 +14269,10 @@ revert_static_member_fn (tree decl)
 {
   tree stype = static_fn_type (decl);
   cp_cv_quals quals = type_memfn_quals (stype);
+  cp_ref_qualifier rqual = type_memfn_rqual (stype);
 
-  if (quals != TYPE_UNQUALIFIED)
-    stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
+  if (quals != TYPE_UNQUALIFIED || rqual != REF_QUAL_NONE)
+    stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED, REF_QUAL_NONE);
 
   TREE_TYPE (decl) = stype;