OSDN Git Service

Allow dynamic initialization of thread_locals.
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 8a3163a..0b936ea 100644 (file)
@@ -169,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.  */
@@ -552,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;
@@ -617,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))
@@ -818,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;
 }
 
@@ -2154,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.  */
@@ -2480,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");
@@ -2638,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;
 }
@@ -2672,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)))
@@ -3234,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);
@@ -3306,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
@@ -3323,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;
 }
 
@@ -3378,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;
     }
@@ -3817,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;
@@ -4121,13 +4135,32 @@ 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 = decl_spec_seq_has_spec_p (declspecs, ds_friend);
   int saw_typedef = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
@@ -4236,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;
@@ -4261,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;
@@ -4459,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
@@ -5097,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)
@@ -5133,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]
@@ -5280,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
@@ -5370,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);
@@ -5565,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
@@ -5915,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
@@ -5945,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
@@ -6121,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;
@@ -6167,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
@@ -6219,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
@@ -6499,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
@@ -6530,6 +6578,24 @@ get_atexit_node (void)
   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
@@ -6621,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;
@@ -6647,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
     {
@@ -6677,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;
@@ -6717,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);
 }
 
@@ -6737,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.  */
@@ -6744,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:
@@ -6782,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 ();
@@ -6790,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;
@@ -6848,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);
 }
@@ -6893,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)
@@ -7672,7 +7781,11 @@ grokvardecl (tree type,
     }
 
   if (decl_spec_seq_has_spec_p (declspecs, ds_thread))
-    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 the type of the decl has no linkage, make sure that we'll
      notice that in mark_used.  */
@@ -7904,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
@@ -7913,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;
@@ -7921,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
@@ -7933,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))
@@ -7986,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
@@ -8100,8 +8242,21 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
       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.)  */
@@ -8360,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)
@@ -8510,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",
@@ -9074,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)
@@ -9108,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)
@@ -9145,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:
@@ -9341,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;
 
@@ -9503,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;
 
@@ -9526,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)
@@ -9557,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)
        {
@@ -9657,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)
     {
@@ -10340,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);
@@ -10551,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'.  */
@@ -10600,19 +10780,10 @@ 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,
-                          tf_warning_or_error))
-    {
-      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_NORMAL);
+  --cp_unevaluated_operand;
 
   if (warn_zero_as_null_pointer_constant
       && c_inhibit_evaluation_warnings == 0
@@ -10883,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)
@@ -10896,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;
@@ -11488,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]
 
@@ -11578,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)
@@ -11683,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
@@ -12466,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;
 
@@ -12483,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;
@@ -13586,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");
@@ -13786,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);
        }
     }
 }