OSDN Git Service

Fix PR c++/44188
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index c720f6c..c9f864a 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -33,26 +33,27 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "rtl.h"
-#include "expr.h"
 #include "flags.h"
 #include "cp-tree.h"
+#include "tree-iterator.h"
 #include "tree-inline.h"
 #include "decl.h"
+#include "intl.h"
 #include "output.h"
 #include "except.h"
 #include "toplev.h"
 #include "hashtab.h"
 #include "tm_p.h"
 #include "target.h"
-#include "c-common.h"
-#include "c-pragma.h"
+#include "c-family/c-common.h"
+#include "c-family/c-pragma.h"
 #include "diagnostic.h"
 #include "intl.h"
 #include "debug.h"
 #include "timevar.h"
 #include "tree-flow.h"
 #include "pointer-set.h"
+#include "splay-tree.h"
 #include "plugin.h"
 
 static tree grokparms (tree parmlist, tree *);
@@ -103,7 +104,6 @@ static tree build_cp_library_fn (tree, enum tree_code, tree);
 static void store_parm_decls (tree);
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
-static tree next_initializable_field (tree);
 
 /* The following symbols are subsumed in the cp_global_trees array, and
    listed here individually for documentation purposes.
@@ -498,6 +498,10 @@ poplevel_named_label_1 (void **slot, void *data)
   return 1;
 }
 
+/* Saved errorcount to avoid -Wunused-but-set-{parameter,variable} warnings
+   when errors were reported, except for -Werror-unused-but-set-*.  */
+static int unused_but_set_errorcount;
+
 /* Exit a binding level.
    Pop the level off, and restore the state of the identifier-decl mappings
    that were in effect when this level was entered.
@@ -520,8 +524,6 @@ poplevel (int keep, int reverse, int functionbody)
   /* The chain of decls was accumulated in reverse order.
      Put it into forward order, just for cleanliness.  */
   tree decls;
-  int tmp = functionbody;
-  int real_functionbody;
   tree subblocks;
   tree block;
   tree decl;
@@ -535,8 +537,8 @@ poplevel (int keep, int reverse, int functionbody)
 
   gcc_assert (current_binding_level->kind != sk_class);
 
-  real_functionbody = (current_binding_level->kind == sk_cleanup
-                      ? ((functionbody = 0), tmp) : functionbody);
+  if (current_binding_level->kind == sk_cleanup)
+    functionbody = 0;
   subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
 
   gcc_assert (!VEC_length(cp_class_binding,
@@ -591,14 +593,28 @@ poplevel (int keep, int reverse, int functionbody)
     = current_binding_level->kind == sk_for && flag_new_for_scope == 1;
 
   /* Before we remove the declarations first check for unused variables.  */
-  if (warn_unused_variable
+  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)
+         && (! TREE_USED (decl) || !DECL_READ_P (decl))
          && ! DECL_IN_SYSTEM_HEADER (decl)
          && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
-       warning (OPT_Wunused_variable, "unused variable %q+D", 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;
+           }
+       }
 
   /* Remove declarations for all the DECLs in this level.  */
   for (link = decls; link; link = TREE_CHAIN (link))
@@ -849,6 +865,7 @@ create_implicit_typedef (tree name, tree type)
      amongst these.  */
   SET_DECL_IMPLICIT_TYPEDEF_P (decl);
   TYPE_NAME (type) = decl;
+  TYPE_STUB_DECL (type) = decl;
 
   return decl;
 }
@@ -935,7 +952,7 @@ decls_match (tree newdecl, tree olddecl)
 #ifdef NO_IMPLICIT_EXTERN_C
       /* A new declaration doesn't match a built-in one unless it
         is also extern "C".  */
-      if (DECL_BUILT_IN (olddecl)
+      if (DECL_IS_BUILTIN (olddecl)
          && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
        return 0;
 #endif
@@ -1034,8 +1051,6 @@ decls_match (tree newdecl, tree olddecl)
 void
 warn_extern_redeclared_static (tree newdecl, tree olddecl)
 {
-  tree name;
-
   if (TREE_CODE (newdecl) == TYPE_DECL
       || TREE_CODE (newdecl) == TEMPLATE_DECL
       || TREE_CODE (newdecl) == CONST_DECL
@@ -1058,7 +1073,6 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
       && DECL_ARTIFICIAL (olddecl))
     return;
 
-  name = DECL_ASSEMBLER_NAME (newdecl);
   permerror (input_location, "%qD was declared %<extern%> and later %<static%>", newdecl);
   permerror (input_location, "previous declaration of %q+D", olddecl);
 }
@@ -1090,10 +1104,10 @@ check_redeclaration_exception_specification (tree new_decl,
   if ((pedantic || ! DECL_IN_SYSTEM_HEADER (old_decl))
       && ! DECL_IS_BUILTIN (old_decl)
       && flag_exceptions
-      && !comp_except_specs (new_exceptions, old_exceptions,
-                            /*exact=*/true))
+      && !comp_except_specs (new_exceptions, old_exceptions, ce_normal))
     {
-      error ("declaration of %qF throws different exceptions", new_decl);
+      error ("declaration of %qF has a different exception specifier",
+            new_decl);
       error ("from previous declaration %q+F", old_decl);
     }
 }
@@ -1183,9 +1197,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
             bad choice of name.  */
          if (! TREE_PUBLIC (newdecl))
            {
-             warning (OPT_Wshadow, "shadowing %s function %q#D",
-                      DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                      olddecl);
+             warning (OPT_Wshadow, 
+                       DECL_BUILT_IN (olddecl)
+                       ? G_("shadowing built-in function %q#D")
+                       : G_("shadowing library function %q#D"), olddecl);
              /* Discard the old built-in function.  */
              return NULL_TREE;
            }
@@ -1256,9 +1271,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                           olddecl);
                }
              else
-               warning (OPT_Wshadow, "shadowing %s function %q#D",
-                        DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                        olddecl);
+               warning (OPT_Wshadow, 
+                         DECL_BUILT_IN (olddecl)
+                         ? G_("shadowing built-in function %q#D")
+                         : G_("shadowing library function %q#D"), olddecl);
            }
          else
            /* Discard the old built-in function.  */
@@ -1270,7 +1286,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       /* Even if the types match, prefer the new declarations type for
         built-ins which have not been explicitly declared, for
         exception lists, etc...  */
-      else if (DECL_ANTICIPATED (olddecl))
+      else if (DECL_SOURCE_LOCATION (olddecl) == BUILTINS_LOCATION)
        {
          tree type = TREE_TYPE (newdecl);
          tree attribs = (*targetm.merge_type_attributes)
@@ -1931,6 +1947,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          if (DECL_VIRTUAL_P (newdecl))
            DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
        }
+      /* Only variables have this field.  */
+      else if (TREE_CODE (newdecl) == VAR_DECL
+              && VAR_HAD_UNKNOWN_BOUND (olddecl))
+       SET_VAR_HAD_UNKNOWN_BOUND (newdecl);
     }
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
@@ -2094,6 +2114,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
     TREE_USED (newdecl) = 1;
   else if (TREE_USED (newdecl))
     TREE_USED (olddecl) = 1;
+  if (TREE_CODE (newdecl) == VAR_DECL)
+    {
+      if (DECL_READ_P (olddecl))
+       DECL_READ_P (newdecl) = 1;
+      else if (DECL_READ_P (newdecl))
+       DECL_READ_P (olddecl) = 1;
+    }
+  if (DECL_PRESERVE_P (olddecl))
+    DECL_PRESERVE_P (newdecl) = 1;
+  else if (DECL_PRESERVE_P (newdecl))
+    DECL_PRESERVE_P (olddecl) = 1;
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -2211,7 +2242,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
        return NULL;
       else
-       return "redefinition of %q#D";
+       return G_("redefinition of %q#D");
     }
   else if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -2227,7 +2258,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       if (DECL_NAMESPACE_SCOPE_P (olddecl)
          && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)
          && ! decls_match (olddecl, newdecl))
-       return "%qD conflicts with used function";
+       return G_("%qD conflicts with used function");
 
       /* We'll complain about linkage mismatches in
         warn_extern_redeclared_static.  */
@@ -2237,10 +2268,10 @@ redeclaration_error_message (tree newdecl, tree olddecl)
          && DECL_INITIAL (newdecl) != NULL_TREE)
        {
          if (DECL_NAME (olddecl) == NULL_TREE)
-           return "%q#D not declared in class";
+           return G_("%q#D not declared in class");
          else if (!GNU_INLINE_P (olddecl)
                   || GNU_INLINE_P (newdecl))
-           return "redefinition of %q#D";
+           return G_("redefinition of %q#D");
        }
 
       if (DECL_DECLARED_INLINE_P (olddecl) && DECL_DECLARED_INLINE_P (newdecl))
@@ -2251,9 +2282,11 @@ redeclaration_error_message (tree newdecl, tree olddecl)
          if (olda != newa)
            {
              if (newa)
-               return "%q+D redeclared inline with %<gnu_inline%> attribute";
+               return G_("%q+D redeclared inline with "
+                         "%<gnu_inline%> attribute");
              else
-               return "%q+D redeclared inline without %<gnu_inline%> attribute";
+               return G_("%q+D redeclared inline without "
+                         "%<gnu_inline%> attribute");
            }
        }
 
