OSDN Git Service

PR c++/50296
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 598af1c..eed4535 100644 (file)
@@ -74,6 +74,7 @@ static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, tree *);
 static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
                         int, int, tree);
+static int check_static_variable_definition (tree, tree);
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (tree, tree, bool);
 static tree build_library_fn_1 (tree, enum tree_code, tree);
@@ -183,7 +184,7 @@ struct GTY((chain_next ("%h.next"))) named_label_use_entry {
   /* The binding level to which this entry is *currently* attached.
      This is initially the binding level in which the goto appeared,
      but is modified as scopes are closed.  */
-  struct cp_binding_level *binding_level;
+  cp_binding_level *binding_level;
   /* The head of the names list that was current when the goto appeared,
      or the inner scope popped.  These are the decls that will *not* be
      skipped when jumping to the label.  */
@@ -207,7 +208,7 @@ struct GTY(()) named_label_entry {
   /* The binding level to which the label is *currently* attached.
      This is initially set to the binding level in which the label
      is defined, but is modified as scopes are closed.  */
-  struct cp_binding_level *binding_level;
+  cp_binding_level *binding_level;
   /* The head of the names list that was current when the label was
      defined, or the inner scope popped.  These are the decls that will
      be skipped when jumping to the label.  */
@@ -269,7 +270,7 @@ current_tmpl_spec_kind (int n_class_scopes)
   int n_template_parm_scopes = 0;
   int seen_specialization_p = 0;
   int innermost_specialization_p = 0;
-  struct cp_binding_level *b;
+  cp_binding_level *b;
 
   /* Scan through the template parameter scopes.  */
   for (b = current_binding_level;
@@ -446,7 +447,7 @@ objc_get_current_scope (void)
 void
 objc_mark_locals_volatile (void *enclosing_blk)
 {
-  struct cp_binding_level *scope;
+  cp_binding_level *scope;
 
   for (scope = current_binding_level;
        scope && scope != enclosing_blk;
@@ -469,8 +470,8 @@ static int
 poplevel_named_label_1 (void **slot, void *data)
 {
   struct named_label_entry *ent = (struct named_label_entry *) *slot;
-  struct cp_binding_level *bl = (struct cp_binding_level *) data;
-  struct cp_binding_level *obl = bl->level_chain;
+  cp_binding_level *bl = (cp_binding_level *) data;
+  cp_binding_level *obl = bl->level_chain;
 
   if (ent->binding_level == bl)
     {
@@ -642,6 +643,9 @@ poplevel (int keep, int reverse, int functionbody)
   for (link = decls; link; link = TREE_CHAIN (link))
     {
       if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
+         /* It's hard to make this ARM compatibility hack play nicely with
+            lambdas, and it really isn't necessary in C++11 mode.  */
+         && cxx_dialect < cxx0x
          && DECL_NAME (link))
        {
          tree name = DECL_NAME (link);
@@ -852,7 +856,7 @@ walk_namespaces (walk_namespaces_fn f, void* data)
 int
 wrapup_globals_for_namespace (tree name_space, void* data)
 {
-  struct cp_binding_level *level = NAMESPACE_LEVEL (name_space);
+  cp_binding_level *level = NAMESPACE_LEVEL (name_space);
   VEC(tree,gc) *statics = level->static_decls;
   tree *vec = VEC_address (tree, statics);
   int len = VEC_length (tree, statics);
@@ -1783,6 +1787,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       tree oldtype = TREE_TYPE (olddecl);
       tree newtype;
 
+      if (TREE_CODE (newdecl) == FUNCTION_DECL)
+       maybe_instantiate_noexcept (olddecl);
+
       /* Merge the data types specified in the two decls.  */
       newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
 
@@ -2640,10 +2647,10 @@ identify_goto (tree decl, const location_t *locus)
    true if all is well.  */
 
 static bool
-check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names,
+check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
                       bool exited_omp, const location_t *locus)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   bool identified = false, saw_eh = false, saw_omp = false;
 
   if (exited_omp)
@@ -2715,7 +2722,7 @@ check_previous_goto (tree decl, struct named_label_use_entry *use)
 }
 
 static bool
-check_switch_goto (struct cp_binding_level* level)
+check_switch_goto (cp_binding_level* level)
 {
   return check_previous_goto_1 (NULL_TREE, level, level->names, false, NULL);
 }
@@ -2801,7 +2808,7 @@ check_goto (tree decl)
     error ("  enters OpenMP structured block");
   else if (flag_openmp)
     {
-      struct cp_binding_level *b;
+      cp_binding_level *b;
       for (b = current_binding_level; b ; b = b->level_chain)
        {
          if (b == ent->binding_level)
@@ -2827,7 +2834,7 @@ check_goto (tree decl)
 bool
 check_omp_return (void)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   for (b = current_binding_level; b ; b = b->level_chain)
     if (b->kind == sk_omp)
       {
@@ -2846,7 +2853,7 @@ static tree
 define_label_1 (location_t location, tree name)
 {
   struct named_label_entry *ent, dummy;
-  struct cp_binding_level *p;
+  cp_binding_level *p;
   tree decl;
 
   decl = lookup_label (name);
@@ -2905,7 +2912,7 @@ define_label (location_t location, tree name)
 
 struct cp_switch
 {
-  struct cp_binding_level *level;
+  cp_binding_level *level;
   struct cp_switch *next;
   /* The SWITCH_STMT being built.  */
   tree switch_stmt;
@@ -2957,6 +2964,28 @@ pop_switch (void)
   free (cs);
 }
 
+/* Convert a case constant VALUE in a switch to the type TYPE of the switch
+   condition.  Note that if TYPE and VALUE are already integral we don't
+   really do the conversion because the language-independent
+   warning/optimization code will work better that way.  */
+
+static tree
+case_conversion (tree type, tree value)
+{
+  if (value == NULL_TREE)
+    return value;
+
+  if (cxx_dialect >= cxx0x
+      && (SCOPED_ENUM_P (type)
+         || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))))
+    {
+      if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+       type = type_promotes_to (type);
+      value = perform_implicit_conversion (type, value, tf_warning_or_error);
+    }
+  return cxx_constant_value (value);
+}
+
 /* Note that we've seen a definition of a case label, and complain if this
    is a bad place for one.  */
 
@@ -2964,7 +2993,8 @@ tree
 finish_case_label (location_t loc, tree low_value, tree high_value)
 {
   tree cond, r;
-  struct cp_binding_level *p;
+  cp_binding_level *p;
+  tree type;
 
   if (processing_template_decl)
     {
@@ -2984,13 +3014,12 @@ finish_case_label (location_t loc, tree low_value, tree high_value)
   if (!check_switch_goto (switch_stack->level))
     return error_mark_node;
 
-  if (low_value)
-    low_value = cxx_constant_value (low_value);
-  if (high_value)
-    high_value = cxx_constant_value (high_value);
+  type = SWITCH_STMT_TYPE (switch_stack->switch_stmt);
+
+  low_value = case_conversion (type, low_value);
+  high_value = case_conversion (type, high_value);
 
-  r = c_add_case_label (loc, switch_stack->cases, cond,
-                       SWITCH_STMT_TYPE (switch_stack->switch_stmt),
+  r = c_add_case_label (loc, switch_stack->cases, cond, type,
                        low_value, high_value);
 
   /* After labels, make any new cleanups in the function go into their
@@ -3492,8 +3521,6 @@ cxx_init_decl_processing (void)
   tree void_ftype;
   tree void_ftype_ptr;
 
-  build_common_tree_nodes (flag_signed_char);
-
   /* Create all the identifiers we need.  */
   initialize_predefined_identifiers ();
 
@@ -3510,8 +3537,6 @@ cxx_init_decl_processing (void)
   TREE_PUBLIC (global_namespace) = 1;
   begin_scope (sk_namespace, global_namespace);
 
-  current_lang_name = NULL_TREE;
-
   if (flag_visibility_ms_compat)
     default_visibility = VISIBILITY_HIDDEN;
 
@@ -3575,6 +3600,10 @@ cxx_init_decl_processing (void)
   init_list_type_node = make_node (LANG_TYPE);
   record_unknown_type (init_list_type_node, "init list");
 
+  dependent_lambda_return_type_node = make_node (LANG_TYPE);
+  record_unknown_type (dependent_lambda_return_type_node,
+                      "undeduced lambda return type");
+
   {
     /* Make sure we get a unique function type, so we can give
        its pointer type a name.  (This wins for gdb.) */
@@ -3607,6 +3636,7 @@ cxx_init_decl_processing (void)
   current_lang_name = lang_name_cplusplus;
 
   {
+    tree newattrs;
     tree newtype, deltype;
     tree ptr_ftype_sizetype;
     tree new_eh_spec;
@@ -3634,7 +3664,13 @@ cxx_init_decl_processing (void)
     else
       new_eh_spec = noexcept_false_spec;
 
-    newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec);
+    /* Ensure attribs.c is initialized.  */
+    init_attributes ();
+    newattrs
+      = build_tree_list (get_identifier ("alloc_size"),
+                        build_tree_list (NULL_TREE, integer_one_node));
+    newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
+    newtype = build_exception_variant (newtype, 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);
@@ -3646,7 +3682,7 @@ cxx_init_decl_processing (void)
     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);
+    SET_TYPE_MODE (nullptr_type_node, ptr_mode);
     record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
     nullptr_node = build_int_cst (nullptr_type_node, 0);
   }
@@ -3736,7 +3772,7 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep)
 
   if (current_function_decl)
     {
-      struct cp_binding_level *b = current_binding_level;
+      cp_binding_level *b = current_binding_level;
       if (b->kind == sk_function_parms)
        return error_mark_node;
       while (b->level_chain->kind != sk_function_parms)
@@ -4568,6 +4604,12 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
      explicitly); we need to allow the temporary to be initialized
      first.  */
   tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error);
+  if (DECL_DECLARED_CONSTEXPR_P (decl))
+    {
+      tmp = cxx_constant_value (tmp);
+      DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
+       = reduced_constant_expression_p (tmp);
+    }
 
   if (tmp == error_mark_node)
     return NULL_TREE;
@@ -4626,7 +4668,8 @@ build_init_list_var_init (tree decl, tree type, tree init, tree *array_init,
    is valid, i.e., does not have a designated initializer.  */
 
 static bool
-check_array_designated_initializer (const constructor_elt *ce)
+check_array_designated_initializer (const constructor_elt *ce,
+                                   unsigned HOST_WIDE_INT index)
 {
   /* Designated initializers for array elements are not supported.  */
   if (ce->index)
@@ -4637,8 +4680,13 @@ check_array_designated_initializer (const constructor_elt *ce)
        error ("name used in a GNU-style designated "
               "initializer for an array");
       else if (TREE_CODE (ce->index) == INTEGER_CST)
-       /* An index added by reshape_init.  */
-       return true;
+       {
+         /* A C99 designator is OK if it matches the current index.  */
+         if (TREE_INT_CST_LOW (ce->index) == index)
+           return true;
+         else
+           sorry ("non-trivial designated initializers not supported");
+       }
       else
        {
          gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
@@ -4680,7 +4728,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
          constructor_elt *ce;
          HOST_WIDE_INT i;
          FOR_EACH_VEC_ELT (constructor_elt, v, i, ce)
-           if (!check_array_designated_initializer (ce))
+           if (!check_array_designated_initializer (ce, i))
              failure = 1;
        }
 
@@ -4939,7 +4987,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
     {
       tree elt_init;
 
-      check_array_designated_initializer (d->cur);
+      check_array_designated_initializer (d->cur, index);
       elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
                                 complain);
       if (elt_init == error_mark_node)
@@ -5330,13 +5378,13 @@ build_aggr_init_full_exprs (tree decl, tree init, int flags)
      
 {
   int saved_stmts_are_full_exprs_p = 0;
-  if (building_stmt_tree ())
+  if (building_stmt_list_p ())
     {
       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
       current_stmt_tree ()->stmts_are_full_exprs_p = 1;
     }
   init = build_aggr_init (decl, init, flags, tf_warning_or_error);
-  if (building_stmt_tree ())
+  if (building_stmt_list_p ())
     current_stmt_tree ()->stmts_are_full_exprs_p =
       saved_stmts_are_full_exprs_p;
   return init;
@@ -5361,6 +5409,14 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
      type.  */
   TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl));
 
+  if (DECL_HAS_VALUE_EXPR_P (decl))
+    {
+      /* A variable with DECL_HAS_VALUE_EXPR_P set is just a placeholder,
+        it doesn't have storage to be initialized.  */
+      gcc_assert (init == NULL_TREE);
+      return NULL_TREE;
+    }
+
   if (type == error_mark_node)
     /* We will have already complained.  */
     return NULL_TREE;
@@ -5438,7 +5494,11 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
              init = error_mark_node;
            }
          else
-           init = reshape_init (type, init, tf_warning_or_error);          
+           {
+             init = reshape_init (type, init, tf_warning_or_error);
+             if (cxx_dialect >= cxx0x && SCALAR_TYPE_P (type))
+               check_narrowing (type, init);
+           }
        }
 
       /* If DECL has an array type without a specific bound, deduce the
@@ -5729,7 +5789,7 @@ initialize_local_var (tree decl, tree init)
          if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
            wrap_temporary_cleanups (init, cleanup);
 
-         gcc_assert (building_stmt_tree ());
+         gcc_assert (building_stmt_list_p ());
          saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
          current_stmt_tree ()->stmts_are_full_exprs_p = 1;
          finish_expr_stmt (init);
@@ -5879,7 +5939,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   cleanup = NULL_TREE;
 
   /* If a name was specified, get the string.  */
-  if (global_scope_p (current_binding_level))
+  if (at_namespace_scope_p ())
     asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
   if (asmspec_tree && asmspec_tree != error_mark_node)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
@@ -5887,6 +5947,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (current_class_type
       && CP_DECL_CONTEXT (decl) == current_class_type
       && TYPE_BEING_DEFINED (current_class_type)
+      && !CLASSTYPE_TEMPLATE_INSTANTIATION (current_class_type)
       && (DECL_INITIAL (decl) || init))
     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
@@ -5905,18 +5966,20 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
        d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
                                                  tf_warning_or_error);
       d_init = resolve_nondeduced_context (d_init);
-      if (describable_type (d_init))
-       {
-         type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
-                                                      auto_node);
-         if (type == error_mark_node)
-           return;
-       }
+      type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
+                                                  auto_node);
+      if (type == error_mark_node)
+       return;
     }
 
   if (!ensure_literal_type_for_constexpr_object (decl))
     DECL_DECLARED_CONSTEXPR_P (decl) = 0;
 
+  if (TREE_CODE (decl) == VAR_DECL
+      && DECL_CLASS_SCOPE_P (decl)
+      && DECL_INITIALIZED_IN_CLASS_P (decl))
+    check_static_variable_definition (decl, type);
+
   if (init && TREE_CODE (decl) == FUNCTION_DECL)
     {
       tree clone;
@@ -5946,6 +6009,11 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (init && TREE_CODE (decl) == VAR_DECL)
     {
       DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+      /* If DECL is a reference, then we want to know whether init is a
+        reference constant; init_const_expr_p as passed tells us whether
+        it's an rvalue constant.  */
+      if (TREE_CODE (type) == REFERENCE_TYPE)
+       init_const_expr_p = potential_constant_expression (init);
       if (init_const_expr_p)
        {
          /* Set these flags now for templates.  We'll update the flags in
@@ -6161,7 +6229,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   /* Add this declaration to the statement-tree.  This needs to happen
      after the call to check_initializer so that the DECL_EXPR for a
      reference temp is added before the DECL_EXPR for the reference itself.  */
-  if (at_function_scope_p ())
+  if (DECL_FUNCTION_SCOPE_P (decl))
     add_decl_expr (decl);
 
   /* Let the middle end know about variables and functions -- but not
@@ -6256,6 +6324,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (was_readonly)
     TREE_READONLY (decl) = 1;
+
+  invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
 }
 
 /* Returns a declaration for a VAR_DECL as if:
@@ -6403,6 +6473,11 @@ get_dso_handle_node (void)
   dso_handle_node = declare_global_var (get_identifier ("__dso_handle"),
                                        ptr_type_node);
 
+#ifdef HAVE_GAS_HIDDEN
+  DECL_VISIBILITY (dso_handle_node) = VISIBILITY_HIDDEN;
+  DECL_VISIBILITY_SPECIFIED (dso_handle_node) = 1;
+#endif
+
   return dso_handle_node;
 }
 
@@ -6599,7 +6674,6 @@ expand_static_init (tree decl, tree init)
       tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
       tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
       tree guard, guard_addr;
-      tree acquire_fn, release_fn, abort_fn;
       tree flag, begin;
 
       /* Emit code to perform this initialization but once.  This code
@@ -6649,29 +6723,31 @@ expand_static_init (tree decl, tree init)
 
       if (flag_threadsafe_statics)
        {
+         tree vfntype = NULL_TREE;
+         tree acquire_name, release_name, abort_name;
+         tree acquire_fn, release_fn, abort_fn;
          guard_addr = build_address (guard);
 
-         acquire_fn = get_identifier ("__cxa_guard_acquire");
-         release_fn = get_identifier ("__cxa_guard_release");
-         abort_fn = get_identifier ("__cxa_guard_abort");
-         if (!get_global_value_if_present (acquire_fn, &acquire_fn))
-           {
-             tree vfntype = build_function_type_list (void_type_node,
-                                                      TREE_TYPE (guard_addr),
-                                                      NULL_TREE);
-             acquire_fn = push_library_fn
-               (acquire_fn, build_function_type_list (integer_type_node,
+         acquire_name = get_identifier ("__cxa_guard_acquire");
+         release_name = get_identifier ("__cxa_guard_release");
+         abort_name = get_identifier ("__cxa_guard_abort");
+         acquire_fn = identifier_global_value (acquire_name);
+         release_fn = identifier_global_value (release_name);
+         abort_fn = identifier_global_value (abort_name);
+         if (!acquire_fn)
+           acquire_fn = push_library_fn
+             (acquire_name, build_function_type_list (integer_type_node,
                                                       TREE_TYPE (guard_addr),
                                                       NULL_TREE),
-                NULL_TREE);
-             release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
-             abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
-           }
-         else
-           {
-             release_fn = identifier_global_value (release_fn);
-             abort_fn = identifier_global_value (abort_fn);
-           }
+              NULL_TREE);
+         if (!release_fn || !abort_fn)
+           vfntype = build_function_type_list (void_type_node,
+                                               TREE_TYPE (guard_addr),
+                                               NULL_TREE);
+         if (!release_fn)
+           release_fn = push_library_fn (release_name, vfntype, NULL_TREE);
+         if (!abort_fn)
+           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
 
          inner_if_stmt = begin_if_stmt ();
          finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
@@ -6950,7 +7026,14 @@ build_this_parm (tree type, cp_cv_quals quals)
   tree parm;
   cp_cv_quals this_quals;
 
-  this_type = type_of_this_parm (type);
+  if (CLASS_TYPE_P (type))
+    {
+      this_type
+       = cp_build_qualified_type (type, quals & ~TYPE_QUAL_RESTRICT);
+      this_type = build_pointer_type (this_type);
+    }
+  else
+    this_type = type_of_this_parm (type);
   /* The `this' parameter is implicitly `const'; it cannot be
      assigned to.  */
   this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
@@ -6960,6 +7043,17 @@ build_this_parm (tree type, cp_cv_quals quals)
   return parm;
 }
 
+/* DECL is a static member function.  Complain if it was declared
+   with function-cv-quals.  */
+
+static void
+check_static_quals (tree decl, cp_cv_quals quals)
+{
+  if (quals != TYPE_UNQUALIFIED)
+    error ("static member function %q#D declared with type qualifiers",
+          decl);
+}
+
 /* CTYPE is class type, or null if non-class.
    TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
    or METHOD_TYPE.
@@ -7241,6 +7335,9 @@ grokfndecl (tree ctype,
   if (decl == error_mark_node)
     return NULL_TREE;
 
+  if (DECL_STATIC_FUNCTION_P (decl))
+    check_static_quals (decl, quals);
+
   if (attrlist)
     {
       cplus_decl_attributes (&decl, *attrlist, 0);
@@ -7290,9 +7387,11 @@ grokfndecl (tree ctype,
 
          if (DECL_STATIC_FUNCTION_P (old_decl)
              && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
-           /* Remove the `this' parm added by grokclassfn.
-              XXX Isn't this done in start_function, too?  */
-           revert_static_member_fn (decl);
+           {
+             /* Remove the `this' parm added by grokclassfn.  */
+             revert_static_member_fn (decl);
+             check_static_quals (decl, quals);
+           }
          if (DECL_ARTIFICIAL (old_decl))
            {
              error ("definition of implicitly-declared %qD", old_decl);
@@ -7602,9 +7701,12 @@ build_ptrmem_type (tree class_type, tree member_type)
    messages.  Return 1 if the definition is particularly bad, or 0
    otherwise.  */
 
-int
+static int
 check_static_variable_definition (tree decl, tree type)
 {
+  /* Can't check yet if we don't know the type.  */
+  if (dependent_type_p (type))
+    return 0;
   /* If DECL is declared constexpr, we'll do the appropriate checks
      in check_initializer.  */
   if (DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl))
@@ -7936,6 +8038,12 @@ create_array_type_for_decl (tree name, tree type, tree size)
   if (type == error_mark_node || size == error_mark_node)
     return error_mark_node;
 
+  /* 8.3.4/1: If the type of the identifier of D contains the auto
+     type-specifier, the program is ill-formed.  */
+  if (pedantic && type_uses_auto (type))
+    pedwarn (input_location, OPT_pedantic,
+            "declaration of %qD as array of %<auto%>", name);
+
   /* If there are some types which cannot be array elements,
      issue an error-message and return.  */
   switch (TREE_CODE (type))
@@ -8267,10 +8375,15 @@ grokdeclarator (const cp_declarator *declarator,
                else if (TYPE_P (qualifying_scope))
                  {
                    ctype = qualifying_scope;
-                   if (innermost_code != cdk_function
-                       && current_class_type
-                       && !UNIQUELY_DERIVED_FROM_P (ctype,
-                                                    current_class_type))
+                   if (!MAYBE_CLASS_TYPE_P (ctype))
+                     {
+                       error ("%q#T is not a class or a namespace", ctype);
+                       ctype = NULL_TREE;
+                     }
+                   else if (innermost_code != cdk_function
+                            && current_class_type
+                            && !UNIQUELY_DERIVED_FROM_P (ctype,
+                                                         current_class_type))
                      {
                        error ("type %qT is not derived from type %qT",
                               ctype, current_class_type);
@@ -8384,6 +8497,20 @@ grokdeclarator (const cp_declarator *declarator,
       return error_mark_node;
     }
 
+  if (dname && IDENTIFIER_OPNAME_P (dname))
+    {
+      if (declspecs->specs[(int)ds_typedef])
+       {
+         error ("declaration of %qD as %<typedef%>", dname);
+         return error_mark_node;
+       }
+      else if (decl_context == PARM || decl_context == CATCHPARM)
+       {
+         error ("declaration of %qD as parameter", dname);
+         return error_mark_node;
+       }
+    }
+
   /* Anything declared one level down from the top level
      must be one of the parameters of a function
      (because the body is at least two levels down).  */
@@ -8400,7 +8527,7 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (decl_context == NORMAL && !toplevel_bindings_p ())
     {
-      struct cp_binding_level *b = current_binding_level;
+      cp_binding_level *b = current_binding_level;
       current_binding_level = b->level_chain;
       if (current_binding_level != 0 && toplevel_bindings_p ())
        decl_context = PARM;
@@ -8725,12 +8852,6 @@ grokdeclarator (const cp_declarator *declarator,
               || thread_p)
        error ("storage class specifiers invalid in parameter declarations");
 
-      if (type_uses_auto (type))
-       {
-         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)
@@ -9168,13 +9289,18 @@ grokdeclarator (const cp_declarator *declarator,
                 to create the type "rvalue reference to cv TD' creates the
                 type TD."
               */
-             if (!VOID_TYPE_P (type))
+             if (VOID_TYPE_P (type))
+               /* We already gave an error.  */;
+             else if (TREE_CODE (type) == REFERENCE_TYPE)
+               {
+                 if (declarator->u.reference.rvalue_ref)
+                   /* Leave type alone.  */;
+                 else
+                   type = cp_build_reference_type (TREE_TYPE (type), false);
+               }
+             else
                type = cp_build_reference_type
-                      ((TREE_CODE (type) == REFERENCE_TYPE
-                        ? TREE_TYPE (type) : type),
-                       (declarator->u.reference.rvalue_ref
-                        && (TREE_CODE(type) != REFERENCE_TYPE
-                            || TYPE_REF_IS_RVALUE (type))));
+                 (type, declarator->u.reference.rvalue_ref);
 
              /* In C++0x, we need this check for direct reference to
                 reference declarations, which are forbidden by
@@ -9244,8 +9370,11 @@ grokdeclarator (const cp_declarator *declarator,
         error ("both %<const%> and %<constexpr%> cannot be used here");
       if (type_quals & TYPE_QUAL_VOLATILE)
         error ("both %<volatile%> and %<constexpr%> cannot be used here");
-      type_quals |= TYPE_QUAL_CONST;
-      type = cp_build_qualified_type (type, type_quals);
+      if (TREE_CODE (type) != REFERENCE_TYPE)
+       {
+         type_quals |= TYPE_QUAL_CONST;
+         type = cp_build_qualified_type (type, type_quals);
+       }
     }
 
   if (unqualified_id && TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR
@@ -9266,7 +9395,7 @@ grokdeclarator (const cp_declarator *declarator,
      would not have exited the loop above.  */
   if (declarator
       && declarator->u.id.qualifying_scope
-      && TYPE_P (declarator->u.id.qualifying_scope))
+      && MAYBE_CLASS_TYPE_P (declarator->u.id.qualifying_scope))
     {
       tree t;
 
@@ -9356,12 +9485,6 @@ grokdeclarator (const cp_declarator *declarator,
   if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
     ctype = current_class_type;
 
-  /* A constexpr non-static member function is implicitly const.  */
-  if (constexpr_p && ctype && staticp == 0
-      && TREE_CODE (type) == FUNCTION_TYPE
-      && sfk != sfk_constructor && sfk != sfk_destructor)
-    memfn_quals |= TYPE_QUAL_CONST;
-
   /* Now TYPE has the actual type.  */
 
   if (returned_attrs)
@@ -9477,6 +9600,12 @@ grokdeclarator (const cp_declarator *declarator,
           memfn_quals = TYPE_UNQUALIFIED;
         }
 
+      if (type_uses_auto (type))
+       {
+         error ("typedef declared %<auto%>");
+         type = error_mark_node;
+       }
+
       if (decl_context == FIELD)
        decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
       else
@@ -9514,6 +9643,7 @@ grokdeclarator (const cp_declarator *declarator,
          && TYPE_NAME (type)
          && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
          && TYPE_ANONYMOUS_P (type)
+         && declspecs->type_definition_p
          && cp_type_quals (type) == TYPE_UNQUALIFIED)
        {
          tree t;
@@ -9717,6 +9847,12 @@ grokdeclarator (const cp_declarator *declarator,
       if (ctype || in_namespace)
        error ("cannot use %<::%> in parameter declaration");
 
+      if (type_uses_auto (type))
+       {
+         error ("parameter declared %<auto%>");
+         type = error_mark_node;
+       }
+
       /* A parameter declared as an array of T is really a pointer to T.
         One declared as a function is really a pointer to a function.
         One declared as a member is really a pointer to member.  */
@@ -9733,7 +9869,12 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
       && !NEW_DELETE_OPNAME_P (unqualified_id))
-    type = build_memfn_type (type, ctype, memfn_quals);
+    {
+      cp_cv_quals real_quals = memfn_quals;
+      if (constexpr_p && sfk != sfk_constructor && sfk != sfk_destructor)
+       real_quals |= TYPE_QUAL_CONST;
+      type = build_memfn_type (type, ctype, real_quals);
+    }
 
   {
     tree decl;
@@ -9895,7 +10036,7 @@ grokdeclarator (const cp_declarator *declarator,
               instantiation made the field's type be incomplete.  */
            if (current_class_type
                && TYPE_NAME (current_class_type)
-               && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type))
+               && IDENTIFIER_TEMPLATE (current_class_name)
                && declspecs->type
                && declspecs->type == type)
              error ("  in instantiation of template %qT",
@@ -9971,21 +10112,6 @@ grokdeclarator (const cp_declarator *declarator,
                        staticp = 1;
                      }
                  }
-
-               if (uses_template_parms (type))
-                 /* We'll check at instantiation time.  */
-                 ;
-               else if (constexpr_p)
-                 /* constexpr has the same requirements.  */
-                 ;
-               else if (check_static_variable_definition (unqualified_id,
-                                                          type))
-                 /* If we just return the declaration, crashes
-                    will sometimes occur.  We therefore return
-                    void_type_node, as if this was a friend
-                    declaration, to cause callers to completely
-                    ignore this declaration.  */
-                 return error_mark_node;
              }
 
            if (staticp)
@@ -10076,13 +10202,6 @@ grokdeclarator (const cp_declarator *declarator,
                       "declared out of global scope", name);
          }
 
-       if (ctype != NULL_TREE
-           && TREE_CODE (ctype) != NAMESPACE_DECL && !MAYBE_CLASS_TYPE_P (ctype))
-         {
-           error ("%q#T is not a class or a namespace", ctype);
-           ctype = NULL_TREE;
-         }
-
        if (ctype == NULL_TREE)
          {
            if (virtualp)
@@ -10497,12 +10616,6 @@ grokparms (tree parmlist, tree *parms)
            init = check_default_argument (decl, init);
        }
 
-      if (TREE_CODE (decl) == PARM_DECL
-          && FUNCTION_PARAMETER_PACK_P (decl)
-          && TREE_CHAIN (parm)
-          && TREE_CHAIN (parm) != void_list_node)
-        error ("parameter packs must be at the end of the parameter list");
-
       DECL_CHAIN (decl) = decls;
       decls = decl;
       result = tree_cons (init, type, result);
@@ -12136,9 +12249,13 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
              tree prev_value;
              bool overflowed;
 
-             /* The next value is the previous value plus one.
-                add_double doesn't know the type of the target expression,
-                so we must check with int_fits_type_p as well.  */
+             /* C++03 7.2/4: If no initializer is specified for the first
+                enumerator, the type is an unspecified integral
+                type. Otherwise the type is the same as the type of the
+                initializing value of the preceding enumerator unless the
+                incremented value is not representable in that type, in
+                which case the type is an unspecified integral type
+                sufficient to contain the incremented value.  */
              prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
              if (error_operand_p (prev_value))
                value = error_mark_node;
@@ -12147,9 +12264,34 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
                  overflowed = add_double (TREE_INT_CST_LOW (prev_value),
                                           TREE_INT_CST_HIGH (prev_value),
                                           1, 0, &lo, &hi);
-                 value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi);
-                 overflowed
-                   |= !int_fits_type_p (value, TREE_TYPE (prev_value));
+                 if (!overflowed)
+                   {
+                     double_int di;
+                     tree type = TREE_TYPE (prev_value);
+                     bool pos = (TYPE_UNSIGNED (type) || hi >= 0);
+                     di.low = lo; di.high = hi;
+                     if (!double_int_fits_to_tree_p (type, di))
+                       {
+                         unsigned int itk;
+                         for (itk = itk_int; itk != itk_none; itk++)
+                           {
+                             type = integer_types[itk];
+                             if (type != NULL_TREE
+                                 && (pos || !TYPE_UNSIGNED (type))
+                                 && double_int_fits_to_tree_p (type, di))
+                               break;
+                           }
+                         if (type && cxx_dialect < cxx0x
+                             && itk > itk_unsigned_long)
+                           pedwarn (input_location, OPT_Wlong_long, pos ? "\
+incremented enumerator value is too large for %<unsigned long%>" :  "\
+incremented enumerator value is too large for %<long%>");
+                       }
+                     if (type == NULL_TREE)
+                       overflowed = true;
+                     else
+                       value = double_int_to_tree (type, di);
+                   }
 
                  if (overflowed)
                    {
@@ -12323,7 +12465,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   tree fntype;
   tree restype;
   int doing_friend = 0;
-  struct cp_binding_level *bl;
+  cp_binding_level *bl;
   tree current_function_parms;
   struct c_fileinfo *finfo
     = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
@@ -12373,12 +12515,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   /* Sometimes we don't notice that a function is a static member, and
      build a METHOD_TYPE for it.  Fix that up now.  */
-  if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
-      && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE)
-    {
-      revert_static_member_fn (decl1);
-      ctype = NULL_TREE;
-    }
+  gcc_assert (!(ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
+               && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE));
 
   /* Set up current_class_type, and enter the scope of the class, if
      appropriate.  */
@@ -12521,10 +12659,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
        maybe_apply_pragma_weak (decl1);
     }
 
-  /* constexpr functions must have literal argument types and
-     literal return type.  */
-  validate_constexpr_fundecl (decl1);
-
   /* Reset this in case the call to pushdecl changed it.  */
   current_function_decl = decl1;
 
@@ -12570,6 +12704,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
       cp_function_chain->x_current_class_ref
        = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
+      /* Set this second to avoid shortcut in cp_build_indirect_ref.  */
       cp_function_chain->x_current_class_ptr = t;
 
       /* Constructors and destructors need to know whether they're "in
@@ -12596,7 +12731,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
                        compiler-generated functions.  */
                     && !DECL_ARTIFICIAL (decl1));
 
-  if (DECL_INTERFACE_KNOWN (decl1))
+  if (processing_template_decl)
+    /* Don't mess with interface flags.  */;
+  else if (DECL_INTERFACE_KNOWN (decl1))
     {
       tree ctx = decl_function_context (decl1);
 
@@ -12615,8 +12752,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   else if (!finfo->interface_unknown && honor_interface)
     {
       if (DECL_DECLARED_INLINE_P (decl1)
-         || DECL_TEMPLATE_INSTANTIATION (decl1)
-         || processing_template_decl)
+         || DECL_TEMPLATE_INSTANTIATION (decl1))
        {
          DECL_EXTERNAL (decl1)
            = (finfo->interface_only
@@ -12748,7 +12884,7 @@ use_eh_spec_block (tree fn)
             not creating the EH_SPEC_BLOCK we save a little memory,
             and we avoid spurious warnings about unreachable
             code.  */
-         && !DECL_ARTIFICIAL (fn));
+         && !DECL_DEFAULTED_FN (fn));
 }
 
 /* Store the parameter declarations into the current function declaration.
@@ -12845,7 +12981,7 @@ save_function_data (tree decl)
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
   /* Clear out the bits we don't need.  */
-  f->base.x_stmt_tree.x_cur_stmt_list = NULL_TREE;
+  f->base.x_stmt_tree.x_cur_stmt_list = NULL;
   f->bindings = NULL;
   f->x_local_names = NULL;
 }
@@ -12957,7 +13093,8 @@ finish_destructor_body (void)
 /* Do the necessary processing for the beginning of a function body, which
    in this case includes member-initializers, but not the catch clauses of
    a function-try-block.  Currently, this means opening a binding level
-   for the member-initializers (in a ctor) and member cleanups (in a dtor).  */
+   for the member-initializers (in a ctor), member cleanups (in a dtor),
+   and capture proxies (in a lambda operator()).  */
 
 tree
 begin_function_body (void)
@@ -13090,7 +13227,7 @@ finish_function (int flags)
       This caused &foo to be of type ptr-to-const-function
       which then got a warning when stored in a ptr-to-function variable.  */
 
-  gcc_assert (building_stmt_tree ());
+  gcc_assert (building_stmt_list_p ());
   /* The current function is being defined, so its DECL_INITIAL should
      be set, and unless there's a multiple definition, it should be
      error_mark_node.  */
@@ -13102,22 +13239,13 @@ finish_function (int flags)
     {
       if (DECL_MAIN_P (current_function_decl))
        {
-         tree stmt;
-
          /* Make it so that `main' always returns 0 by default (or
             1 for VMS).  */
 #if VMS_TARGET
-         stmt = finish_return_stmt (integer_one_node);
+         finish_return_stmt (integer_one_node);
 #else
-         stmt = finish_return_stmt (integer_zero_node);
+         finish_return_stmt (integer_zero_node);
 #endif
-         /* Hack.  We don't want the middle-end to warn that this
-            return is unreachable, so put the statement on the
-            special line 0.  */
-         {
-           location_t linezero = linemap_line_start (line_table, 0, 1);
-           SET_EXPR_LOCATION (stmt, linezero);
-         }
        }
 
       if (use_eh_spec_block (current_function_decl))
@@ -13578,14 +13706,8 @@ revert_static_member_fn (tree decl)
   cp_cv_quals quals = type_memfn_quals (stype);
 
   if (quals != TYPE_UNQUALIFIED)
-    {
-      if (quals == TYPE_QUAL_CONST && DECL_DECLARED_CONSTEXPR_P (decl))
-       /* The const was implicit, don't complain.  */;
-      else
-       error ("static member function %q#D declared with type qualifiers",
-              decl);
-      stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
-    }
+    stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
+
   TREE_TYPE (decl) = stype;
 
   if (DECL_ARGUMENTS (decl))
@@ -13602,6 +13724,7 @@ cp_tree_node_structure (union lang_tree_node * t)
   switch (TREE_CODE (&t->generic))
     {
     case DEFAULT_ARG:          return TS_CP_DEFAULT_ARG;
+    case DEFERRED_NOEXCEPT:    return TS_CP_DEFERRED_NOEXCEPT;
     case IDENTIFIER_NODE:      return TS_CP_IDENTIFIER;
     case OVERLOAD:             return TS_CP_OVERLOAD;
     case TEMPLATE_PARM_INDEX:  return TS_CP_TPI;