OSDN Git Service

Allow dynamic initialization of thread_locals.
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index e664d43..0b936ea 100644 (file)
@@ -39,7 +39,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"
@@ -170,6 +169,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.  */
@@ -553,7 +555,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;
@@ -618,26 +620,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))
@@ -819,7 +827,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;
 }
 
@@ -960,6 +968,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.  */
@@ -988,7 +997,14 @@ decls_match (tree newdecl, tree olddecl)
       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)
@@ -1456,6 +1472,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
@@ -1486,7 +1503,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                              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
@@ -2142,39 +2163,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.  */
@@ -2468,7 +2490,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 +2649,16 @@ 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 (cp_label_binding, gc, current_binding_level->shadowed_labels,
+                bind);
 
   return decl;
 }
@@ -2660,8 +2683,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)))
@@ -3222,13 +3244,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 +3318,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 +3335,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 +3392,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 +3671,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 +3832,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 +4135,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 +4176,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,38 +4227,38 @@ 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 && warn_attributes)
+  if (declspecs->attributes && warn_attributes && declared_type)
     {
       location_t loc;
       if (!CLASS_TYPE_P (declared_type)
@@ -4227,10 +4269,22 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
        /* For a template class (an explicit instantiation), use the
           current location.  */
        loc = input_location;
-      warning_at (loc, OPT_Wattributes, "attribute ignored in declaration "
-                 "of %q#T", declared_type);
-      inform (loc, "attribute for %q#T must follow the %qs keyword",
-             declared_type, class_key_or_enum_as_string (declared_type));
+
+      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;
@@ -4252,7 +4306,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;
@@ -4423,7 +4478,8 @@ start_decl (const cp_declarator *declarator,
     }
 
   /* If #pragma weak was used, mark the decl weak now.  */
-  maybe_apply_pragma_weak (decl);
+  if (!processing_template_decl)
+    maybe_apply_pragma_weak (decl);
 
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DECLARED_INLINE_P (decl)
@@ -4449,11 +4505,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
@@ -4463,7 +4514,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);
            }
@@ -4518,18 +4569,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))
@@ -4659,7 +4698,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
@@ -5099,6 +5138,7 @@ 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)
@@ -5135,6 +5175,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]
@@ -5257,7 +5306,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;
@@ -5281,7 +5331,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
          && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (str_init)) == 1)
        {
          str_init = VEC_index (constructor_elt,
-                               CONSTRUCTOR_ELTS (str_init), 0)->value;
+                               CONSTRUCTOR_ELTS (str_init), 0).value;
        }
 
       /* If it's a string literal, then it's the initializer for the array
@@ -5371,7 +5421,7 @@ reshape_init (tree type, tree init, tsubst_flags_t complain)
     return init;
 
   /* Recurse on this CONSTRUCTOR.  */
-  d.cur = VEC_index (constructor_elt, v, 0);
+  d.cur = &VEC_index (constructor_elt, v, 0);
   d.end = d.cur + VEC_length (constructor_elt, v);
 
   new_init = reshape_init_r (type, &d, true, complain);
@@ -5566,6 +5616,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
@@ -5916,7 +5971,7 @@ type_dependent_init_p (tree init)
       nelts = VEC_length (constructor_elt, elts);
       for (i = 0; i < nelts; ++i)
        if (type_dependent_init_p (VEC_index (constructor_elt,
-                                             elts, i)->value))
+                                             elts, i).value))
          return true;
     }
   else
@@ -5946,7 +6001,7 @@ value_dependent_init_p (tree init)
       nelts = VEC_length (constructor_elt, elts);
       for (i = 0; i < nelts; ++i)
        if (value_dependent_init_p (VEC_index (constructor_elt,
-                                              elts, i)->value))
+                                              elts, i).value))
          return true;
     }
   else
@@ -6008,8 +6063,8 @@ 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)
@@ -6122,8 +6177,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;
@@ -6168,13 +6230,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
@@ -6191,7 +6246,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);
        }
 
@@ -6220,13 +6275,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
@@ -6500,7 +6548,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 +6573,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 +6687,27 @@ 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.  */
+  ob_parm = (DECL_THREAD_LOCAL_P (decl)
+            || (flag_use_cxa_atexit
+                && !targetm.cxx.use_atexit_for_cxa_atexit ()));
+  dso_parm = ob_parm;
+  use_dtor = ob_parm && CLASS_TYPE_P (type);
   if (use_dtor)
     {
       int idx;
@@ -6648,7 +6717,8 @@ register_dtor_fn (tree decl)
       gcc_assert (idx >= 0);
       cleanup = VEC_index (tree, 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 +6748,45 @@ 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 if (ob_parm)
+    /* 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
+    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 +6798,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 +6821,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 +6848,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 +6889,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 +6897,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 +6955,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);
 }
@@ -6894,7 +7002,7 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
          && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (initial_value)))
        {
          VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value);
-         tree value = VEC_index (constructor_elt, v, 0)->value;
+         tree value = VEC_index (constructor_elt, v, 0).value;
 
          if (TREE_CODE (value) == STRING_CST
              && VEC_length (constructor_elt, v) == 1)
@@ -7439,6 +7547,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 +7780,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.  */
@@ -7861,7 +7980,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 +8017,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 +8056,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 +8063,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 +8075,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 +8128,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 +8182,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 +8234,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 +8324,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,
@@ -8353,7 +8515,7 @@ check_var_type (tree identifier, tree type)
 
 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)
@@ -8419,16 +8581,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;
@@ -8503,7 +8665,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",
@@ -8629,7 +8791,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;
@@ -8667,7 +8829,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;
@@ -8757,7 +8919,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,
@@ -8776,7 +8938,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);
     }
 