@@ -2267,7 +2300,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
        {
          if (COMPLETE_TYPE_P (TREE_TYPE (newdecl))
              && COMPLETE_TYPE_P (TREE_TYPE (olddecl)))
-           return "redefinition of %q#D";
+           return G_("redefinition of %q#D");
          return NULL;
        }
 
@@ -2284,7 +2317,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
        ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot));
       if (DECL_INITIAL (nt) && DECL_INITIAL (ot)
          && (!GNU_INLINE_P (ot) || GNU_INLINE_P (nt)))
-       return "redefinition of %q#D";
+       return G_("redefinition of %q#D");
 
       if (DECL_DECLARED_INLINE_P (ot) && DECL_DECLARED_INLINE_P (nt))
        {
@@ -2294,9 +2327,11 @@ redeclaration_error_message (tree newdecl, tree olddecl)
          if (olda != newa)
            {
              if (newa)
-               return "%q+D redeclared inline with %<gnu_inline%> attribute";
+               return G_("%q+D redeclared inline with "
+                         "%<gnu_inline%> attribute");
              else
-               return "%q+D redeclared inline without %<gnu_inline%> attribute";
+               return G_("%q+D redeclared inline without "
+                         "%<gnu_inline%> attribute");
            }
        }
 
@@ -2311,7 +2346,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
           && !check_default_tmpl_args (nt, DECL_TEMPLATE_PARMS (newdecl), 
                                        /*is_primary=*/1, /*is_partial=*/0,
                                        /*is_friend_decl=*/2))
-        return "redeclaration of friend %q#D may not have default template arguments";
+        return G_("redeclaration of friend %q#D "
+                 "may not have default template arguments");
 
       return NULL;
     }
@@ -2324,11 +2360,11 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* Only variables can be thread-local, and all declarations must
         agree on this property.  */
       if (DECL_THREAD_LOCAL_P (newdecl))
-       return "thread-local declaration of %q#D follows "
-              "non-thread-local declaration";
+       return G_("thread-local declaration of %q#D follows "
+                 "non-thread-local declaration");
       else
-       return "non-thread-local declaration of %q#D follows "
-              "thread-local declaration";
+       return G_("non-thread-local declaration of %q#D follows "
+                 "thread-local declaration");
     }
   else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
     {
@@ -2342,7 +2378,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
           is invalid.  */
       if ((TREE_CODE (newdecl) == VAR_DECL && DECL_ANON_UNION_VAR_P (newdecl))
          || (TREE_CODE (olddecl) == VAR_DECL && DECL_ANON_UNION_VAR_P (olddecl)))
-       return "redeclaration of %q#D";
+       return G_("redeclaration of %q#D");
       /* If at least one declaration is a reference, there is no
         conflict.  For example:
 
@@ -2353,7 +2389,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
        return NULL;
       /* Reject two definitions.  */
-      return "redefinition of %q#D";
+      return G_("redefinition of %q#D");
     }
   else
     {
@@ -2361,7 +2397,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* Reject two definitions, and reject a definition
         together with an external reference.  */
       if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)))
-       return "redeclaration of %q#D";
+       return G_("redeclaration of %q#D");
       return NULL;
     }
 }
@@ -3039,11 +3075,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (!dependent_scope_p (context))
     /* We should only set WANT_TYPE when we're a nested typename type.
        Then we can give better diagnostics if we find a non-type.  */
-    t = lookup_field (context, name, 0, /*want_type=*/true);
+    t = lookup_field (context, name, 2, /*want_type=*/true);
   else
     t = NULL_TREE;
 
-  if (!t && dependent_type_p (context)) 
+  if ((!t || TREE_CODE (t) == TREE_LIST) && dependent_type_p (context))
     return build_typename_type (context, name, fullname, tag_type);
 
   want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR;
@@ -3056,6 +3092,20 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
       return error_mark_node;
     }
   
+  /* Pull out the template from an injected-class-name (or multiple).  */
+  if (want_template)
+    t = maybe_get_template_decl_from_type_decl (t);
+
+  if (TREE_CODE (t) == TREE_LIST)
+    {
+      if (complain & tf_error)
+       {
+         error ("lookup of %qT in %qT is ambiguous", name, context);
+         print_candidates (t);
+       }
+      return error_mark_node;
+    }
+
   if (want_template && !DECL_CLASS_TEMPLATE_P (t))
     {
       if (complain & tf_error)
@@ -3074,6 +3124,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (complain & tf_error)
     perform_or_defer_access_check (TYPE_BINFO (context), t, t);
 
+  /* 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
+     template instantiation time.  */
+  add_typedef_to_current_template_for_access_check (t, context, input_location);
+
   if (want_template)
     return lookup_template_class (t, TREE_OPERAND (fullname, 1),
                                  NULL_TREE, context,
@@ -3328,7 +3383,7 @@ cxx_init_decl_processing (void)
   tree void_ftype;
   tree void_ftype_ptr;
 
-  build_common_tree_nodes (flag_signed_char, false);
+  build_common_tree_nodes (flag_signed_char);
 
   /* Create all the identifiers we need.  */
   initialize_predefined_identifiers ();
@@ -3378,6 +3433,8 @@ cxx_init_decl_processing (void)
   truthvalue_true_node = boolean_true_node;
 
   empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
+  noexcept_true_spec = build_tree_list (boolean_true_node, NULL_TREE);
+  noexcept_false_spec = build_tree_list (boolean_false_node, NULL_TREE);
 
 #if 0
   record_builtin_type (RID_MAX, NULL, string_type_node);
@@ -3397,7 +3454,7 @@ cxx_init_decl_processing (void)
 
   /* C++ extensions */
 
-  unknown_type_node = make_node (UNKNOWN_TYPE);
+  unknown_type_node = make_node (LANG_TYPE);
   record_unknown_type (unknown_type_node, "unknown type");
 
   /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node.  */
@@ -3408,7 +3465,7 @@ cxx_init_decl_processing (void)
   TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
   TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
 
-  init_list_type_node = make_node (UNKNOWN_TYPE);
+  init_list_type_node = make_node (LANG_TYPE);
   record_unknown_type (init_list_type_node, "init list");
 
   {
@@ -3426,7 +3483,7 @@ cxx_init_decl_processing (void)
   vtbl_type_node
     = build_cplus_array_type (vtable_entry_type, NULL_TREE);
   layout_type (vtbl_type_node);
-  vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
+  vtbl_type_node = cp_build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
   record_builtin_type (RID_MAX, NULL, vtbl_type_node);
   vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
   layout_type (vtbl_ptr_type_node);
@@ -3443,35 +3500,52 @@ cxx_init_decl_processing (void)
   current_lang_name = lang_name_cplusplus;
 
   {
-    tree bad_alloc_id;
-    tree bad_alloc_type_node;
-    tree bad_alloc_decl;
     tree newtype, deltype;
     tree ptr_ftype_sizetype;
-
-    push_namespace (std_identifier);
-    bad_alloc_id = get_identifier ("bad_alloc");
-    bad_alloc_type_node = make_class_type (RECORD_TYPE);
-    TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
-    bad_alloc_decl
-      = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
-    DECL_CONTEXT (bad_alloc_decl) = current_namespace;
-    TYPE_STUB_DECL (bad_alloc_type_node) = bad_alloc_decl;
-    pop_namespace ();
+    tree new_eh_spec;
 
     ptr_ftype_sizetype
       = build_function_type (ptr_type_node,
                             tree_cons (NULL_TREE,
                                        size_type_node,
                                        void_list_node));
-    newtype = build_exception_variant
-      (ptr_ftype_sizetype, add_exception_specifier
-       (NULL_TREE, bad_alloc_type_node, -1));
+    if (cxx_dialect == cxx98)
+      {
+       tree bad_alloc_id;
+       tree bad_alloc_type_node;
+       tree bad_alloc_decl;
+
+       push_namespace (std_identifier);
+       bad_alloc_id = get_identifier ("bad_alloc");
+       bad_alloc_type_node = make_class_type (RECORD_TYPE);
+       TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
+       bad_alloc_decl
+         = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
+       DECL_CONTEXT (bad_alloc_decl) = current_namespace;
+       pop_namespace ();
+
+       new_eh_spec
+         = add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1);
+      }
+    else
+      new_eh_spec = noexcept_false_spec;
+
+    newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec);
     deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
     push_cp_library_fn (NEW_EXPR, newtype);
     push_cp_library_fn (VEC_NEW_EXPR, newtype);
     global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
     push_cp_library_fn (VEC_DELETE_EXPR, deltype);
+
+    nullptr_type_node = make_node (LANG_TYPE);
+    TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
+    TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
+    TYPE_UNSIGNED (nullptr_type_node) = 1;
+    TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
+    SET_TYPE_MODE (nullptr_type_node, Pmode);
+    record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
+    nullptr_node = make_node (INTEGER_CST);
+    TREE_TYPE (nullptr_node) = nullptr_type_node;
   }
 
   abort_fndecl
@@ -3515,7 +3589,7 @@ cp_fname_init (const char* name, tree *type_p)
       init = build_string (length + 1, name);
     }
 
-  type = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
+  type = cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST);
   type = build_cplus_array_type (type, domain);
 
   *type_p = type;
@@ -3939,6 +4013,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
               "and functions");
       else if (saw_typedef)
        warning (0, "%<typedef%> was ignored in this declaration");
+      else if (declspecs->specs[(int) ds_constexpr])
+        error ("%<constexpr> cannot be used for type declarations");
     }
 
   return declared_type;
@@ -4050,7 +4126,6 @@ start_decl (const cp_declarator *declarator,
            tree *pushed_scope_p)
 {
   tree decl;
-  tree type;
   tree context;
   bool was_public;
   int flags;
@@ -4073,8 +4148,6 @@ start_decl (const cp_declarator *declarator,
       || decl == error_mark_node)
     return error_mark_node;
 
-  type = TREE_TYPE (decl);
-
   context = DECL_CONTEXT (decl);
 
   if (context)
@@ -4181,6 +4254,9 @@ 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]
+                  && !DECL_DECLARED_CONSTEXPR_P (field))
+                error ("%qD declared %<constexpr%> outside its class", field);
            }
        }
       else
@@ -4219,6 +4295,9 @@ start_decl (const cp_declarator *declarator,
       if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
        permerror (input_location, "declaration of %q#D outside of class is not definition",
                   decl);
+
+      if (!ensure_literal_type_for_constexpr_object (decl))
+        return error_mark_node;
     }
 
   was_public = TREE_PUBLIC (decl);
@@ -4250,7 +4329,7 @@ start_decl (const cp_declarator *declarator,
       /* This is a const variable with implicit 'static'.  Set
         DECL_THIS_STATIC so we can tell it from variables that are
         !TREE_PUBLIC because of the anonymous namespace.  */
-      gcc_assert (cp_type_readonly (TREE_TYPE (decl)));
+      gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (decl)));
       DECL_THIS_STATIC (decl) = 1;
     }
 
@@ -4382,7 +4461,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
      DECL_INITIAL for local references (instead assigning to them
      explicitly); we need to allow the temporary to be initialized
      first.  */
-  tmp = initialize_reference (type, init, decl, cleanup);
+  tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error);
 
   if (tmp == error_mark_node)
     return NULL_TREE;
@@ -4611,7 +4690,7 @@ maybe_commonize_var (tree decl)
       /* Don't mess with __FUNCTION__.  */
       && ! DECL_ARTIFICIAL (decl)
       && DECL_FUNCTION_SCOPE_P (decl)
-      && vague_linkage_fn_p (DECL_CONTEXT (decl)))
+      && vague_linkage_p (DECL_CONTEXT (decl)))
     {
       if (flag_weak)
        {
@@ -4658,19 +4737,40 @@ maybe_commonize_var (tree decl)
 static void
 check_for_uninitialized_const_var (tree decl)
 {
-  tree type = TREE_TYPE (decl);
+  tree type = strip_array_types (TREE_TYPE (decl));
+
+  if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl)
+      && DECL_INITIAL (decl) == NULL)
+    error ("missing initializer for constexpr %qD", decl);
 
   /* ``Unless explicitly declared extern, a const object does not have
      external linkage and must be initialized. ($8.4; $12.1)'' ARM
      7.1.6 */
-  if (TREE_CODE (decl) == VAR_DECL
+  else if (TREE_CODE (decl) == VAR_DECL
       && TREE_CODE (type) != REFERENCE_TYPE
       && CP_TYPE_CONST_P (type)
-      && !TYPE_NEEDS_CONSTRUCTING (type)
+      && (!TYPE_NEEDS_CONSTRUCTING (type)
+         || !type_has_user_provided_default_constructor (type))
       && !DECL_INITIAL (decl))
-    error ("uninitialized const %qD", decl);
-}
+    {
+      permerror (DECL_SOURCE_LOCATION (decl),
+                "uninitialized const %qD", decl);
 
+      if (CLASS_TYPE_P (type)
+         && !type_has_user_provided_default_constructor (type))
+       {
+         tree defaulted_ctor;
+
+         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+                 "%q#T has no user-provided default constructor", type);
+         defaulted_ctor = in_class_defaulted_default_constructor (type);
+         if (defaulted_ctor)
+           inform (DECL_SOURCE_LOCATION (defaulted_ctor),
+                   "constructor is not user-provided because it is "
+                   "explicitly defaulted in the class body");
+       }
+    }
+}
 \f
 /* Structure holding the current initializer being processed by reshape_init.
    CUR is a pointer to the current element being processed, END is a pointer
@@ -4688,7 +4788,7 @@ static tree reshape_init_r (tree, reshape_iter *, bool);
    initialized.  If there are no more such fields, the return value
    will be NULL.  */
 
-static tree
+tree
 next_initializable_field (tree field)
 {
   while (field
@@ -4852,6 +4952,9 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
 
       field_init = reshape_init_r (TREE_TYPE (field), d,
                                   /*first_initializer_p=*/false);
+      if (field_init == error_mark_node)
+       return error_mark_node;
+
       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init);
 
       /* [dcl.init.aggr]
@@ -4900,7 +5003,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
              init = error_mark_node;
            }
          else
-           maybe_warn_cpp0x ("extended initializer lists");
+           maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
        }
 
       d->cur++;
@@ -4921,7 +5024,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
         looking through the outermost braces; A a2 = { a1 }; is not a
         valid aggregate initialization.  */
       && !first_initializer_p
-      && can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL))
+      && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))
+         || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL)))
     {
       d->cur++;
       return init;
@@ -5112,6 +5216,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
 {
   tree type = TREE_TYPE (decl);
   tree init_code = NULL;
+  tree core_type;
 
   /* Things that are going to be initialized need to have complete
      type.  */
@@ -5143,7 +5248,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
        {
          if (init_len == 0)
            {
-             maybe_warn_cpp0x ("extended initializer lists");
+             maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
              init = build_zero_init (type, NULL_TREE, false);
            }
          else if (init_len != 1)
@@ -5182,7 +5287,6 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
                error ("in C++98 %qD must be initialized by constructor, "
                       "not by %<{...}%>",
                       decl);
-             init = build_tree_list (NULL_TREE, init);
            }
          else if (TREE_CODE (type) == VECTOR_TYPE && TYPE_VECTOR_OPAQUE (type))
            {
@@ -5219,15 +5323,16 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
   else if (DECL_EXTERNAL (decl))
     ;
   else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type))
-    return build_aggr_init_full_exprs (decl, init, flags);
-  else if (MAYBE_CLASS_TYPE_P (type))
     {
-      tree core_type = strip_array_types (type);
-
-      if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type))
-       error ("structure %qD with uninitialized const members", decl);
-      if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))
-       error ("structure %qD with uninitialized reference members", decl);
+      check_for_uninitialized_const_var (decl);
+      return build_aggr_init_full_exprs (decl, init, flags);
+    }
+  else if (MAYBE_CLASS_TYPE_P (core_type = strip_array_types (type)))
+    {
+      if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
+         || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))
+       diagnose_uninitialized_cst_or_ref_member (core_type, /*using_new=*/false,
+                                                 /*complain=*/true);
 
       check_for_uninitialized_const_var (decl);
     }
@@ -5447,16 +5552,15 @@ initialize_local_var (tree decl, tree init)
 
 /* DECL is a VAR_DECL for a compiler-generated variable with static
    storage duration (like a virtual table) whose initializer is a
-   compile-time constant.  INIT must be either a TREE_LIST of values,
-   or a CONSTRUCTOR.  Initialize the variable and provide it to the
+   compile-time constant.  Initialize the variable and provide it to the
    back end.  */
 
 void