@@ -8827,7 +8989,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)
@@ -8893,7 +9055,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);
@@ -8917,16 +9079,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)
@@ -8935,9 +9108,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)
@@ -8949,7 +9122,7 @@ grokdeclarator (const cp_declarator *declarator,
       storage_class = sc_none;
       staticp = 0;
     }
-  friendp = !! declspecs->specs[(int)ds_friend];
+  friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
 
   if (dependent_name && !friendp)
     {
@@ -8960,7 +9133,7 @@ grokdeclarator (const cp_declarator *declarator,
   /* 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;
@@ -9004,7 +9177,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;
@@ -9018,7 +9191,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.  */
@@ -9056,9 +9229,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)
@@ -9090,6 +9269,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)
@@ -9127,6 +9315,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:
@@ -9165,6 +9360,11 @@ 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;
@@ -9188,9 +9388,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))
                      {
@@ -9314,6 +9518,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;
 
@@ -9476,6 +9687,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;
 
@@ -9499,8 +9721,6 @@ grokdeclarator (const cp_declarator *declarator,
      the object as `const'.  */
   if (constexpr_p && innermost_code != cdk_function)
     {
-      if (type_quals & TYPE_QUAL_CONST)
-        error ("both %<const%> and %<constexpr%> cannot be used here");
       if (type_quals & TYPE_QUAL_VOLATILE)
         error ("both %<volatile%> and %<constexpr%> cannot be used here");
       if (TREE_CODE (type) != REFERENCE_TYPE)
@@ -9530,36 +9750,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)
        {
@@ -9608,7 +9801,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",
@@ -9630,6 +9823,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)
     {
@@ -9640,12 +9840,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
@@ -9679,7 +9879,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;
@@ -9709,7 +9910,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;
 
@@ -9764,7 +9965,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);
@@ -9821,7 +10023,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;
@@ -10029,7 +10231,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;
@@ -10234,7 +10437,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
@@ -10309,7 +10513,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);
@@ -10318,15 +10529,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);
          }
@@ -10420,7 +10631,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;
@@ -10520,7 +10731,7 @@ local_variable_p (const_tree t)
 
 static tree
 local_variable_p_walkfn (tree *tp, int *walk_subtrees,
-                        void *data ATTRIBUTE_UNUSED)
+                        void * /*data*/)
 {
   /* Check DECL_NAME to avoid including temporaries.  We don't check
      DECL_ARTIFICIAL because we do want to complain about 'this'.  */
@@ -10569,17 +10780,20 @@ 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));
+  ++cp_unevaluated_operand;
+  perform_implicit_conversion_flags (decl_type, arg, tf_warning_or_error,
+                                    LOOKUP_NORMAL);
+  --cp_unevaluated_operand;
 
-      return error_mark_node;
+  if (warn_zero_as_null_pointer_constant
+      && c_inhibit_evaluation_warnings == 0
+      && 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;
     }
 
   /* [dcl.fct.default]
@@ -10840,10 +11054,6 @@ copy_fn_p (const_tree d)
 bool
 move_fn_p (const_tree d)
 {
-  tree args;
-  tree arg_type;
-  bool result = false;
-
   gcc_assert (DECL_FUNCTION_MEMBER_P (d));
 
   if (cxx_dialect == cxx98)
@@ -10853,12 +11063,29 @@ move_fn_p (const_tree d)
   if (TREE_CODE (d) == TEMPLATE_DECL
       || (DECL_TEMPLATE_INFO (d)
          && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
-    /* Instantiations of template member functions are never copy
+    /* Instantiations of template member functions are never move
        functions.  Note that member functions of templated classes are
        represented as template functions internally, and we must
-       accept those as copy functions.  */
+       accept those as move functions.  */
     return 0;
 
+  return move_signature_fn_p (d);
+}
+
+/* D is a constructor or overloaded `operator='.
+
+   Then, this function returns true when D has the same signature as a move
+   constructor or move assignment operator (because either it is such a
+   ctor/op= or it is a template specialization with the same signature),
+   false otherwise.  */
+
+bool
+move_signature_fn_p (const_tree d)
+{
+  tree args;
+  tree arg_type;
+  bool result = false;
+
   args = FUNCTION_FIRST_USER_PARMTYPE (d);
   if (!args)
     return 0;
@@ -11375,7 +11602,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
@@ -11445,9 +11672,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]
 
@@ -11535,7 +11763,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)
@@ -11640,6 +11870,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
@@ -11800,7 +12033,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);
@@ -12342,6 +12582,12 @@ finish_enum_value_list (tree enumtype)
   for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
     TYPE_VALUES (t) = TYPE_VALUES (enumtype);
 
+  if (at_class_scope_p ()
+      && COMPLETE_TYPE_P (current_class_type)
+      && UNSCOPED_ENUM_P (enumtype))
+    insert_late_enum_def_into_classtype_sorted_fields (enumtype,
+                                                      current_class_type);
+
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (enumtype, namespace_bindings_p ());
 }
@@ -12410,8 +12656,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;
 
@@ -12427,15 +12671,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;
@@ -12512,16 +12754,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;
@@ -12570,7 +12805,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)))
@@ -12741,6 +12977,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;
@@ -12849,6 +13086,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 ();
 
@@ -13228,11 +13471,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,
@@ -13404,16 +13648,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
@@ -13463,6 +13700,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);
@@ -13517,7 +13772,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");
@@ -13717,10 +13973,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_var, gc, incomplete_vars, iv);
        }
     }
 }