-initialize_artificial_var (tree decl, tree init)
+initialize_artificial_var (tree decl, VEC(constructor_elt,gc) *v)
 {
+  tree init;
   gcc_assert (DECL_ARTIFICIAL (decl));
-  if (TREE_CODE (init) == TREE_LIST)
-    init = build_constructor_from_list (TREE_TYPE (decl), init);
+  init = build_constructor (TREE_TYPE (decl), v);
   gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
   DECL_INITIAL (decl) = init;
   DECL_INITIALIZED_P (decl) = 1;
@@ -5573,23 +5677,27 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (init && TREE_CODE (decl) == FUNCTION_DECL)
     {
+      tree clone;
       if (init == ridpointers[(int)RID_DELETE])
        {
          /* FIXME check this is 1st decl.  */
          DECL_DELETED_FN (decl) = 1;
          DECL_DECLARED_INLINE_P (decl) = 1;
          DECL_INITIAL (decl) = error_mark_node;
+         FOR_EACH_CLONE (clone, decl)
+           {
+             DECL_DELETED_FN (clone) = 1;
+             DECL_DECLARED_INLINE_P (clone) = 1;
+             DECL_INITIAL (clone) = error_mark_node;
+           }
          init = NULL_TREE;
        }
       else if (init == ridpointers[(int)RID_DEFAULT])
        {
-         if (!defaultable_fn_p (decl))
-           {
-             error ("%qD cannot be defaulted", decl);
-             DECL_INITIAL (decl) = NULL_TREE;
-           }
-         else
+         if (defaultable_fn_check (decl))
            DECL_DEFAULTED_FN (decl) = 1;
+         else
+           DECL_INITIAL (decl) = NULL_TREE;
        }
     }
     
@@ -5704,7 +5812,18 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       if (DECL_FUNCTION_SCOPE_P (decl)
          && TREE_STATIC (decl)
          && !DECL_ARTIFICIAL (decl))
-       push_local_name (decl);
+       {
+         push_local_name (decl);
+         if (DECL_CONSTRUCTOR_P (current_function_decl)
+             || DECL_DESTRUCTOR_P (current_function_decl))
+           /* 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.  */
+           cfun->local_decls = tree_cons (NULL_TREE, decl,
+                                          cfun->local_decls);
+       }
+
       /* Convert the initializer to the type of DECL, if we have not
         already initialized DECL.  */
       if (!DECL_INITIALIZED_P (decl)
@@ -5911,10 +6030,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (was_readonly)
     TREE_READONLY (decl) = 1;
-
-  /* If this was marked 'used', be sure it will be output.  */
-  if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
-    mark_decl_referenced (decl);
 }
 
 /* Returns a declaration for a VAR_DECL as if:
@@ -6104,6 +6219,7 @@ start_cleanup_fn (void)
       parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node);
       DECL_CONTEXT (parmdecl) = fndecl;
       TREE_USED (parmdecl) = 1;
+      DECL_READ_P (parmdecl) = 1;
       DECL_ARGUMENTS (fndecl) = parmdecl;
     }
 
@@ -6133,10 +6249,10 @@ register_dtor_fn (tree decl)
 {
   tree cleanup;
   tree compound_stmt;
-  tree args;
   tree fcall;
   tree type;
   bool use_dtor;
+  tree arg0, arg1 = NULL_TREE, arg2 = NULL_TREE;
 
   type = TREE_TYPE (decl);
   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
@@ -6214,25 +6330,23 @@ register_dtor_fn (tree decl)
           in, and, in general, it's cheaper to pass NULL than any
           other value.  */
        addr = null_pointer_node;
-      args = tree_cons (NULL_TREE,
-                       cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0,
-                                        tf_warning_or_error),
-                       NULL_TREE);
+      arg2 = cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0,
+                                tf_warning_or_error);
       if (targetm.cxx.use_aeabi_atexit ())
        {
-         args = tree_cons (NULL_TREE, cleanup, args);
-         args = tree_cons (NULL_TREE, addr, args);
+         arg1 = cleanup;
+         arg0 = addr;
        }
       else
        {
-         args = tree_cons (NULL_TREE, addr, args);
-         args = tree_cons (NULL_TREE, cleanup, args);
+         arg1 = addr;
+         arg0 = cleanup;
        }
     }
   else
-    args = tree_cons (NULL_TREE, cleanup, NULL_TREE);
-  return cp_build_function_call (get_atexit_node (), args, 
-                                tf_warning_or_error);
+    arg0 = cleanup;
+  return cp_build_function_call_nary (get_atexit_node (), tf_warning_or_error,
+                                     arg0, arg1, arg2, NULL_TREE);
 }
 
 /* DECL is a VAR_DECL with static storage duration.  INIT, if present,
@@ -6622,6 +6736,7 @@ grokfndecl (tree ctype,
     {
     case sfk_constructor:
     case sfk_copy_constructor:
+    case sfk_move_constructor:
       DECL_CONSTRUCTOR_P (decl) = 1;
       break;
     case sfk_destructor:
@@ -6678,7 +6793,7 @@ grokfndecl (tree ctype,
            }
          gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE
                      || TREE_CODE (fns) == OVERLOAD);
-         DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
+         DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args);
 
          for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
            if (TREE_PURPOSE (t)
@@ -6704,7 +6819,7 @@ grokfndecl (tree ctype,
   if (in_namespace)
     set_decl_namespace (decl, in_namespace, friendp);
   else if (!ctype)
-    DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+    DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ());
 
   /* `main' and builtins have implicit 'C' linkage.  */
   if ((MAIN_NAME_P (declarator)
@@ -6750,6 +6865,38 @@ grokfndecl (tree ctype,
                || decl_function_context (TYPE_MAIN_DECL (ctype))))
     publicp = 0;
 
+  if (publicp && cxx_dialect == cxx98)
+    {
+      /* [basic.link]: A name with no linkage (notably, the name of a class
+        or enumeration declared in a local scope) shall not be used to
+        declare an entity with linkage.
+
+        DR 757 relaxes this restriction for C++0x.  */
+      t = no_linkage_check (TREE_TYPE (decl),
+                           /*relaxed_p=*/false);
+      if (t)
+       {
+         if (TYPE_ANONYMOUS_P (t))
+           {
+             if (DECL_EXTERN_C_P (decl))
+               /* Allow this; it's pretty common in C.  */;
+             else
+               {
+                 permerror (input_location, "anonymous type with no linkage "
+                            "used to declare function %q#D with linkage",
+                            decl);
+                 if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
+                   permerror (input_location, "%q+#D does not refer to the unqualified "
+                              "type, so it is not used for linkage",
+                              TYPE_NAME (t));
+               }
+           }
+         else
+           permerror (input_location, "type %qT with no linkage used to "
+                      "declare function %q#D with linkage", t, decl);
+       }
+    }
+
   TREE_PUBLIC (decl) = publicp;
   if (! publicp)
     {
@@ -6934,7 +7081,7 @@ grokvardecl (tree type,
       /* An explicit "extern" specifier indicates a namespace-scope
         variable.  */
       if (declspecs->storage_class == sc_extern)
-       scope = current_namespace;
+       scope = current_decl_namespace ();
       else if (!at_function_scope_p ())
        scope = current_scope ();
     }
@@ -6989,15 +7136,49 @@ grokvardecl (tree type,
   if (declspecs->specs[(int)ds_thread])
     DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
 
+  /* If the type of the decl has no linkage, make sure that we'll
+     notice that in mark_used.  */
+  if (cxx_dialect > cxx98
+      && decl_linkage (decl) != lk_none
+      && DECL_LANG_SPECIFIC (decl) == NULL
+      && !DECL_EXTERN_C_P (decl)
+      && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
+    retrofit_lang_decl (decl);
+
   if (TREE_PUBLIC (decl))
     {
-      /* If the type of the decl has no linkage, make sure that we'll
-        notice that in mark_used.  */
-      if (DECL_LANG_SPECIFIC (decl) == NULL
-         && TREE_PUBLIC (decl)
-         && !DECL_EXTERN_C_P (decl)
-         && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
-       retrofit_lang_decl (decl);
+      /* [basic.link]: A name with no linkage (notably, the name of a class
+        or enumeration declared in a local scope) shall not be used to
+        declare an entity with linkage.
+
+        DR 757 relaxes this restriction for C++0x.  */
+      tree t = (cxx_dialect > cxx98 ? NULL_TREE
+               : no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false));
+      if (t)
+       {
+         if (TYPE_ANONYMOUS_P (t))
+           {
+             if (DECL_EXTERN_C_P (decl))
+               /* Allow this; it's pretty common in C.  */
+               ;
+             else
+               {
+                 /* DRs 132, 319 and 389 seem to indicate types with
+                    no linkage can only be used to declare extern "C"
+                    entities.  Since it's not always an error in the
+                    ISO C++ 90 Standard, we only issue a warning.  */
+                 warning (0, "anonymous type with no linkage used to declare "
+                          "variable %q#D with linkage", decl);
+                 if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
+                   warning (0, "%q+#D does not refer to the unqualified "
+                            "type, so it is not used for linkage",
+                            TYPE_NAME (t));
+               }
+           }
+         else
+           warning (0, "type %qT with no linkage used to declare variable "
+                    "%q#D with linkage", t, decl);
+       }
     }
   else
     DECL_INTERFACE_KNOWN (decl) = 1;
@@ -7089,16 +7270,8 @@ build_ptrmem_type (tree class_type, tree member_type)
 {
   if (TREE_CODE (member_type) == METHOD_TYPE)
     {
-      tree arg_types;
-
-      arg_types = TYPE_ARG_TYPES (member_type);
-      class_type = (cp_build_qualified_type
-                   (class_type,
-                    cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)))));
-      member_type
-       = build_method_type_directly (class_type,
-                                     TREE_TYPE (member_type),
-                                     TREE_CHAIN (arg_types));
+      cp_cv_quals quals = type_memfn_quals (member_type);
+      member_type = build_memfn_type (member_type, class_type, quals);
       return build_ptrmemfunc_type (build_pointer_type (member_type));
     }
   else
@@ -7181,11 +7354,8 @@ compute_array_index_type (tree name, tree size)
         structural equality checks.  */
       itype = build_index_type (build_min (MINUS_EXPR, sizetype,
                                           size, integer_one_node));
-      if (!TREE_SIDE_EFFECTS (size))
-       {
-         TYPE_DEPENDENT_P (itype) = 1;
-         TYPE_DEPENDENT_P_VALID (itype) = 1;
-       }
+      TYPE_DEPENDENT_P (itype) = 1;
+      TYPE_DEPENDENT_P_VALID (itype) = 1;
       SET_TYPE_STRUCTURAL_EQUALITY (itype);
       return itype;
     }
@@ -7203,8 +7373,12 @@ compute_array_index_type (tree name, tree size)
   /* The size might be the result of a cast.  */
   STRIP_TYPE_NOPS (size);
 
+  size = mark_rvalue_use (size);
+
   /* It might be a const variable or enumeration constant.  */
   size = integral_constant_value (size);
+  if (error_operand_p (size))
+    return error_mark_node;
 
   /* Normally, the array-bound will be a constant.  */
   if (TREE_CODE (size) == INTEGER_CST)
@@ -7334,47 +7508,45 @@ static tree
 create_array_type_for_decl (tree name, tree type, tree size)
 {
   tree itype = NULL_TREE;
-  const char* error_msg;
 
   /* If things have already gone awry, bail now.  */
   if (type == error_mark_node || size == error_mark_node)
     return error_mark_node;
 
-  /* Assume that everything will go OK.  */
-  error_msg = NULL;
-
-  /* There are some types which cannot be array elements.  */
+  /* If there are some types which cannot be array elements,
+     issue an error-message and return.  */
   switch (TREE_CODE (type))
     {
     case VOID_TYPE:
-      error_msg = "array of void";
-      break;
+      if (name)
+        error ("declaration of %qD as array of void", name);
+      else
+        error ("creating array of void");
+      return error_mark_node;
 
     case FUNCTION_TYPE:
-      error_msg = "array of functions";
-      break;
+      if (name)
+        error ("declaration of %qD as array of functions", name);
+      else
+        error ("creating array of functions");
+      return error_mark_node;
 
     case REFERENCE_TYPE:
-      error_msg = "array of references";
-      break;
+      if (name)
+        error ("declaration of %qD as array of references", name);
+      else
+        error ("creating array of references");
+      return error_mark_node;
 
     case METHOD_TYPE:
-      error_msg = "array of function members";
-      break;
-
-    default:
-      break;
-    }
-
-  /* If something went wrong, issue an error-message and return.  */
-  if (error_msg)
-    {
       if (name)
-       error ("declaration of %qD as %s", name, error_msg);
+        error ("declaration of %qD as array of function members", name);
       else
-       error ("creating %s", error_msg);
-
+        error ("creating array of function members");
       return error_mark_node;
+
+    default:
+      break;
     }
 
   /* [dcl.array]
@@ -7500,11 +7672,13 @@ check_var_type (tree identifier, tree type)
       try to parse.
      PARM for a parameter declaration (either within a function prototype
       or before a function body).  Make a PARM_DECL, or return void_type_node.
+     TPARM for a template parameter declaration.
      CATCHPARM for a parameter declaration before a catch clause.
      TYPENAME if for a typename (in a cast or sizeof).
       Don't make a DECL node; just return the ..._TYPE node.
      FIELD for a struct or union field; make a FIELD_DECL.
      BITFIELD for a field with specified width.
+
    INITIALIZED is as for start_decl.
 
    ATTRLIST is a pointer to the list of attributes, which may be NULL
@@ -7534,6 +7708,7 @@ grokdeclarator (const cp_declarator *declarator,
 {
   tree type = NULL_TREE;
   int longlong = 0;
+  int explicit_int128 = 0;
   int virtualp, explicitp, friendp, inlinep, staticp;
   int explicit_int = 0;
   int explicit_char = 0;
@@ -7588,6 +7763,8 @@ grokdeclarator (const cp_declarator *declarator,
   bool type_was_error_mark_node = false;
   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];
   const char *errmsg;
 
   signed_p = declspecs->specs[(int)ds_signed];
@@ -7595,6 +7772,7 @@ grokdeclarator (const cp_declarator *declarator,
   short_p = declspecs->specs[(int)ds_short];
   long_p = declspecs->specs[(int)ds_long];
   longlong = declspecs->specs[(int)ds_long] >= 2;
+  explicit_int128 = declspecs->explicit_int128_p;
   thread_p = declspecs->specs[(int)ds_thread];
 
   if (decl_context == FUNCDEF)
@@ -7605,6 +7783,8 @@ grokdeclarator (const cp_declarator *declarator,
     bitfield = 1, decl_context = FIELD;
   else if (decl_context == TEMPLATE_TYPE_ARG)
     template_type_arg = true, decl_context = TYPENAME;
+  else if (decl_context == TPARM)
+    template_parm_flag = true, decl_context = PARM;
 
   if (initialized > 1)
     funcdef_flag = true;
@@ -7905,8 +8085,8 @@ grokdeclarator (const cp_declarator *declarator,
   if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node)
     {
       long_p = false;
-      type = build_qualified_type (long_double_type_node,
-                                  cp_type_quals (type));
+      type = cp_build_qualified_type (long_double_type_node,
+                                     cp_type_quals (type));
     }
 
   /* Check all other uses of type modifiers.  */
@@ -7921,12 +8101,16 @@ grokdeclarator (const cp_declarator *declarator,
        error ("%<signed%> and %<unsigned%> specified together for %qs", name);
       else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<long long%> invalid for %qs", name);
+      else if (explicit_int128 && TREE_CODE (type) != INTEGER_TYPE)
+       error ("%<__int128%> invalid for %qs", name);
       else if (long_p && TREE_CODE (type) == REAL_TYPE)
        error ("%<long%> invalid for %qs", name);
       else if (short_p && TREE_CODE (type) == REAL_TYPE)
        error ("%<short%> invalid for %qs", name);
       else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<long%> or %<short%> invalid for %qs", name);
+      else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128)
+       error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", name);
       else if ((long_p || short_p) && explicit_char)
        error ("%<long%> or %<short%> specified with char for %qs", name);
       else if (long_p && short_p)
@@ -7941,7 +8125,7 @@ grokdeclarator (const cp_declarator *declarator,
       else
        {
          ok = 1;
-         if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
+         if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic)
            {
              pedwarn (input_location, OPT_pedantic, 
                       "long, short, signed or unsigned used invalidly for %qs",
@@ -7949,6 +8133,22 @@ grokdeclarator (const cp_declarator *declarator,
              if (flag_pedantic_errors)
                ok = 0;
            }
+         if (explicit_int128)
+           {
+             if (int128_integer_type_node == NULL_TREE)
+               {
+                 error ("%<__int128%> is not supported by this target");
+                 ok = 0;
+               }
+             else if (pedantic)
+               {
+                 pedwarn (input_location, OPT_pedantic,
+                          "ISO C++ does not support %<__int128%> for %qs",
+                          name);
+                 if (flag_pedantic_errors)
+                   ok = 0;
+               }
+           }
        }
 
       /* Discard the type modifiers if they are invalid.  */
@@ -7959,6 +8159,7 @@ grokdeclarator (const cp_declarator *declarator,
          long_p = false;
          short_p = false;
          longlong = 0;
+         explicit_int128 = false;
        }
     }
 
@@ -7983,7 +8184,9 @@ grokdeclarator (const cp_declarator *declarator,
          && TREE_CODE (type) == INTEGER_TYPE
          && !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node)))
     {
-      if (longlong)
+      if (explicit_int128)
+       type = int128_unsigned_type_node;
+      else if (longlong)
        type = long_long_unsigned_type_node;
       else if (long_p)
        type = long_unsigned_type_node;
@@ -7998,6 +8201,8 @@ grokdeclarator (const cp_declarator *declarator,
     }
   else if (signed_p && type == char_type_node)
     type = signed_char_type_node;
+  else if (explicit_int128)
+    type = int128_integer_type_node;
   else if (longlong)
     type = long_long_integer_type_node;
   else if (long_p)
@@ -8013,8 +8218,7 @@ grokdeclarator (const cp_declarator *declarator,
         "complex double", but if any modifiers at all are specified it is
         the complex form of TYPE.  E.g, "complex short" is
         "complex short int".  */
-
-      else if (defaulted_int && ! longlong
+      else if (defaulted_int && ! longlong && ! explicit_int128
               && ! (long_p || short_p || signed_p || unsigned_p))
        type = complex_double_type_node;
       else if (type == integer_type_node)
@@ -8032,6 +8236,17 @@ grokdeclarator (const cp_declarator *declarator,
   type_quals = TYPE_UNQUALIFIED;
   if (declspecs->specs[(int)ds_const])
     type_quals |= TYPE_QUAL_CONST;
+  /* A `constexpr' specifier used in an object declaration declares
+     the object as `const'.  */
+  if (constexpr_p)
+    {
+      if (innermost_code == cdk_function)
+        ;
+      else if (declspecs->specs[(int)ds_const] != 0)
+        error ("both %<const%> and %<constexpr%> cannot be used here");
+      else
+        type_quals |= TYPE_QUAL_CONST;
+    }
   if (declspecs->specs[(int)ds_volatile])
     type_quals |= TYPE_QUAL_VOLATILE;
   if (declspecs->specs[(int)ds_restrict])
@@ -8040,21 +8255,6 @@ grokdeclarator (const cp_declarator *declarator,
     error ("qualifiers are not allowed on declaration of %<operator %T%>",
           ctor_return_type);
 
-  if (TREE_CODE (type) == FUNCTION_TYPE
-      && type_quals != TYPE_UNQUALIFIED)
-    {
-      /* This was an error in C++98 (cv-qualifiers cannot be added to
-        a function type), but DR 295 makes the code well-formed by
-        dropping the extra qualifiers. */
-      if (pedantic)
-       {
-         tree bad_type = build_qualified_type (type, type_quals);
-         pedwarn (input_location, OPT_pedantic, 
-                  "ignoring %qV qualifiers added to function type %qT",
-                  bad_type, type);
-       }
-      type_quals = TYPE_UNQUALIFIED;
-    }
   type_quals |= cp_type_quals (type);
   type = cp_build_qualified_type_real
     (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
@@ -8093,6 +8293,11 @@ grokdeclarator (const cp_declarator *declarator,
          error ("typedef declaration invalid in parameter declaration");
          return error_mark_node;
        }
+      else if (template_parm_flag && storage_class != sc_none)
+       {
+         error ("storage class specified for template parameter %qs", name);
+         return error_mark_node;
+       }
       else if (storage_class == sc_static
               || storage_class == sc_extern
               || thread_p)
@@ -8103,6 +8308,14 @@ grokdeclarator (const cp_declarator *declarator,
          error ("parameter declared %<auto%>");
          type = error_mark_node;
        }
+
+      /* Function parameters cannot be constexpr.  If we saw one, moan
+         and pretend it wasn't there.  */
+      if (constexpr_p)
+        {
+          error ("a parameter cannot be declared %<constexpr%>");
+          constexpr_p = 0;
+        }
     }
 
   /* Give error if `virtual' is used outside of class declaration.  */
@@ -8405,11 +8618,26 @@ grokdeclarator (const cp_declarator *declarator,
              {
                if (explicitp == 1)
                  {
-                   maybe_warn_cpp0x ("explicit conversion operators");
+                   maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
                    explicitp = 2;
                  }
              }
 
+            /* It is not allowed to use `constexpr' in a function
+               declaration that is not a definition.
+               That is too strict, though.  */
+            if (constexpr_p && !funcdef_flag)
+              {
+                error ("the %<constexpr%> specifier cannot be used in "
+                       "a function declaration that is not a definition");
+                constexpr_p = false;
+              }
+
+            /* A constexpr non-static member function is implicitly const.  */
+            if (constexpr_p && decl_context == FIELD && staticp == 0
+                && sfk != sfk_constructor && sfk != sfk_destructor)
+              memfn_quals |= TYPE_QUAL_CONST;
+
            arg_types = grokparms (declarator->u.function.parameters,
                                   &parms);
 
@@ -8470,7 +8698,7 @@ grokdeclarator (const cp_declarator *declarator,
              && (TREE_CODE (type) == FUNCTION_TYPE
                  || (memfn_quals && TREE_CODE (type) == METHOD_TYPE)))
            {
-             memfn_quals |= cp_type_quals (type);
+             memfn_quals |= type_memfn_quals (type);
              type = build_memfn_type (type,
                                       declarator->u.pointer.class_type,
                                       memfn_quals);
@@ -8478,11 +8706,40 @@ grokdeclarator (const cp_declarator *declarator,
            }
 
          if (TREE_CODE (type) == FUNCTION_TYPE
-             && cp_type_quals (type) != TYPE_UNQUALIFIED)
-           error ("cannot declare %s to qualified function type %qT",
-                  declarator->kind == cdk_reference ? "reference" : "pointer",
+             && type_memfn_quals (type) != TYPE_UNQUALIFIED)
+            error (declarator->kind == cdk_reference
+                   ? G_("cannot declare reference to qualified function type %qT")
+                   : G_("cannot declare pointer to qualified function type %qT"),
                   type);
 
+         /* When the pointed-to type involves components of variable size,
+            care must be taken to ensure that the size evaluation code is
+            emitted early enough to dominate all the possible later uses
+            and late enough for the variables on which it depends to have
+            been assigned.
+
+            This is expected to happen automatically when the pointed-to
+            type has a name/declaration of it's own, but special attention
+            is required if the type is anonymous.
+
+            We handle the NORMAL and FIELD contexts here by inserting a
+            dummy statement that just evaluates the size at a safe point
+            and ensures it is not deferred until e.g. within a deeper
+            conditional context (c++/43555).
+
+            We expect nothing to be needed here for PARM or TYPENAME.
+            Evaluating the size at this point for TYPENAME would
+            actually be incorrect, as we might be in the middle of an
+            expression with side effects on the pointed-to type size
+            "arguments" prior to the pointer declaration point and the
+            size evaluation could end up prior to the side effects.  */
+
+         if (!TYPE_NAME (type)
+             && (decl_context == NORMAL || decl_context == FIELD)
+             && at_function_scope_p ()
+             && variably_modified_type_p (type, NULL_TREE))
+           finish_expr_stmt (TYPE_SIZE (type));
+
          if (declarator->kind == cdk_reference)
            {
              /* In C++0x, the type we are creating a reference to might be
@@ -8654,6 +8911,12 @@ grokdeclarator (const cp_declarator *declarator,
              return error_mark_node;
            }
 
+          /* It is not permitted to define a member function outside ist
+             membership class as `constexpr'.  */
+          if (constexpr_p)
+            error ("a constexpr function cannot be defined "
+                   "outside of its class");
+
          if (TREE_CODE (sname) == IDENTIFIER_NODE
              && NEW_DELETE_OPNAME_P (sname))
            /* Overloaded operator new and operator delete
@@ -8774,7 +9037,7 @@ grokdeclarator (const cp_declarator *declarator,
         function type.  */
       if (memfn_quals && TREE_CODE (type) == FUNCTION_TYPE)
         {
-          type = cp_build_qualified_type (type, memfn_quals);
+          type = apply_memfn_quals (type, memfn_quals);
           
           /* We have now dealt with these qualifiers.  */
           memfn_quals = TYPE_UNQUALIFIED;
@@ -8825,10 +9088,12 @@ grokdeclarator (const cp_declarator *declarator,
          for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
            {
              if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
-               {
-                 debug_hooks->set_name (t, decl);
-                 TYPE_NAME (t) = decl;
-               }
+               /* We do not rename the debug info representing the
+                  anonymous tagged type because the standard says in
+                  [dcl.typedef] that the naming applies only for
+                  linkage purposes.  */
+               /*debug_hooks->set_name (t, decl);*/
+               TYPE_NAME (t) = decl;
            }
 
          if (TYPE_LANG_SPECIFIC (type))
@@ -8878,7 +9143,9 @@ grokdeclarator (const cp_declarator *declarator,
       tree decls = NULL_TREE;
       tree args;
 
-      for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args))
+      for (args = TYPE_ARG_TYPES (type);
+          args && args != void_list_node;
+          args = TREE_CHAIN (args))
        {
          tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args));
 
@@ -8892,7 +9159,7 @@ grokdeclarator (const cp_declarator *declarator,
        {
          /* A cv-qualifier-seq shall only be part of the function type
             for a non-static member function. [8.3.5/4 dcl.fct] */
-         if (cp_type_quals (type) != TYPE_UNQUALIFIED
+         if (type_memfn_quals (type) != TYPE_UNQUALIFIED
              && (current_class_type == NULL_TREE || staticp) )
            {
              error (staticp
@@ -8905,7 +9172,8 @@ grokdeclarator (const cp_declarator *declarator,
 
          /* The qualifiers on the function type become the qualifiers on
             the non-static member function. */
-         memfn_quals |= cp_type_quals (type);
+         memfn_quals |= type_memfn_quals (type);
+         type_quals = TYPE_UNQUALIFIED;
        }
     }
 
@@ -8972,7 +9240,7 @@ grokdeclarator (const cp_declarator *declarator,
            type = build_memfn_type (type, ctype, memfn_quals);
          /* Core issue #547: need to allow this in template type args.  */
          else if (template_type_arg && TREE_CODE (type) == FUNCTION_TYPE)
-           type = cp_build_qualified_type (type, memfn_quals);
+           type = apply_memfn_quals (type, memfn_quals);
          else
            error ("invalid qualifiers on non-member function type");
        }
@@ -9121,6 +9389,8 @@ grokdeclarator (const cp_declarator *declarator,
                           uqname, ctype);
                    return error_mark_node;
                  }
+                if (constexpr_p)
+                  error ("a destructor cannot be %<constexpr%>");
              }
            else if (sfk == sfk_constructor && friendp)
              {
@@ -9141,7 +9411,8 @@ grokdeclarator (const cp_declarator *declarator,
                               parms,
                               unqualified_id,
                               virtualp, flags, memfn_quals, raises,
-                              friendp ? -1 : 0, friendp, publicp, inlinep,
+                              friendp ? -1 : 0, friendp, publicp,
+                               inlinep || constexpr_p,
                               sfk,
                               funcdef_flag, template_count, in_namespace,
                               attrlist, declarator->id_loc);
@@ -9230,6 +9501,7 @@ grokdeclarator (const cp_declarator *declarator,
                      return error_mark_node;
                  }
 
+                DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
                decl = do_friend (ctype, unqualified_id, decl,
                                  *attrlist, flags,
                                  funcdef_flag);
@@ -9294,6 +9566,9 @@ grokdeclarator (const cp_declarator *declarator,
              }
            else
              {
+                if (constexpr_p)
+                  error ("non-static data member %qE declared %<constexpr%>",
+                         unqualified_id);
                decl = build_decl (input_location,
                                   FIELD_DECL, unqualified_id, type);
                DECL_NONADDRESSABLE_P (decl) = bitfield;
@@ -9388,7 +9663,7 @@ grokdeclarator (const cp_declarator *declarator,
        decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
                           virtualp, flags, memfn_quals, raises,
                           1, friendp,
-                          publicp, inlinep, sfk, funcdef_flag,
+                          publicp, inlinep || constexpr_p, sfk, funcdef_flag,
                           template_count, in_namespace, attrlist,
                           declarator->id_loc);
        if (decl == NULL_TREE)
@@ -9485,6 +9760,10 @@ grokdeclarator (const cp_declarator *declarator,
     else if (storage_class == sc_static)
       DECL_THIS_STATIC (decl) = 1;
 
+    /* Don't forget constexprness.  */
+    if (VAR_OR_FUNCTION_DECL_P (decl))
+      DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
+
     /* Record constancy and volatility on the DECL itself .  There's
        no need to do this when processing a template; we'll do this
        for the instantiated declaration based on the type of DECL.  */
@@ -9632,6 +9911,10 @@ type_is_deprecated (tree type)
       && TREE_DEPRECATED (TYPE_NAME (type)))
     return type;
 
+  /* Do warn about using typedefs to a deprecated class.  */
+  if (TAGGED_TYPE_P (type) && type != TYPE_MAIN_VARIANT (type))
+    return type_is_deprecated (TYPE_MAIN_VARIANT (type));
+
   code = TREE_CODE (type);
 
   if (code == POINTER_TYPE || code == REFERENCE_TYPE
@@ -9748,9 +10031,12 @@ grokparms (tree parmlist, tree *parms)
                  t = TREE_TYPE (t);
                }
              if (TREE_CODE (t) == ARRAY_TYPE)
-               error ("parameter %qD includes %s to array of unknown "
-                      "bound %qT",
-                      decl, ptr ? "pointer" : "reference", t);
+               error (ptr
+                       ? G_("parameter %qD includes pointer to array of "
+                            "unknown bound %qT")
+                       : G_("parameter %qD includes reference to array of "
+                            "unknown bound %qT"),
+                       decl, t);
            }
 
          if (any_error)
@@ -9789,9 +10075,9 @@ grokparms (tree parmlist, tree *parms)
    0  if D is not a copy constructor or copy assignment
       operator.
    1  if D is a copy constructor or copy assignment operator whose
-      first parameter is a reference to const qualified T.
-   2  if D is a copy constructor or copy assignment operator whose
       first parameter is a reference to non-const qualified T.
+   2  if D is a copy constructor or copy assignment operator whose
+      first parameter is a reference to const qualified T.
 
    This function can be used as a predicate. Positive values indicate
    a copy constructor and nonzero values indicate a copy assignment
@@ -9926,7 +10212,7 @@ grok_special_member_properties (tree decl)
             are no other parameters or else all other parameters have
             default arguments.  */
          TYPE_HAS_INIT_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
+         if (user_provided_p (decl))
            TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1;
          if (ctor > 1)
            TYPE_HAS_CONST_INIT_REF (class_type) = 1;
@@ -9934,7 +10220,7 @@ grok_special_member_properties (tree decl)
       else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
        {
          TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
-         if (TREE_CODE (decl) == TEMPLATE_DECL || !DECL_DEFAULTED_FN (decl))
+         if (user_provided_p (decl))
            TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
        }
       else if (is_list_ctor (decl))
@@ -9953,7 +10239,7 @@ grok_special_member_properties (tree decl)
       if (assop)
        {
          TYPE_HAS_ASSIGN_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
+         if (user_provided_p (decl))
            TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1;
          if (assop != 1)
            TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
@@ -10192,28 +10478,38 @@ grok_op_properties (tree decl, bool complain)
        {
          tree t = TREE_TYPE (name);
          int ref = (TREE_CODE (t) == REFERENCE_TYPE);
-         const char *what = 0;
 
          if (ref)
            t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
 
          if (TREE_CODE (t) == VOID_TYPE)
-           what = "void";
+            warning (OPT_Wconversion,
+                     ref
+                     ? G_("conversion to a reference to void "
+                          "will never use a type conversion operator")
+                     : G_("conversion to void "
+                          "will never use a type conversion operator"));
          else if (class_type)
            {
              if (t == class_type)
-               what = "the same type";
+                warning (OPT_Wconversion,
+                     ref
+                     ? G_("conversion to a reference to the same type "
+                          "will never use a type conversion operator")
+                     : G_("conversion to the same type "
+                          "will never use a type conversion operator"));               
              /* Don't force t to be complete here.  */
              else if (MAYBE_CLASS_TYPE_P (t)
                       && COMPLETE_TYPE_P (t)
                       && DERIVED_FROM_P (t, class_type))
-               what = "a base class";
+                 warning (OPT_Wconversion,
+                          ref
+                          ? G_("conversion to a reference to a base class "
+                               "will never use a type conversion operator")
+                          : G_("conversion to a base class "
+                               "will never use a type conversion operator"));          
            }
 
-         if (what)
-           warning (OPT_Wconversion, "conversion to %s%s will never use a type "
-                    "conversion operator",
-                    ref ? "a reference to " : "", what);
        }
 
       if (operator_code == COND_EXPR)
@@ -10448,6 +10744,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
      elaborated type specifier is the implicit typedef created when
      the type is declared.  */
   else if (!DECL_IMPLICIT_TYPEDEF_P (decl)
+          && !DECL_SELF_REFERENCE_P (decl)
           && tag_code != typename_type)
     {
       error ("using typedef-name %qD after %qs", decl, tag_name (tag_code));
@@ -10789,7 +11086,12 @@ xref_basetypes (tree ref, tree base_list)
 
   /* The binfo slot should be empty, unless this is an (ill-formed)
      redefinition.  */
-  gcc_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref));
+  if (TYPE_BINFO (ref) && !TYPE_SIZE (ref))
+    {
+      error ("redefinition of %q#T", ref);
+      return false;
+    }
+
   gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);
 
   binfo = make_tree_binfo (max_bases);
@@ -10981,7 +11283,7 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p)
       if (enumtype == error_mark_node)
        name = make_anon_name ();
 
-      enumtype = make_node (ENUMERAL_TYPE);
+      enumtype = cxx_make_type (ENUMERAL_TYPE);
       enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
     }
 
@@ -11037,12 +11339,6 @@ finish_enum (tree enumtype)
   tree maxnode;
   tree value;
   tree t;
-  bool unsignedp;
-  bool use_short_enum;
-  int lowprec;
-  int highprec;
-  int precision;
-  unsigned int itk;
   tree underlying_type = NULL_TREE;
   bool fixed_underlying_type_p 
     = ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE;
@@ -11105,17 +11401,19 @@ finish_enum (tree enumtype)
        the enumeration had a single enumerator with value 0.  */
     minnode = maxnode = integer_zero_node;
 
-  /* Compute the number of bits require to represent all values of the
-     enumeration.  We must do this before the type of MINNODE and
-     MAXNODE are transformed, since tree_int_cst_min_precision relies
-     on the TREE_TYPE of the value it is passed.  */
-  unsignedp = tree_int_cst_sgn (minnode) >= 0;
-  lowprec = tree_int_cst_min_precision (minnode, unsignedp);
-  highprec = tree_int_cst_min_precision (maxnode, unsignedp);
-  precision = MAX (lowprec, highprec);
-
   if (!fixed_underlying_type_p)
     {
+      /* Compute the number of bits require to represent all values of the
+        enumeration.  We must do this before the type of MINNODE and
+        MAXNODE are transformed, since tree_int_cst_min_precision relies
+        on the TREE_TYPE of the value it is passed.  */
+      bool unsignedp = tree_int_cst_sgn (minnode) >= 0;
+      int lowprec = tree_int_cst_min_precision (minnode, unsignedp);
+      int highprec = tree_int_cst_min_precision (maxnode, unsignedp);
+      int precision = MAX (lowprec, highprec);
+      unsigned int itk;
+      bool use_short_enum;
+
       /* Determine the underlying type of the enumeration.
 
          [dcl.enum]
@@ -11141,7 +11439,8 @@ finish_enum (tree enumtype)
            itk++)
         {
           underlying_type = integer_types[itk];
-          if (TYPE_PRECISION (underlying_type) >= precision
+          if (underlying_type != NULL_TREE
+             && TYPE_PRECISION (underlying_type) >= precision
               && TYPE_UNSIGNED (underlying_type) == unsignedp)
             break;
         }
@@ -11162,43 +11461,51 @@ finish_enum (tree enumtype)
          The value of sizeof() applied to an enumeration type, an object
          of an enumeration type, or an enumerator, is the value of sizeof()
          applied to the underlying type.  */
+      TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (underlying_type);
+      TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (underlying_type);
       TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
       TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
       SET_TYPE_MODE (enumtype, TYPE_MODE (underlying_type));
+      TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
       TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
       TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
       TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
 
-      /* Set the underlying type of the enumeration type to the
-         computed enumeration type, restricted to the enumerator
-         values. */
+      /* Compute the minimum and maximum values for the type.
+
+        [dcl.enum]
+
+        For an enumeration where emin is the smallest enumerator and emax
+        is the largest, the values of the enumeration are the values of the
+        underlying type in the range bmin to bmax, where bmin and bmax are,
+        respectively, the smallest and largest values of the smallest bit-
+        field that can store emin and emax.  */
+
+      /* The middle-end currently assumes that types with TYPE_PRECISION
+        narrower than their underlying type are suitably zero or sign
+        extended to fill their mode.  Similarly, it assumes that the front
+        end assures that a value of a particular type must be within
+        TYPE_MIN_VALUE and TYPE_MAX_VALUE.
+
+        We used to set these fields based on bmin and bmax, but that led
+        to invalid assumptions like optimizing away bounds checking.  So
+        now we just set the TYPE_PRECISION, TYPE_MIN_VALUE, and
+        TYPE_MAX_VALUE to the values for the mode above and only restrict
+        the ENUM_UNDERLYING_TYPE for the benefit of diagnostics.  */
       ENUM_UNDERLYING_TYPE (enumtype)
        = build_distinct_type_copy (underlying_type);
-      set_min_and_max_values_for_integral_type 
+      TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision;
+      set_min_and_max_values_for_integral_type
         (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
+
+      /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE.  */
+      if (flag_strict_enums)
+       set_min_and_max_values_for_integral_type (enumtype, precision,
+                                                 unsignedp);
     }
   else
     underlying_type = ENUM_UNDERLYING_TYPE (enumtype);
 
-  /* Compute the minimum and maximum values for the type.
-
-     [dcl.enum]
-
-     For an enumeration where emin is the smallest enumerator and emax
-     is the largest, the values of the enumeration are the values of the
-     underlying type in the range bmin to bmax, where bmin and bmax are,
-     respectively, the smallest and largest values of the smallest bit-
-     field that can store emin and emax.  */
-  
-  /* The middle-end currently assumes that types with TYPE_PRECISION
-     narrower than their underlying type are suitably zero or sign
-     extended to fill their mode.  g++ doesn't make these guarantees.
-     Until the middle-end can represent such paradoxical types, we
-     set the TYPE_PRECISION to the width of the underlying type.  */
-  TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
-  
-  set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp);
-  
   /* Convert each of the enumerators to the type of the underlying
      type of the enumeration.  */
   for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
@@ -11413,7 +11720,7 @@ lookup_enumerator (tree enumtype, tree name)
 }
 
 \f
-/* We're defining DECL.  Make sure that it's type is OK.  */
+/* We're defining DECL.  Make sure that its type is OK.  */
 
 static void
 check_function_type (tree decl, tree current_function_parms)
@@ -11424,6 +11731,10 @@ 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);
 
+  /* constexpr functions must have literal argument types and
+     literal return type.  */
+  validate_constexpr_fundecl (decl);
+
   if (dependent_type_p (return_type))
     return;
   if (!COMPLETE_OR_VOID_TYPE_P (return_type)
@@ -11443,9 +11754,12 @@ check_function_type (tree decl, tree current_function_parms)
                                             TREE_CHAIN (args));
       else
        fntype = build_function_type (void_type_node, args);
-      TREE_TYPE (decl)
+      fntype
        = build_exception_variant (fntype,
                                   TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)));
+      fntype = (cp_build_type_attribute_variant
+               (fntype, TYPE_ATTRIBUTES (TREE_TYPE (decl))));
+      TREE_TYPE (decl) = fntype;
     }
   else
     abstract_virtuals_error (decl, TREE_TYPE (fntype));
@@ -11730,7 +12044,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       gcc_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE);
 
       cp_function_chain->x_current_class_ref
-       = cp_build_indirect_ref (t, NULL, tf_warning_or_error);
+       = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
       cp_function_chain->x_current_class_ptr = t;
 
       /* Constructors and destructors need to know whether they're "in
@@ -11820,9 +12134,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
       if ((DECL_DECLARED_INLINE_P (decl1)
           || DECL_TEMPLATE_INSTANTIATION (decl1))
-         && ! DECL_INTERFACE_KNOWN (decl1)
-         /* Don't try to defer nested functions for now.  */
-         && ! decl_function_context (decl1))
+         && ! DECL_INTERFACE_KNOWN (decl1))
        DECL_DEFER_OUTPUT (decl1) = 1;
       else
        DECL_INTERFACE_KNOWN (decl1) = 1;
@@ -11898,7 +12210,7 @@ use_eh_spec_block (tree fn)
 {
   return (flag_exceptions && flag_enforce_eh_specs
          && !processing_template_decl
-         && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))
+         && !type_throw_all_p (TREE_TYPE (fn))
          /* We insert the EH_SPEC_BLOCK only in the original
             function; then, it is copied automatically to the
             clones.  */
@@ -12352,6 +12664,8 @@ finish_function (int flags)
       && !current_function_returns_value && !current_function_returns_null
       /* Don't complain if we abort or throw.  */
       && !current_function_returns_abnormally
+      /* Don't complain if we are declared noreturn.  */
+      && !TREE_THIS_VOLATILE (fndecl)
       && !DECL_NAME (DECL_RESULT (fndecl))
       && !TREE_NO_WARNING (fndecl)
       /* Structor return values (if any) are set by the compiler.  */
@@ -12367,11 +12681,38 @@ finish_function (int flags)
      info for the epilogue.  */
   cfun->function_end_locus = input_location;
 
+  /* Complain about parameters that are only set, but never otherwise used.  */
+  if (warn_unused_but_set_parameter
+      && !processing_template_decl
+      && errorcount == unused_but_set_errorcount
+      && !DECL_CLONED_FUNCTION_P (fndecl))
+    {
+      tree decl;
+
+      for (decl = DECL_ARGUMENTS (fndecl);
+          decl;
+          decl = TREE_CHAIN (decl))
+       if (TREE_USED (decl)
+           && TREE_CODE (decl) == PARM_DECL
+           && !DECL_READ_P (decl)
+           && DECL_NAME (decl)
+           && !DECL_ARTIFICIAL (decl)
+           && !TREE_NO_WARNING (decl)
+           && !DECL_IN_SYSTEM_HEADER (decl)
+           && TREE_TYPE (decl) != error_mark_node
+           && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
+           && (!CLASS_TYPE_P (TREE_TYPE (decl))
+               || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+         warning (OPT_Wunused_but_set_parameter,
+                  "parameter %q+D set but not used", decl);
+      unused_but_set_errorcount = errorcount;
+    }
+
   /* Genericize before inlining.  */
   if (!processing_template_decl)
     {
       struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl);
-      invoke_plugin_callbacks (PLUGIN_CXX_CP_PRE_GENERICIZE, fndecl);
+      invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
       cp_genericize (fndecl);
       /* Clear out the bits we don't need.  */
       f->x_current_class_ptr = NULL;
@@ -12604,9 +12945,8 @@ cxx_maybe_build_cleanup (tree decl)
       fn = lookup_name (id);
       arg = build_address (decl);
       mark_used (decl);
-      cleanup = cp_build_function_call (fn, build_tree_list (NULL_TREE,
-                                                            arg),
-                                       tf_warning_or_error);
+      cleanup = cp_build_function_call_nary (fn, tf_warning_or_error,
+                                            arg, NULL_TREE);
     }
   /* Handle ordinary C++ destructors.  */
   type = TREE_TYPE (decl);
@@ -12645,26 +12985,45 @@ finish_stmt (void)
 {
 }
 
+/* Return the FUNCTION_TYPE that corresponds to MEMFNTYPE, which can be a
+   FUNCTION_DECL, METHOD_TYPE, FUNCTION_TYPE, pointer or reference to
+   METHOD_TYPE or FUNCTION_TYPE, or pointer to member function.  */
+
+tree
+static_fn_type (tree memfntype)
+{
+  tree fntype;
+  tree args;
+
+  if (TYPE_PTRMEMFUNC_P (memfntype))
+    memfntype = TYPE_PTRMEMFUNC_FN_TYPE (memfntype);
+  if (POINTER_TYPE_P (memfntype)
+      || TREE_CODE (memfntype) == FUNCTION_DECL)
+    memfntype = TREE_TYPE (memfntype);
+  if (TREE_CODE (memfntype) == FUNCTION_TYPE)
+    return memfntype;
+  gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE);
+  args = TYPE_ARG_TYPES (memfntype);
+  fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args));
+  fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype));
+  fntype = (cp_build_type_attribute_variant
+           (fntype, TYPE_ATTRIBUTES (memfntype)));
+  fntype = (build_exception_variant
+           (fntype, TYPE_RAISES_EXCEPTIONS (memfntype)));
+  return fntype;
+}
+
 /* DECL was originally constructed as a non-static member function,
    but turned out to be static.  Update it accordingly.  */
 
 void
 revert_static_member_fn (tree decl)
 {
-  tree tmp;
-  tree function = TREE_TYPE (decl);
-  tree args = TYPE_ARG_TYPES (function);
+  TREE_TYPE (decl) = static_fn_type (decl);
 
-  if (cp_type_quals (TREE_TYPE (TREE_VALUE (args)))
-      != TYPE_UNQUALIFIED)
+  if (cp_type_quals (TREE_TYPE (decl)) != TYPE_UNQUALIFIED)
     error ("static member function %q#D declared with type qualifiers", decl);
 
-  args = TREE_CHAIN (args);
-  tmp = build_function_type (TREE_TYPE (function), args);
-  tmp = build_qualified_type (tmp, cp_type_quals (function));
-  tmp = build_exception_variant (tmp,
-                                TYPE_RAISES_EXCEPTIONS (function));
-  TREE_TYPE (decl) = tmp;
   if (DECL_ARGUMENTS (decl))
     DECL_ARGUMENTS (decl) = TREE_CHAIN (DECL_ARGUMENTS (decl));
   DECL_STATIC_FUNCTION_P (decl) = 1;
@@ -12687,6 +13046,8 @@ cp_tree_node_structure (union lang_tree_node * t)
     case STATIC_ASSERT:                return TS_CP_STATIC_ASSERT;
     case ARGUMENT_PACK_SELECT:  return TS_CP_ARGUMENT_PACK_SELECT;
     case TRAIT_EXPR:           return TS_CP_TRAIT_EXPR;
+    case LAMBDA_EXPR:          return TS_CP_LAMBDA_EXPR;
+    case TEMPLATE_INFO:                return TS_CP_TEMPLATE_INFO;
     default:                   return TS_CP_GENERIC;
     }
 }