]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/decl.c
Merge from trunk.
[thirdparty/gcc.git] / gcc / cp / decl.c
index a82132882159d7fceb4bb6ede9011106a5f8eb18..babfc8893b850e9fb32805225e97d75694bf765c 100644 (file)
@@ -31,6 +31,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "stringpool.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "attribs.h"
+#include "calls.h"
 #include "flags.h"
 #include "cp-tree.h"
 #include "tree-iterator.h"
@@ -44,6 +49,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-common.h"
 #include "c-family/c-objc.h"
 #include "c-family/c-pragma.h"
+#include "c-family/c-target.h"
+#include "c-family/c-ubsan.h"
 #include "diagnostic.h"
 #include "intl.h"
 #include "debug.h"
@@ -52,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "splay-tree.h"
 #include "plugin.h"
 #include "cgraph.h"
+#include "wide-int.h"
 
 /* Possible cases of bad specifiers type used by bad_specifiers. */
 enum bad_spec_place {
@@ -75,7 +83,6 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
 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);
 static int member_function_or_else (tree, tree, enum overload_flags);
 static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
                            int);
@@ -107,8 +114,8 @@ static tree cp_make_fname_decl (location_t, tree, int);
 static void initialize_predefined_identifiers (void);
 static tree check_special_function_return_type
        (special_function_kind, tree, tree);
-static tree push_cp_library_fn (enum tree_code, tree);
-static tree build_cp_library_fn (tree, enum tree_code, tree);
+static tree push_cp_library_fn (enum tree_code, tree, int);
+static tree build_cp_library_fn (tree, enum tree_code, tree, int);
 static void store_parm_decls (tree);
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
@@ -622,17 +629,22 @@ poplevel (int keep, int reverse, int functionbody)
           push_local_binding where the list of decls returned by
           getdecls is built.  */
        decl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d;
-       if (TREE_CODE (decl) == VAR_DECL
+       // See through references for improved -Wunused-variable (PR 38958).
+       tree type = non_reference (TREE_TYPE (decl));
+       if (VAR_P (decl)
            && (! TREE_USED (decl) || !DECL_READ_P (decl))
            && ! DECL_IN_SYSTEM_HEADER (decl)
            && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)
-           && TREE_TYPE (decl) != error_mark_node
-           && (!CLASS_TYPE_P (TREE_TYPE (decl))
-               || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+           && type != error_mark_node
+           && (!CLASS_TYPE_P (type)
+               || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+               || lookup_attribute ("warn_unused",
+                                    TYPE_ATTRIBUTES (TREE_TYPE (decl)))))
          {
            if (! TREE_USED (decl))
              warning (OPT_Wunused_variable, "unused variable %q+D", decl);
            else if (DECL_CONTEXT (decl) == current_function_decl
+                    // For -Wunused-but-set-variable leave references alone.
                     && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
                     && errorcount == unused_but_set_errorcount)
              {
@@ -646,10 +658,10 @@ poplevel (int keep, int reverse, int functionbody)
   /* Remove declarations for all the DECLs in this level.  */
   for (link = decls; link; link = TREE_CHAIN (link))
     {
-      if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
+      if (leaving_for_scope && VAR_P (link)
          /* 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
+         && cxx_dialect < cxx11
          && DECL_NAME (link))
        {
          tree name = DECL_NAME (link);
@@ -992,10 +1004,7 @@ decls_match (tree newdecl, tree olddecl)
 
       /* A declaration with deduced return type should use its pre-deduction
         type for declaration matching.  */
-      if (FNDECL_USED_AUTO (olddecl))
-       r2 = DECL_STRUCT_FUNCTION (olddecl)->language->x_auto_return_pattern;
-      else
-       r2 = TREE_TYPE (f2);
+      r2 = fndecl_declared_return_type (olddecl);
 
       if (same_type_p (TREE_TYPE (f1), r2))
        {
@@ -1027,6 +1036,7 @@ decls_match (tree newdecl, tree olddecl)
          else
            types_match =
              compparms (p1, p2)
+             && type_memfn_rqual (f1) == type_memfn_rqual (f2)
              && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE
                  || comp_type_attributes (TREE_TYPE (newdecl),
                                           TREE_TYPE (olddecl)) != 0);
@@ -1084,7 +1094,7 @@ decls_match (tree newdecl, tree olddecl)
     {
       /* Need to check scope for variable declaration (VAR_DECL).
         For typedef (TYPE_DECL), scope is ignored.  */
-      if (TREE_CODE (newdecl) == VAR_DECL
+      if (VAR_P (newdecl)
          && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
          /* [dcl.link]
             Two declarations for an object with C language linkage
@@ -1143,8 +1153,9 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
       && DECL_ARTIFICIAL (olddecl))
     return;
 
-  permerror (input_location, "%qD was declared %<extern%> and later %<static%>", newdecl);
-  permerror (input_location, "previous declaration of %q+D", olddecl);
+  if (permerror (input_location,
+                "%qD was declared %<extern%> and later %<static%>", newdecl))
+    inform (input_location, "previous declaration of %q+D", olddecl);
 }
 
 /* NEW_DECL is a redeclaration of OLD_DECL; both are functions or
@@ -1196,16 +1207,27 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl)
   if (DECL_DECLARED_CONSTEXPR_P (old_decl)
       == DECL_DECLARED_CONSTEXPR_P (new_decl))
     return true;
-  if (TREE_CODE (old_decl) == FUNCTION_DECL && DECL_BUILT_IN (old_decl))
+  if (TREE_CODE (old_decl) == FUNCTION_DECL)
     {
-      /* Hide a built-in declaration.  */
-      DECL_DECLARED_CONSTEXPR_P (old_decl)
-       = DECL_DECLARED_CONSTEXPR_P (new_decl);
-      return true;
+      if (DECL_BUILT_IN (old_decl))
+       {
+         /* Hide a built-in declaration.  */
+         DECL_DECLARED_CONSTEXPR_P (old_decl)
+           = DECL_DECLARED_CONSTEXPR_P (new_decl);
+         return true;
+       }
+      /* 7.1.5 [dcl.constexpr]
+        Note: An explicit specialization can differ from the template
+        declaration with respect to the constexpr specifier.  */
+      if (! DECL_TEMPLATE_SPECIALIZATION (old_decl)
+         && DECL_TEMPLATE_SPECIALIZATION (new_decl))
+       return true;
+
+      error ("redeclaration %qD differs in %<constexpr%>", new_decl);
+      error ("from previous declaration %q+D", old_decl);
+      return false;
     }
-  error ("redeclaration %qD differs in %<constexpr%>", new_decl);
-  error ("from previous declaration %q+D", old_decl);
-  return false;
+  return true;
 }
 
 #define GNU_INLINE_P(fn) (DECL_DECLARED_INLINE_P (fn)                  \
@@ -1275,19 +1297,19 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
               && DECL_UNINLINABLE (olddecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
        {
-         warning (OPT_Wattributes, "function %q+D redeclared as inline",
-                  newdecl);
-         warning (OPT_Wattributes, "previous declaration of %q+D "
-                  "with attribute noinline", olddecl);
+         if (warning (OPT_Wattributes, "function %q+D redeclared as inline",
+                      newdecl))
+           inform (input_location, "previous declaration of %q+D "
+                   "with attribute noinline", olddecl);
        }
       else if (DECL_DECLARED_INLINE_P (olddecl)
               && DECL_UNINLINABLE (newdecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
        {
-         warning (OPT_Wattributes, "function %q+D redeclared with "
-                  "attribute noinline", newdecl);
-         warning (OPT_Wattributes, "previous declaration of %q+D was inline",
-                  olddecl);
+         if (warning (OPT_Wattributes, "function %q+D redeclared with "
+                      "attribute noinline", newdecl))
+           inform (input_location, "previous declaration of %q+D was inline",
+                   olddecl);
        }
     }
 
@@ -1328,6 +1350,15 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            }
          return NULL_TREE;
        }
+      else if (DECL_OMP_DECLARE_REDUCTION_P (olddecl))
+       {
+         gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (newdecl));
+         error_at (DECL_SOURCE_LOCATION (newdecl),
+                   "redeclaration of %<pragma omp declare reduction%>");
+         error_at (DECL_SOURCE_LOCATION (olddecl),
+                   "previous %<pragma omp declare reduction%> declaration");
+         return error_mark_node;
+       }
       else if (!types_match)
        {
          /* Avoid warnings redeclaring built-ins which have not been
@@ -1348,7 +1379,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                  {
                    tree t = TREE_VALUE (t1);
 
-                   if (TREE_CODE (t) == POINTER_TYPE
+                   if (TYPE_PTR_P (t)
                        && TYPE_NAME (TREE_TYPE (t))
                        && DECL_NAME (TYPE_NAME (TREE_TYPE (t)))
                           == get_identifier ("FILE")
@@ -1473,7 +1504,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       error ("%q#D redeclared as different kind of symbol", newdecl);
       if (TREE_CODE (olddecl) == TREE_LIST)
        olddecl = TREE_VALUE (olddecl);
-      error ("previous declaration of %q+#D", olddecl);
+      inform (input_location, "previous declaration of %q+#D", olddecl);
 
       return error_mark_node;
     }
@@ -1529,11 +1560,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                              TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
            {
              error ("new declaration %q#D", newdecl);
-             if (FNDECL_USED_AUTO (olddecl))
-               error_at (DECL_SOURCE_LOCATION (olddecl), "ambiguates old "
-                         "declaration with deduced return type");
-             else
-               error ("ambiguates old declaration %q+#D", olddecl);
+             error ("ambiguates old declaration %q+#D", olddecl);
               return error_mark_node;
            }
          else
@@ -1542,7 +1569,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       else
        {
          error ("conflicting declaration %q#D", newdecl);
-         error ("%q+D has a previous declaration as %q#D", olddecl, olddecl);
+         inform (input_location,
+                 "%q+D has a previous declaration as %q#D", olddecl, olddecl);
          return error_mark_node;
        }
     }
@@ -1605,9 +1633,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
        {
          error_at (DECL_SOURCE_LOCATION (newdecl), errmsg, newdecl);
          if (DECL_NAME (olddecl) != NULL_TREE)
-           error ((DECL_INITIAL (olddecl) && namespace_bindings_p ())
-                  ? G_("%q+#D previously defined here")
-                  : G_("%q+#D previously declared here"), olddecl);
+           inform (input_location,
+                   (DECL_INITIAL (olddecl) && namespace_bindings_p ())
+                   ? G_("%q+#D previously defined here")
+                   : G_("%q+#D previously declared here"), olddecl);
          return error_mark_node;
        }
       else if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -1620,8 +1649,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          warning_at (DECL_SOURCE_LOCATION (olddecl), 0,
                      "follows non-prototype definition here");
        }
-      else if ((TREE_CODE (olddecl) == FUNCTION_DECL
-               || TREE_CODE (olddecl) == VAR_DECL)
+      else if (VAR_OR_FUNCTION_DECL_P (olddecl)
               && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
        {
          /* [dcl.link]
@@ -1752,16 +1780,22 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          && (! DECL_TEMPLATE_SPECIALIZATION (newdecl)
              || DECL_TEMPLATE_SPECIALIZATION (olddecl)))
        {
-         warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl);
-         warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
+         if (warning (OPT_Wredundant_decls,
+                      "redundant redeclaration of %qD in same scope",
+                      newdecl))
+           inform (input_location, "previous declaration of %q+D", olddecl);
        }
 
-      if (DECL_DELETED_FN (newdecl))
+      if (!(DECL_TEMPLATE_INSTANTIATION (olddecl)
+           && DECL_TEMPLATE_SPECIALIZATION (newdecl)))
        {
-         error ("deleted definition of %qD", newdecl);
-         error ("after previous declaration %q+D", olddecl);
+         if (DECL_DELETED_FN (newdecl))
+           {
+             error ("deleted definition of %qD", newdecl);
+             error ("after previous declaration %q+D", olddecl);
+           }
+         DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
        }
-      DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
     }
 
   /* Deal with C++: must preserve virtual function table size.  */
@@ -1867,7 +1901,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          && newtype == DECL_ORIGINAL_TYPE (newdecl))
        newtype = oldtype;
 
-      if (TREE_CODE (newdecl) == VAR_DECL)
+      if (VAR_P (newdecl))
        {
          DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
          DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl);
@@ -1904,7 +1938,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          && !(processing_template_decl && uses_template_parms (newdecl)))
        layout_type (TREE_TYPE (newdecl));
 
-      if ((TREE_CODE (newdecl) == VAR_DECL
+      if ((VAR_P (newdecl)
           || TREE_CODE (newdecl) == PARM_DECL
           || TREE_CODE (newdecl) == RESULT_DECL
           || TREE_CODE (newdecl) == FIELD_DECL
@@ -1974,7 +2008,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          /* Keep the old RTL.  */
          COPY_DECL_RTL (olddecl, newdecl);
        }
-      else if (TREE_CODE (newdecl) == VAR_DECL
+      else if (VAR_P (newdecl)
               && (DECL_SIZE (olddecl) || !DECL_SIZE (newdecl)))
        {
          /* Keep the old RTL.  We cannot keep the old RTL if the old
@@ -2064,8 +2098,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
        }
       /* Only functions have these fields.  */
-      if (TREE_CODE (newdecl) == FUNCTION_DECL
-         || DECL_FUNCTION_TEMPLATE_P (newdecl))
+      if (DECL_DECLARES_FUNCTION_P (newdecl))
        {
          DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
          olddecl_friend = DECL_FRIEND_P (olddecl);
@@ -2081,7 +2114,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            SET_DECL_THUNKS (newdecl, DECL_THUNKS (olddecl));
        }
       /* Only variables have this field.  */
-      else if (TREE_CODE (newdecl) == VAR_DECL
+      else if (VAR_P (newdecl)
               && VAR_HAD_UNKNOWN_BOUND (olddecl))
        SET_VAR_HAD_UNKNOWN_BOUND (newdecl);
     }
@@ -2257,7 +2290,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
     }
   /* Init priority used to be merged from newdecl to olddecl by the memcpy,
      so keep this behavior.  */
-  if (TREE_CODE (newdecl) == VAR_DECL && DECL_HAS_INIT_PRIORITY_P (newdecl))
+  if (VAR_P (newdecl) && DECL_HAS_INIT_PRIORITY_P (newdecl))
     {
       SET_DECL_INIT_PRIORITY (olddecl, DECL_INIT_PRIORITY (newdecl));
       DECL_HAS_INIT_PRIORITY_P (olddecl) = 1;
@@ -2286,7 +2319,7 @@ 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 (VAR_P (newdecl))
     {
       if (DECL_READ_P (olddecl))
        DECL_READ_P (newdecl) = 1;
@@ -2397,7 +2430,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
     flags and attributes.  */
   if (DECL_RTL_SET_P (olddecl)
       && (TREE_CODE (olddecl) == FUNCTION_DECL
-         || (TREE_CODE (olddecl) == VAR_DECL
+         || (VAR_P (olddecl)
              && TREE_STATIC (olddecl))))
     make_decl_rtl (olddecl);
 
@@ -2540,7 +2573,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
 
       return NULL;
     }
-  else if (TREE_CODE (newdecl) == VAR_DECL
+  else if (VAR_P (newdecl)
           && DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl)
           && (! DECL_LANG_SPECIFIC (olddecl)
               || ! CP_DECL_THREADPRIVATE_P (olddecl)
@@ -2565,8 +2598,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
           union { int i; };
 
           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)))
+      if ((VAR_P (newdecl) && DECL_ANON_UNION_VAR_P (newdecl))
+         || (VAR_P (olddecl) && DECL_ANON_UNION_VAR_P (olddecl)))
        return G_("redeclaration of %q#D");
       /* If at least one declaration is a reference, there is no
         conflict.  For example:
@@ -2718,7 +2751,7 @@ decl_jump_unsafe (tree decl)
      preceding types and is declared without an initializer (8.5).  */
   tree type = TREE_TYPE (decl);
 
-  if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)
+  if (!VAR_P (decl) || TREE_STATIC (decl)
       || type == error_mark_node)
     return 0;
 
@@ -3082,13 +3115,15 @@ case_conversion (tree type, tree value)
   if (value == NULL_TREE)
     return value;
 
-  if (cxx_dialect >= cxx0x
+  if (cxx_dialect >= cxx11
       && (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);
+      value = (perform_implicit_conversion_flags
+              (type, value, tf_warning_or_error,
+               LOOKUP_IMPLICIT | LOOKUP_NO_NON_INTEGRAL));
     }
   return cxx_constant_value (value);
 }
@@ -3783,10 +3818,10 @@ cxx_init_decl_processing (void)
     newtype = build_exception_variant (newtype, new_eh_spec);
     deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
     deltype = build_exception_variant (deltype, 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);
+    DECL_IS_OPERATOR_NEW (push_cp_library_fn (NEW_EXPR, newtype, 0)) = 1;
+    DECL_IS_OPERATOR_NEW (push_cp_library_fn (VEC_NEW_EXPR, newtype, 0)) = 1;
+    global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+    push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
 
     nullptr_type_node = make_node (NULLPTR_TYPE);
     TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
@@ -3799,7 +3834,8 @@ cxx_init_decl_processing (void)
   }
 
   abort_fndecl
-    = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
+    = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype,
+                           ECF_NORETURN | ECF_NOTHROW);
 
   /* Perform other language dependent initializations.  */
   init_class_processing ();
@@ -3990,7 +4026,8 @@ cxx_builtin_function_ext_scope (tree decl)
    function.  Not called directly.  */
 
 static tree
-build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
+build_library_fn (tree name, enum tree_code operator_code, tree type,
+                 int ecf_flags)
 {
   tree fn = build_lang_decl (FUNCTION_DECL, name, type);
   DECL_EXTERNAL (fn) = 1;
@@ -4002,28 +4039,17 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
      external shared object.  */
   DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
   DECL_VISIBILITY_SPECIFIED (fn) = 1;
-  return fn;
-}
-
-/* Returns the _DECL for a library function with C linkage.
-   We assume that such functions never throw; if this is incorrect,
-   callers should unset TREE_NOTHROW.  */
-
-static tree
-build_library_fn (tree name, tree type)
-{
-  tree fn = build_library_fn_1 (name, ERROR_MARK, type);
-  TREE_NOTHROW (fn) = 1;
+  set_call_expr_flags (fn, ecf_flags);
   return fn;
 }
 
 /* Returns the _DECL for a library function with C++ linkage.  */
 
 static tree
-build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
+build_cp_library_fn (tree name, enum tree_code operator_code, tree type,
+                    int ecf_flags)
 {
-  tree fn = build_library_fn_1 (name, operator_code, type);
-  TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
+  tree fn = build_library_fn (name, operator_code, type, ecf_flags);
   DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
   SET_DECL_LANGUAGE (fn, lang_cplusplus);
   return fn;
@@ -4033,18 +4059,19 @@ build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
    IDENTIFIER_NODE.  */
 
 tree
-build_library_fn_ptr (const char* name, tree type)
+build_library_fn_ptr (const char* name, tree type, int ecf_flags)
 {
-  return build_library_fn (get_identifier (name), type);
+  return build_library_fn (get_identifier (name), ERROR_MARK, type, ecf_flags);
 }
 
 /* Like build_cp_library_fn, but takes a C string instead of an
    IDENTIFIER_NODE.  */
 
 tree
-build_cp_library_fn_ptr (const char* name, tree type)
+build_cp_library_fn_ptr (const char* name, tree type, int ecf_flags)
 {
-  return build_cp_library_fn (get_identifier (name), ERROR_MARK, type);
+  return build_cp_library_fn (get_identifier (name), ERROR_MARK, type,
+                             ecf_flags);
 }
 
 /* Like build_library_fn, but also pushes the function so that we will
@@ -4052,14 +4079,14 @@ build_cp_library_fn_ptr (const char* name, tree type)
    may throw exceptions listed in RAISES.  */
 
 tree
-push_library_fn (tree name, tree type, tree raises)
+push_library_fn (tree name, tree type, tree raises, int ecf_flags)
 {
   tree fn;
 
   if (raises)
     type = build_exception_variant (type, raises);
 
-  fn = build_library_fn (name, type);
+  fn = build_library_fn (name, ERROR_MARK, type, ecf_flags);
   pushdecl_top_level (fn);
   return fn;
 }
@@ -4068,11 +4095,12 @@ push_library_fn (tree name, tree type, tree raises)
    will be found by normal lookup.  */
 
 static tree
-push_cp_library_fn (enum tree_code operator_code, tree type)
+push_cp_library_fn (enum tree_code operator_code, tree type,
+                   int ecf_flags)
 {
   tree fn = build_cp_library_fn (ansi_opname (operator_code),
                                 operator_code,
-                                type);
+                                type, ecf_flags);
   pushdecl (fn);
   if (flag_tm)
     apply_tm_attr (fn, get_identifier ("transaction_safe"));
@@ -4083,10 +4111,10 @@ push_cp_library_fn (enum tree_code operator_code, tree type)
    a FUNCTION_TYPE.  */
 
 tree
-push_void_library_fn (tree name, tree parmtypes)
+push_void_library_fn (tree name, tree parmtypes, int ecf_flags)
 {
   tree type = build_function_type (void_type_node, parmtypes);
-  return push_library_fn (name, type, NULL_TREE);
+  return push_library_fn (name, type, NULL_TREE, ecf_flags);
 }
 
 /* Like push_library_fn, but also note that this function throws
@@ -4095,9 +4123,7 @@ push_void_library_fn (tree name, tree parmtypes)
 tree
 push_throw_library_fn (tree name, tree type)
 {
-  tree fn = push_library_fn (name, type, NULL_TREE);
-  TREE_THIS_VOLATILE (fn) = 1;
-  TREE_NOTHROW (fn) = 0;
+  tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN);
   return fn;
 }
 \f
@@ -4184,7 +4210,7 @@ void
 warn_misplaced_attr_for_class_type (source_location location,
                                    tree class_type)
 {
-  gcc_assert (TAGGED_TYPE_P (class_type));
+  gcc_assert (OVERLOAD_TYPE_P (class_type));
 
   warning_at (location, OPT_Wattributes,
              "attribute ignored in declaration "
@@ -4452,7 +4478,7 @@ start_decl (const cp_declarator *declarator,
 
   deprecated_state = DEPRECATED_NORMAL;
 
-  if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE
+  if (decl == NULL_TREE || VOID_TYPE_P (decl)
       || decl == error_mark_node)
     return error_mark_node;
 
@@ -4499,7 +4525,7 @@ start_decl (const cp_declarator *declarator,
   /* If this is a typedef that names the class for linkage purposes
      (7.1.3p8), apply any attributes directly to the type.  */
   if (TREE_CODE (decl) == TYPE_DECL
-      && TAGGED_TYPE_P (TREE_TYPE (decl))
+      && OVERLOAD_TYPE_P (TREE_TYPE (decl))
       && decl == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))))
     flags = ATTR_FLAG_TYPE_IN_PLACE;
   else
@@ -4530,10 +4556,10 @@ start_decl (const cp_declarator *declarator,
 
   if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context)))
     {
-      if (TREE_CODE (decl) == VAR_DECL)
+      if (VAR_P (decl))
        {
          tree field = lookup_field (context, DECL_NAME (decl), 0, false);
-         if (field == NULL_TREE || TREE_CODE (field) != VAR_DECL)
+         if (field == NULL_TREE || !VAR_P (field))
            error ("%q#D is not a static member of %q#T", decl, context);
          else
            {
@@ -4610,7 +4636,7 @@ start_decl (const cp_declarator *declarator,
   if (decl == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (decl) == VAR_DECL
+  if (VAR_P (decl)
       && DECL_NAMESPACE_SCOPE_P (decl) && !TREE_PUBLIC (decl) && !was_public
       && !DECL_THIS_STATIC (decl) && !DECL_ARTIFICIAL (decl))
     {
@@ -4621,7 +4647,7 @@ start_decl (const cp_declarator *declarator,
       DECL_THIS_STATIC (decl) = 1;
     }
 
-  if (!processing_template_decl && TREE_CODE (decl) == VAR_DECL)
+  if (!processing_template_decl && VAR_P (decl))
     start_decl_1 (decl, initialized);
 
   return decl;
@@ -4646,7 +4672,7 @@ start_decl_1 (tree decl, bool initialized)
   if (error_operand_p (decl))
     return;
 
-  gcc_assert (TREE_CODE (decl) == VAR_DECL);
+  gcc_assert (VAR_P (decl));
 
   type = TREE_TYPE (decl);
   complete_p = COMPLETE_TYPE_P (type);
@@ -4760,7 +4786,7 @@ grok_reference_init (tree decl, tree type, tree init, int flags)
    is valid, i.e., does not have a designated initializer.  */
 
 static bool
-check_array_designated_initializer (const constructor_elt *ce,
+check_array_designated_initializer (constructor_elt *ce,
                                    unsigned HOST_WIDE_INT index)
 {
   /* Designated initializers for array elements are not supported.  */
@@ -4769,22 +4795,31 @@ check_array_designated_initializer (const constructor_elt *ce,
       /* The parser only allows identifiers as designated
         initializers.  */
       if (ce->index == error_mark_node)
-       error ("name used in a GNU-style designated "
-              "initializer for an array");
-      else if (TREE_CODE (ce->index) == INTEGER_CST)
+       {
+         error ("name used in a GNU-style designated "
+                "initializer for an array");
+         return false;
+       }
+      else if (identifier_p (ce->index))
+       {
+         error ("name %qD used in a GNU-style designated "
+                "initializer for an array", ce->index);
+         return false;
+       }
+
+      ce->index = cxx_constant_value (ce->index);
+
+      if (TREE_CODE (ce->index) == INTEGER_CST)
        {
          /* A C99 designator is OK if it matches the current index.  */
-         if (TREE_INT_CST_LOW (ce->index) == index)
+         if (wi::eq_p (ce->index, index))
            return true;
          else
            sorry ("non-trivial designated initializers not supported");
        }
       else
-       {
-         gcc_assert (identifier_p (ce->index));
-         error ("name %qD used in a GNU-style designated "
-                "initializer for an array", ce->index);
-       }
+       gcc_unreachable ();
+
       return false;
     }
 
@@ -4869,7 +4904,7 @@ layout_var_decl (tree decl)
   if (type == error_mark_node)
     return;
 
-  /* If we haven't already layed out this declaration, do so now.
+  /* If we haven't already laid out this declaration, do so now.
      Note that we must not call complete type for an external object
      because it's type might involve templates that we are not
      supposed to instantiate yet.  (And it's perfectly valid to say
@@ -4983,7 +5018,7 @@ check_for_uninitialized_const_var (tree 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
+  if (VAR_P (decl)
       && TREE_CODE (type) != REFERENCE_TYPE
       && CP_TYPE_CONST_P (type)
       && !DECL_INITIAL (decl))
@@ -5051,7 +5086,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
                      tsubst_flags_t complain)
 {
   tree new_init;
-  bool sized_array_p = (max_index != NULL_TREE);
+  bool sized_array_p = (max_index && TREE_CONSTANT (max_index));
   unsigned HOST_WIDE_INT max_index_cst = 0;
   unsigned HOST_WIDE_INT index;
 
@@ -5064,12 +5099,11 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
       if (integer_all_onesp (max_index))
        return new_init;
 
-      if (host_integerp (max_index, 1))
-       max_index_cst = tree_low_cst (max_index, 1);
+      if (tree_fits_uhwi_p (max_index))
+       max_index_cst = tree_to_uhwi (max_index);
       /* sizetype is sign extended, not zero extended.  */
       else
-       max_index_cst = tree_low_cst (fold_convert (size_type_node, max_index),
-                                     1);
+       max_index_cst = tree_to_uhwi (fold_convert (size_type_node, max_index));
     }
 
   /* Loop until there are no more initializers.  */
@@ -5186,6 +5220,9 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
       /* Handle designated initializers, as an extension.  */
       if (d->cur->index)
        {
+         if (d->cur->index == error_mark_node)
+           return error_mark_node;
+
          if (TREE_CODE (d->cur->index) == INTEGER_CST)
            {
              if (complain & tf_error)
@@ -5501,15 +5538,12 @@ check_array_initializer (tree decl, tree type, tree init)
        error ("elements of array %q#T have incomplete type", type);
       return true;
     }
-  /* It is not valid to initialize a VLA.  */
-  if (init
+  /* A compound literal can't have variable size.  */
+  if (init && !decl
       && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
          || !TREE_CONSTANT (TYPE_SIZE (element_type))))
     {
-      if (decl)
-       error ("variable-sized object %qD may not be initialized", decl);
-      else
-       error ("variable-sized compound literal");
+      error ("variable-sized compound literal");
       return true;
     }
   return false;
@@ -5656,6 +5690,7 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups)
          && !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
               && CP_AGGREGATE_TYPE_P (type)
               && (CLASS_TYPE_P (type)
+                  || !TYPE_NEEDS_CONSTRUCTING (type)
                   || type_has_extended_temps (type))))
        {
          init_code = build_aggr_init_full_exprs (decl, init, flags);
@@ -5740,7 +5775,7 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups)
     {
       static int explained = 0;
 
-      if (cxx_dialect < cxx0x)
+      if (cxx_dialect < cxx11)
        error ("initializer invalid for static member with constructor");
       else
        error ("non-constant in-class initialization invalid for static "
@@ -5770,7 +5805,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
       /* The `register' keyword, when used together with an
         asm-specification, indicates that the variable should be
         placed in a particular register.  */
-      if (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
+      if (VAR_P (decl) && DECL_REGISTER (decl))
        {
          set_user_assembler_name (decl, asmspec);
          DECL_HARD_REGISTER (decl) = 1;
@@ -5785,7 +5820,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
     }
 
   /* Handle non-variables up front.  */
-  if (TREE_CODE (decl) != VAR_DECL)
+  if (!VAR_P (decl))
     {
       rest_of_decl_compilation (decl, toplev, at_eof);
       return;
@@ -5903,7 +5938,7 @@ initialize_local_var (tree decl, tree init)
   tree cleanup;
   int already_used;
 
-  gcc_assert (TREE_CODE (decl) == VAR_DECL
+  gcc_assert (VAR_P (decl)
              || TREE_CODE (decl) == RESULT_DECL);
   gcc_assert (!TREE_STATIC (decl));
 
@@ -6134,12 +6169,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
                                                   auto_node);
       if (type == error_mark_node)
        return;
+      cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
     }
 
   if (!ensure_literal_type_for_constexpr_object (decl))
     DECL_DECLARED_CONSTEXPR_P (decl) = 0;
 
-  if (TREE_CODE (decl) == VAR_DECL
+  if (VAR_P (decl)
       && DECL_CLASS_SCOPE_P (decl)
       && DECL_INITIALIZED_IN_CLASS_P (decl))
     check_static_variable_definition (decl, type);
@@ -6170,7 +6206,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
        }
     }
 
-  if (init && TREE_CODE (decl) == VAR_DECL)
+  if (init && VAR_P (decl))
     {
       DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
       /* If DECL is a reference, then we want to know whether init is a
@@ -6209,7 +6245,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
         then it can be used in future constant expressions, so its value
         must be available. */
 
-      if (TREE_CODE (decl) != VAR_DECL || dependent_type_p (type))
+      if (!VAR_P (decl) || dependent_type_p (type))
        /* We can't do anything if the decl has dependent type.  */;
       else if (init
               && init_const_expr_p
@@ -6280,7 +6316,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       TREE_READONLY (decl) = 0;
     }
 
-  if (TREE_CODE (decl) == VAR_DECL)
+  if (VAR_P (decl))
     {
       /* If this is a local variable that will need a mangled name,
         register it now.  We must do this before processing the
@@ -6328,25 +6364,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          cleanups = make_tree_vector ();
          init = check_initializer (decl, init, flags, &cleanups);
 
-         /* Check that the initializer for a static data member was a
-            constant.  Although we check in the parser that the
-            initializer is an integral constant expression, we do not
-            simplify division-by-zero at the point at which it
-            occurs.  Therefore, in:
-
-              struct S { static const int i = 7 / 0; };
-
-            we issue an error at this point.  It would
-            probably be better to forbid division by zero in
-            integral constant expressions.  */
-         if (DECL_EXTERNAL (decl) && init)
-           {
-             error ("%qD cannot be initialized by a non-constant expression"
-                    " when being declared", decl);
-             DECL_INITIALIZED_IN_CLASS_P (decl) = 0;
-             init = NULL_TREE;
-           }
-
          /* Handle:
 
             [dcl.init]
@@ -6399,10 +6416,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   /* Let the middle end know about variables and functions -- but not
      static data members in uninstantiated class templates.  */
-  if (TREE_CODE (decl) == VAR_DECL
-      || TREE_CODE (decl) == FUNCTION_DECL)
+  if (VAR_OR_FUNCTION_DECL_P (decl))
     {
-      if (TREE_CODE (decl) == VAR_DECL)
+      if (VAR_P (decl))
        {
          layout_var_decl (decl);
          maybe_commonize_var (decl);
@@ -6622,7 +6638,7 @@ get_atexit_node (void)
 
   /* Now, build the function declaration.  */
   push_lang_context (lang_name_c);
-  atexit_fndecl = build_library_fn_ptr (name, fn_type);
+  atexit_fndecl = build_library_fn_ptr (name, fn_type, ECF_LEAF | ECF_NOTHROW);
   mark_used (atexit_fndecl);
   pop_lang_context ();
   atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
@@ -6644,7 +6660,8 @@ get_thread_atexit_node (void)
                                           NULL_TREE);
 
   /* Now, build the function declaration.  */
-  tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type);
+  tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type,
+                                            ECF_LEAF | ECF_NOTHROW);
   return decay_conversion (atexit_fndecl, tf_warning_or_error);
 }
 
@@ -6868,13 +6885,17 @@ register_dtor_fn (tree decl)
 static void
 expand_static_init (tree decl, tree init)
 {
-  gcc_assert (TREE_CODE (decl) == VAR_DECL);
+  gcc_assert (VAR_P (decl));
   gcc_assert (TREE_STATIC (decl));
 
   /* Some variables require no dynamic initialization.  */
   if (!init
       && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
-    return;
+    {
+      /* Make sure the destructor is callable.  */
+      cxx_maybe_build_cleanup (decl, tf_warning_or_error);
+      return;
+    }
 
   if (DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
       && !DECL_FUNCTION_SCOPE_P (decl))
@@ -6970,15 +6991,17 @@ expand_static_init (tree decl, tree init)
              (acquire_name, build_function_type_list (integer_type_node,
                                                       TREE_TYPE (guard_addr),
                                                       NULL_TREE),
-              NULL_TREE);
+              NULL_TREE, ECF_NOTHROW | ECF_LEAF);
          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);
+           release_fn = push_library_fn (release_name, vfntype, NULL_TREE,
+                                          ECF_NOTHROW | ECF_LEAF);
          if (!abort_fn)
-           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
+           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE,
+                                       ECF_NOTHROW | ECF_LEAF);
 
          inner_if_stmt = begin_if_stmt ();
          finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
@@ -7221,8 +7244,7 @@ check_class_member_definition_namespace (tree decl)
 {
   /* These checks only apply to member functions and static data
      members.  */
-  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
-             || TREE_CODE (decl) == VAR_DECL);
+  gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
   /* We check for problems with specializations in pt.c in
      check_specialization_namespace, where we can issue better
      diagnostics.  */
@@ -7287,6 +7309,22 @@ check_static_quals (tree decl, cp_cv_quals quals)
           decl);
 }
 
+/* Helper function.  Replace the temporary this parameter injected
+   during cp_finish_omp_declare_simd with the real this parameter.  */
+
+static tree
+declare_simd_adjust_this (tree *tp, int *walk_subtrees, void *data)
+{
+  tree this_parm = (tree) data;
+  if (TREE_CODE (*tp) == PARM_DECL
+      && DECL_NAME (*tp) == this_identifier
+      && *tp != this_parm)
+    *tp = this_parm;
+  else if (TYPE_P (*tp))
+    *walk_subtrees = 0;
+  return NULL_TREE;
+}
+
 /* CTYPE is class type, or null if non-class.
    TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
    or METHOD_TYPE.
@@ -7314,6 +7352,7 @@ grokfndecl (tree ctype,
            int virtualp,
            enum overload_flags flags,
            cp_cv_quals quals,
+           cp_ref_qualifier rqual,
            tree raises,
            int check,
            int friendp,
@@ -7330,6 +7369,8 @@ grokfndecl (tree ctype,
   int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
   tree t;
 
+  if (rqual)
+    type = build_ref_qualified_type (type, rqual);
   if (raises)
     type = build_exception_variant (type, raises);
 
@@ -7403,17 +7444,6 @@ grokfndecl (tree ctype,
             the information in the TEMPLATE_ID_EXPR.  */
          SET_DECL_IMPLICIT_INSTANTIATION (decl);
 
-         if (TREE_CODE (fns) == COMPONENT_REF)
-           {
-             /* Due to bison parser ickiness, we will have already looked
-                up an operator_name or PFUNCNAME within the current class
-                (see template_id in parse.y). If the current class contains
-                such a name, we'll get a COMPONENT_REF here. Undo that.  */
-
-             gcc_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
-                         == current_class_type);
-             fns = TREE_OPERAND (fns, 1);
-           }
          gcc_assert (identifier_p (fns) || TREE_CODE (fns) == OVERLOAD);
          DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args);
 
@@ -7451,7 +7481,9 @@ grokfndecl (tree ctype,
        || (IDENTIFIER_LENGTH (declarator) > 10
           && IDENTIFIER_POINTER (declarator)[0] == '_'
           && IDENTIFIER_POINTER (declarator)[1] == '_'
-          && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0))
+          && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0)
+       || (targetcm.cxx_implicit_extern_c
+          && targetcm.cxx_implicit_extern_c(IDENTIFIER_POINTER (declarator))))
       && current_lang_name == lang_name_cplusplus
       && ctype == NULL_TREE
       && DECL_FILE_SCOPE_P (decl))
@@ -7537,13 +7569,25 @@ grokfndecl (tree ctype,
     DECL_DECLARED_CONSTEXPR_P (decl) = true;
 
   DECL_EXTERNAL (decl) = 1;
-  if (quals && TREE_CODE (type) == FUNCTION_TYPE)
+  if (TREE_CODE (type) == FUNCTION_TYPE)
     {
-      error (ctype
-             ? G_("static member function %qD cannot have cv-qualifier")
-             : G_("non-member function %qD cannot have cv-qualifier"),
-            decl);
-      quals = TYPE_UNQUALIFIED;
+      if (quals)
+       {
+         error (ctype
+                ? G_("static member function %qD cannot have cv-qualifier")
+                : G_("non-member function %qD cannot have cv-qualifier"),
+                decl);
+         quals = TYPE_UNQUALIFIED;
+       }
+
+      if (rqual)
+       {
+         error (ctype
+                ? G_("static member function %qD cannot have ref-qualifier")
+                : G_("non-member function %qD cannot have ref-qualifier"),
+                decl);
+         rqual = REF_QUAL_NONE;
+       }
     }
 
   if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))
@@ -7599,6 +7643,33 @@ grokfndecl (tree ctype,
   if (TYPE_NOTHROW_P (type) || nothrow_libfn_p (decl))
     TREE_NOTHROW (decl) = 1;
 
+  if (flag_openmp)
+    {
+      /* Adjust "omp declare simd" attributes.  */
+      tree ods = lookup_attribute ("omp declare simd", *attrlist);
+      if (ods)
+       {
+         tree attr;
+         for (attr = ods; attr;
+              attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr)))
+           {
+             if (TREE_CODE (type) == METHOD_TYPE)
+               walk_tree (&TREE_VALUE (attr), declare_simd_adjust_this,
+                          DECL_ARGUMENTS (decl), NULL);
+             if (TREE_VALUE (attr) != NULL_TREE)
+               {
+                 tree cl = TREE_VALUE (TREE_VALUE (attr));
+                 cl = c_omp_declare_simd_clauses_to_numbers
+                                               (DECL_ARGUMENTS (decl), cl);
+                 if (cl)
+                   TREE_VALUE (TREE_VALUE (attr)) = cl;
+                 else
+                   TREE_VALUE (attr) = NULL_TREE;
+               }
+           }
+       }
+    }
+
   /* Caller will do the rest of this.  */
   if (check < 0)
     return decl;
@@ -7607,7 +7678,7 @@ grokfndecl (tree ctype,
     grokclassfn (ctype, decl, flags);
 
   /* 12.4/3  */
-  if (cxx_dialect >= cxx0x
+  if (cxx_dialect >= cxx11
       && DECL_DESTRUCTOR_P (decl)
       && !TYPE_BEING_DEFINED (DECL_CONTEXT (decl))
       && !processing_template_decl)
@@ -7981,7 +8052,8 @@ build_ptrmem_type (tree class_type, tree member_type)
   if (TREE_CODE (member_type) == METHOD_TYPE)
     {
       cp_cv_quals quals = type_memfn_quals (member_type);
-      member_type = build_memfn_type (member_type, class_type, quals);
+      cp_ref_qualifier rqual = type_memfn_rqual (member_type);
+      member_type = build_memfn_type (member_type, class_type, quals, rqual);
       return build_ptrmemfunc_type (build_pointer_type (member_type));
     }
   else
@@ -8006,7 +8078,7 @@ check_static_variable_definition (tree decl, tree type)
      in check_initializer.  */
   if (DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl))
     return 0;
-  else if (cxx_dialect >= cxx0x && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+  else if (cxx_dialect >= cxx11 && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     {
       if (!COMPLETE_TYPE_P (type))
        error ("in-class initialization of static data member %q#D of "
@@ -8128,7 +8200,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
 
       mark_rvalue_use (size);
 
-      if (cxx_dialect < cxx0x && TREE_CODE (size) == NOP_EXPR
+      if (cxx_dialect < cxx11 && TREE_CODE (size) == NOP_EXPR
          && TREE_SIDE_EFFECTS (size))
        /* In C++98, we mark a non-constant array bound with a magic
           NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case.  */;
@@ -8194,7 +8266,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
         constant. Just build the index type and mark that it requires
         structural equality checks.  */
       itype = build_index_type (build_min (MINUS_EXPR, sizetype,
-                                          size, integer_one_node));
+                                          size, size_one_node));
       TYPE_DEPENDENT_P (itype) = 1;
       TYPE_DEPENDENT_P_VALID (itype) = 1;
       SET_TYPE_STRUCTURAL_EQUALITY (itype);
@@ -8249,7 +8321,8 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
   else if (TREE_CONSTANT (size)
           /* We don't allow VLAs at non-function scopes, or during
              tentative template substitution.  */
-          || !at_function_scope_p () || !(complain & tf_error))
+          || !at_function_scope_p ()
+          || (cxx_dialect < cxx1y && !(complain & tf_error)))
     {
       if (!(complain & tf_error))
        return error_mark_node;
@@ -8261,7 +8334,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
        error ("size of array is not an integral constant-expression");
       size = integer_one_node;
     }
-  else if (pedantic && warn_vla != 0)
+  else if (cxx_dialect < cxx1y && pedantic && warn_vla != 0)
     {
       if (name)
        pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
@@ -8304,6 +8377,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
        {
          /* A variable sized array.  */
          itype = variable_size (itype);
+
          if (TREE_CODE (itype) != SAVE_EXPR)
            {
              /* Look for SIZEOF_EXPRs in itype and fold them, otherwise
@@ -8315,6 +8389,32 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
              if (found)
                itype = variable_size (fold (newitype));
            }
+
+         stabilize_vla_size (itype);
+
+         if (cxx_dialect >= cxx1y)
+           {
+             /* If the VLA bound is larger than half the address space,
+                or less than zero, throw std::bad_array_length.  */
+             tree comp = build2 (LT_EXPR, boolean_type_node, itype,
+                                 ssize_int (-1));
+             comp = build3 (COND_EXPR, void_type_node, comp,
+                            throw_bad_array_length (), void_zero_node);
+             finish_expr_stmt (comp);
+           }
+         else if (flag_sanitize & SANITIZE_VLA)
+           {
+             /* From C++1y onwards, we throw an exception on a negative
+                length size of an array; see above.  */
+
+             /* We have to add 1 -- in the ubsan routine we generate
+                LE_EXPR rather than LT_EXPR.  */
+             tree t = fold_build2 (PLUS_EXPR, TREE_TYPE (itype), itype,
+                                   build_one_cst (TREE_TYPE (itype)));
+             t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t),
+                              ubsan_instrument_vla (input_location, t), t);
+             finish_expr_stmt (t);
+           }
        }
       /* Make sure that there was no overflow when creating to a signed
         index type.  (For example, on a 32-bit machine, an array with
@@ -8439,6 +8539,9 @@ create_array_type_for_decl (tree name, tree type, tree size)
       return error_mark_node;
     }
 
+  if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+    pedwarn (input_location, OPT_Wvla, "array of array of runtime bound");
+
   /* Figure out the index type for the array.  */
   if (size)
     itype = compute_array_index_type (name, size, tf_warning_or_error);
@@ -8630,6 +8733,9 @@ grokdeclarator (const cp_declarator *declarator,
   /* virt-specifiers that apply to the declarator, for a declaration of
      a member function.  */
   cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
+  /* ref-qualifier that applies to the declarator, for a declaration of
+     a member function.  */
+  cp_ref_qualifier rqual = REF_QUAL_NONE;
   /* cv-qualifiers that apply to the type specified by the DECLSPECS.  */
   int type_quals;
   tree raises = NULL_TREE;
@@ -8745,8 +8851,8 @@ grokdeclarator (const cp_declarator *declarator,
                             && !uniquely_derived_from_p (ctype,
                                                          current_class_type))
                      {
-                       error ("type %qT is not derived from type %qT",
-                              ctype, current_class_type);
+                       error ("invalid use of qualified-name %<%T::%D%>",
+                              qualifying_scope, decl);
                        return error_mark_node;
                      }
                  }
@@ -9439,6 +9545,8 @@ grokdeclarator (const cp_declarator *declarator,
            memfn_quals = declarator->u.function.qualifiers;
            /* Pick up virt-specifiers.  */
             virt_specifiers = declarator->u.function.virt_specifiers;
+           /* And ref-qualifier, too */
+           rqual = declarator->u.function.ref_qualifier;
            /* Pick up the exception specifications.  */
            raises = declarator->u.function.exception_specification;
            /* If the exception-specification is ill-formed, let's pretend
@@ -9464,6 +9572,9 @@ grokdeclarator (const cp_declarator *declarator,
                          pedwarn (input_location, 0, "%qs function uses "
                                   "%<auto%> type specifier without trailing "
                                   "return type", name);
+                       else if (virtualp)
+                         permerror (input_location, "virtual function cannot "
+                                    "have deduced return type");
                      }
                    else if (!is_auto (type))
                      {
@@ -9475,7 +9586,7 @@ grokdeclarator (const cp_declarator *declarator,
                  }
                else if (declarator->u.function.late_return_type)
                  {
-                   if (cxx_dialect < cxx0x)
+                   if (cxx_dialect < cxx11)
                      /* Not using maybe_warn_cpp0x because this should
                         always be an error.  */
                      error ("trailing return type only available with "
@@ -9506,12 +9617,13 @@ grokdeclarator (const cp_declarator *declarator,
                   therefore returns a void type.  */
 
                /* ISO C++ 12.4/2.  A destructor may not be declared
-                  const or volatile.  A destructor may not be
-                  static.
+                  const or volatile.  A destructor may not be static.
+                  A destructor may not be declared with ref-qualifier.
 
                   ISO C++ 12.1.  A constructor may not be declared
                   const or volatile.  A constructor may not be
-                  virtual.  A constructor may not be static.  */
+                  virtual.  A constructor may not be static.
+                  A constructor may not be declared with ref-qualifier. */
                if (staticp == 2)
                  error ((flags == DTOR_FLAG)
                         ? G_("destructor cannot be static member function")
@@ -9524,6 +9636,15 @@ grokdeclarator (const cp_declarator *declarator,
                    memfn_quals = TYPE_UNQUALIFIED;
                  }
 
+               if (rqual)
+                 {
+                   maybe_warn_cpp0x (CPP0X_REF_QUALIFIER);
+                   error ((flags == DTOR_FLAG)
+                          ? "destructors may not be ref-qualified"
+                          : "constructors may not be ref-qualified");
+                   rqual = REF_QUAL_NONE;
+                 }
+
                if (decl_context == FIELD
                    && !member_function_or_else (ctype,
                                                 current_class_type,
@@ -9645,19 +9766,29 @@ grokdeclarator (const cp_declarator *declarator,
              memfn_quals |= type_memfn_quals (type);
              type = build_memfn_type (type,
                                       declarator->u.pointer.class_type,
-                                      memfn_quals);
+                                      memfn_quals,
+                                      rqual);
              if (type == error_mark_node)
                return error_mark_node;
+
+             rqual = REF_QUAL_NONE;
              memfn_quals = TYPE_UNQUALIFIED;
            }
 
          if (TREE_CODE (type) == FUNCTION_TYPE
-             && type_memfn_quals (type) != TYPE_UNQUALIFIED)
+             && (type_memfn_quals (type) != TYPE_UNQUALIFIED
+                 || type_memfn_rqual (type) != REF_QUAL_NONE))
             error (declarator->kind == cdk_reference
                    ? G_("cannot declare reference to qualified function type %qT")
                    : G_("cannot declare pointer to qualified function type %qT"),
                   type);
 
+         if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+           pedwarn (input_location, OPT_Wvla,
+                    declarator->kind == cdk_reference
+                    ? G_("reference to array of runtime bound")
+                    : G_("pointer to array of runtime bound"));
+
          /* 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
@@ -9684,12 +9815,8 @@ grokdeclarator (const cp_declarator *declarator,
              && (decl_context == NORMAL || decl_context == FIELD)
              && at_function_scope_p ()
              && variably_modified_type_p (type, NULL_TREE))
-           {
-             /* First break out any side-effects.  */
-             stabilize_vla_size (TYPE_SIZE (type));
-             /* And then force evaluation of the SAVE_EXPR.  */
-             finish_expr_stmt (TYPE_SIZE (type));
-           }
+           /* Force evaluation of the SAVE_EXPR.  */
+           finish_expr_stmt (TYPE_SIZE (type));
 
          if (declarator->kind == cdk_reference)
            {
@@ -9780,14 +9907,6 @@ grokdeclarator (const cp_declarator *declarator,
        }
     }
 
-  /* We need to stabilize side-effects in VLA sizes for regular array
-     declarations too, not just pointers to arrays.  */
-  if (type != error_mark_node && !TYPE_NAME (type)
-      && (decl_context == NORMAL || decl_context == FIELD)
-      && at_function_scope_p ()
-      && variably_modified_type_p (type, NULL_TREE))
-    stabilize_vla_size (TYPE_SIZE (type));
-
   /* A `constexpr' specifier used in an object declaration declares
      the object as `const'.  */
   if (constexpr_p && innermost_code != cdk_function)
@@ -9919,7 +10038,7 @@ grokdeclarator (const cp_declarator *declarator,
     {
       error ("size of array %qs is too large", name);
       /* If we proceed with the array type as it is, we'll eventually
-        crash in tree_low_cst().  */
+        crash in tree_to_[su]hwi().  */
       type = error_mark_node;
     }
 
@@ -9997,12 +10116,13 @@ grokdeclarator (const cp_declarator *declarator,
         example "f S::*" declares a pointer to a const-qualified
         member function of S.  We record the cv-qualification in the
         function type.  */
-      if (memfn_quals && TREE_CODE (type) == FUNCTION_TYPE)
+      if ((rqual || memfn_quals) && TREE_CODE (type) == FUNCTION_TYPE)
         {
-          type = apply_memfn_quals (type, memfn_quals);
+          type = apply_memfn_quals (type, memfn_quals, rqual);
           
           /* We have now dealt with these qualifiers.  */
           memfn_quals = TYPE_UNQUALIFIED;
+         rqual = REF_QUAL_NONE;
         }
 
       if (type_uses_auto (type))
@@ -10011,6 +10131,10 @@ grokdeclarator (const cp_declarator *declarator,
          type = error_mark_node;
        }
 
+      if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+       pedwarn (input_location, OPT_Wvla,
+                "typedef naming array of runtime bound");
+
       if (decl_context == FIELD)
        decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
       else
@@ -10132,8 +10256,10 @@ grokdeclarator (const cp_declarator *declarator,
       if (decl_context != TYPENAME)
        {
          /* A cv-qualifier-seq shall only be part of the function type
-            for a non-static member function. [8.3.5/4 dcl.fct] */
-         if (type_memfn_quals (type) != TYPE_UNQUALIFIED
+            for a non-static member function. A ref-qualifier shall only
+            .... /same as above/ [dcl.fct] */
+         if ((type_memfn_quals (type) != TYPE_UNQUALIFIED
+              || type_memfn_rqual (type) != REF_QUAL_NONE)
              && (current_class_type == NULL_TREE || staticp) )
            {
              error (staticp
@@ -10147,6 +10273,7 @@ grokdeclarator (const cp_declarator *declarator,
          /* The qualifiers on the function type become the qualifiers on
             the non-static member function. */
          memfn_quals |= type_memfn_quals (type);
+         rqual = type_memfn_rqual (type);
          type_quals = TYPE_UNQUALIFIED;
        }
     }
@@ -10204,17 +10331,19 @@ grokdeclarator (const cp_declarator *declarator,
              type = void_type_node;
            }
        }
-      else if (memfn_quals)
+      else if (memfn_quals || rqual)
        {
          if (ctype == NULL_TREE
              && TREE_CODE (type) == METHOD_TYPE)
            ctype = TYPE_METHOD_BASETYPE (type);
 
          if (ctype)
-           type = build_memfn_type (type, ctype, memfn_quals);
-         /* Core issue #547: need to allow this in template type args.  */
-         else if (template_type_arg && TREE_CODE (type) == FUNCTION_TYPE)
-           type = apply_memfn_quals (type, memfn_quals);
+           type = build_memfn_type (type, ctype, memfn_quals, rqual);
+         /* Core issue #547: need to allow this in template type args.
+            Allow it in general in C++11 for alias-declarations.  */
+         else if ((template_type_arg || cxx_dialect >= cxx11)
+                  && TREE_CODE (type) == FUNCTION_TYPE)
+           type = apply_memfn_quals (type, memfn_quals, rqual);
          else
            error ("invalid qualifiers on non-member function type");
        }
@@ -10259,7 +10388,10 @@ grokdeclarator (const cp_declarator *declarator,
 
       if (type_uses_auto (type))
        {
-         error ("parameter declared %<auto%>");
+         if (cxx_dialect >= cxx1y)
+           error ("%<auto%> parameter not permitted in this context");
+         else
+           error ("parameter declared %<auto%>");
          type = error_mark_node;
        }
 
@@ -10283,7 +10415,7 @@ grokdeclarator (const cp_declarator *declarator,
       cp_cv_quals real_quals = memfn_quals;
       if (constexpr_p && sfk != sfk_constructor && sfk != sfk_destructor)
        real_quals |= TYPE_QUAL_CONST;
-      type = build_memfn_type (type, ctype, real_quals);
+      type = build_memfn_type (type, ctype, real_quals, rqual);
     }
 
   {
@@ -10415,7 +10547,7 @@ grokdeclarator (const cp_declarator *declarator,
                               ? unqualified_id : dname,
                               parms,
                               unqualified_id,
-                              virtualp, flags, memfn_quals, raises,
+                              virtualp, flags, memfn_quals, rqual, raises,
                               friendp ? -1 : 0, friendp, publicp,
                                inlinep | (2 * constexpr_p),
                               sfk,
@@ -10445,21 +10577,13 @@ grokdeclarator (const cp_declarator *declarator,
                 && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
          {
            if (unqualified_id)
-             error ("field %qD has incomplete type", unqualified_id);
+             error ("field %qD has incomplete type %qT",
+                    unqualified_id, type);
            else
              error ("name %qT has incomplete type", type);
 
-           /* If we're instantiating a template, tell them which
-              instantiation made the field's type be incomplete.  */
-           if (current_class_type
-               && TYPE_NAME (current_class_type)
-               && IDENTIFIER_TEMPLATE (current_class_name)
-               && declspecs->type
-               && declspecs->type == type)
-             error ("  in instantiation of template %qT",
-                    current_class_type);
-
-           return error_mark_node;
+           type = error_mark_node;
+           decl = NULL_TREE;
          }
        else
          {
@@ -10636,7 +10760,7 @@ grokdeclarator (const cp_declarator *declarator,
                   || storage_class != sc_static);
 
        decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
-                          virtualp, flags, memfn_quals, raises,
+                          virtualp, flags, memfn_quals, rqual, raises,
                           1, friendp,
                           publicp, inlinep | (2 * constexpr_p), sfk,
                            funcdef_flag,
@@ -10743,7 +10867,7 @@ grokdeclarator (const cp_declarator *declarator,
       DECL_THIS_STATIC (decl) = 1;
 
     /* Set constexpr flag on vars (functions got it in grokfndecl).  */
-    if (constexpr_p && TREE_CODE (decl) == VAR_DECL)
+    if (constexpr_p && VAR_P (decl))
       DECL_DECLARED_CONSTEXPR_P (decl) = true;
 
     /* Record constancy and volatility on the DECL itself .  There's
@@ -10785,7 +10909,7 @@ require_complete_types_for_parms (tree parms)
 int
 local_variable_p (const_tree t)
 {
-  if ((TREE_CODE (t) == VAR_DECL
+  if ((VAR_P (t)
        /* A VAR_DECL with a context that is a _TYPE is a static data
          member.  */
        && !TYPE_P (CP_DECL_CONTEXT (t))
@@ -10819,7 +10943,7 @@ local_variable_p_walkfn (tree *tp, int *walk_subtrees,
    DECL, if there is no DECL available.  */
 
 tree
-check_default_argument (tree decl, tree arg)
+check_default_argument (tree decl, tree arg, tsubst_flags_t complain)
 {
   tree var;
   tree decl_type;
@@ -10851,13 +10975,14 @@ check_default_argument (tree decl, tree arg)
      A default argument expression is implicitly converted to the
      parameter type.  */
   ++cp_unevaluated_operand;
-  perform_implicit_conversion_flags (decl_type, arg, tf_warning_or_error,
+  perform_implicit_conversion_flags (decl_type, arg, complain,
                                     LOOKUP_IMPLICIT);
   --cp_unevaluated_operand;
 
   if (warn_zero_as_null_pointer_constant
       && TYPE_PTR_OR_PTRMEM_P (decl_type)
       && null_ptr_cst_p (arg)
+      && (complain & tf_warning)
       && maybe_warn_zero_as_null_pointer_constant (arg, input_location))
     return nullptr_node;
 
@@ -10871,10 +10996,14 @@ check_default_argument (tree decl, tree arg)
   var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL);
   if (var)
     {
-      if (DECL_NAME (var) == this_identifier)
-       permerror (input_location, "default argument %qE uses %qD", arg, var);
-      else
-       error ("default argument %qE uses local variable %qD", arg, var);
+      if (complain & tf_warning_or_error)
+       {
+         if (DECL_NAME (var) == this_identifier)
+           permerror (input_location, "default argument %qE uses %qD",
+                      arg, var);
+         else
+           error ("default argument %qE uses local variable %qD", arg, var);
+       }
       return error_mark_node;
     }
 
@@ -10895,7 +11024,7 @@ type_is_deprecated (tree type)
     return type;
 
   /* Do warn about using typedefs to a deprecated class.  */
-  if (TAGGED_TYPE_P (type) && type != TYPE_MAIN_VARIANT (type))
+  if (OVERLOAD_TYPE_P (type) && type != TYPE_MAIN_VARIANT (type))
     return type_is_deprecated (TYPE_MAIN_VARIANT (type));
 
   code = TREE_CODE (type);
@@ -11025,7 +11154,7 @@ grokparms (tree parmlist, tree *parms)
          if (any_error)
            init = NULL_TREE;
          else if (init && !processing_template_decl)
-           init = check_default_argument (decl, init);
+           init = check_default_argument (decl, init, tf_warning_or_error);
        }
 
       DECL_CHAIN (decl) = decls;
@@ -11481,7 +11610,7 @@ grok_op_properties (tree decl, bool complain)
          if (ref)
            t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
 
-         if (TREE_CODE (t) == VOID_TYPE)
+         if (VOID_TYPE_P (t))
             warning (OPT_Wconversion,
                      ref
                      ? G_("conversion to a reference to void "
@@ -11767,14 +11896,14 @@ check_elaborated_type_specifier (enum tag_types tag_code,
           && tag_code != typename_type)
     {
       error ("%qT referred to as %qs", type, tag_name (tag_code));
-      error ("%q+T has a previous declaration here", type);
+      inform (input_location, "%q+T has a previous declaration here", type);
       return error_mark_node;
     }
   else if (TREE_CODE (type) != ENUMERAL_TYPE
           && tag_code == enum_type)
     {
       error ("%qT referred to as enum", type);
-      error ("%q+T has a previous declaration here", type);
+      inform (input_location, "%q+T has a previous declaration here", type);
       return error_mark_node;
     }
   else if (!allow_template_p
@@ -12533,9 +12662,9 @@ finish_enum_value_list (tree enumtype)
         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);
+      signop sgn = tree_int_cst_sgn (minnode) >= 0 ? UNSIGNED : SIGNED;
+      int lowprec = tree_int_cst_min_precision (minnode, sgn);
+      int highprec = tree_int_cst_min_precision (maxnode, sgn);
       int precision = MAX (lowprec, highprec);
       unsigned int itk;
       bool use_short_enum;
@@ -12567,7 +12696,7 @@ finish_enum_value_list (tree enumtype)
           underlying_type = integer_types[itk];
           if (underlying_type != NULL_TREE
              && TYPE_PRECISION (underlying_type) >= precision
-              && TYPE_UNSIGNED (underlying_type) == unsignedp)
+              && TYPE_SIGN (underlying_type) == sgn)
             break;
         }
       if (itk == itk_none)
@@ -12614,12 +12743,11 @@ finish_enum_value_list (tree enumtype)
        = build_distinct_type_copy (underlying_type);
       TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision;
       set_min_and_max_values_for_integral_type
-        (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
+        (ENUM_UNDERLYING_TYPE (enumtype), precision, sgn);
 
       /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE.  */
       if (flag_strict_enums)
-       set_min_and_max_values_for_integral_type (enumtype, precision,
-                                                 unsignedp);
+       set_min_and_max_values_for_integral_type (enumtype, precision, sgn);
     }
   else
     underlying_type = ENUM_UNDERLYING_TYPE (enumtype);
@@ -12743,14 +12871,14 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
                value = error_mark_node;
              else
                {
-                 double_int di = TREE_INT_CST (prev_value)
-                                 .add_with_sign (double_int_one,
-                                                 false, &overflowed);
+                 tree type = TREE_TYPE (prev_value);
+                 signop sgn = TYPE_SIGN (type);
+                 widest_int wi = wi::add (wi::to_widest (prev_value), 1, sgn,
+                                          &overflowed);
                  if (!overflowed)
                    {
-                     tree type = TREE_TYPE (prev_value);
-                     bool pos = TYPE_UNSIGNED (type) || !di.is_negative ();
-                     if (!double_int_fits_to_tree_p (type, di))
+                     bool pos = !wi::neg_p (wi, sgn);
+                     if (!wi::fits_to_tree_p (wi, type))
                        {
                          unsigned int itk;
                          for (itk = itk_int; itk != itk_none; itk++)
@@ -12758,10 +12886,10 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
                              type = integer_types[itk];
                              if (type != NULL_TREE
                                  && (pos || !TYPE_UNSIGNED (type))
-                                 && double_int_fits_to_tree_p (type, di))
+                                 && wi::fits_to_tree_p (wi, type))
                                break;
                            }
-                         if (type && cxx_dialect < cxx0x
+                         if (type && cxx_dialect < cxx11
                              && itk > itk_unsigned_long)
                            pedwarn (input_location, OPT_Wlong_long, pos ? "\
 incremented enumerator value is too large for %<unsigned long%>" :  "\
@@ -12770,7 +12898,7 @@ incremented enumerator value is too large for %<long%>");
                      if (type == NULL_TREE)
                        overflowed = true;
                      else
-                       value = double_int_to_tree (type, di);
+                       value = wide_int_to_tree (type, wi);
                    }
 
                  if (overflowed)
@@ -12795,8 +12923,8 @@ incremented enumerator value is too large for %<long%>");
           && TREE_CODE (value) == INTEGER_CST)
         {
          if (!int_fits_type_p (value, ENUM_UNDERLYING_TYPE (enumtype)))
-           error ("enumerator value %E is too large for underlying type %<%T%>",
-                  value, ENUM_UNDERLYING_TYPE (enumtype));
+           error ("enumerator value %E is outside the range of underlying "
+                  "type %<%T%>", value, ENUM_UNDERLYING_TYPE (enumtype));
 
           /* Convert the value to the appropriate type.  */
           value = convert (ENUM_UNDERLYING_TYPE (enumtype), value);
@@ -12931,7 +13059,7 @@ check_function_type (tree decl, tree current_function_parms)
    error_mark_node if the function has never been defined, or
    a BLOCK if the function has been defined somewhere.  */
 
-void
+bool
 start_preparsed_function (tree decl1, tree attrs, int flags)
 {
   tree ctype = NULL_TREE;
@@ -12945,7 +13073,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   bool honor_interface;
 
   /* Sanity check.  */
-  gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE);
+  gcc_assert (VOID_TYPE_P (TREE_VALUE (void_list_node)));
   gcc_assert (TREE_CHAIN (void_list_node) == NULL_TREE);
 
   fntype = TREE_TYPE (decl1);
@@ -13010,7 +13138,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   /* Effective C++ rule 15.  */
   if (warn_ecpp
       && DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR
-      && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
+      && VOID_TYPE_P (TREE_TYPE (fntype)))
     warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
@@ -13028,10 +13156,14 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
      by push_nested_class.)  */
   if (processing_template_decl)
     {
-      /* FIXME: Handle error_mark_node more gracefully.  */
       tree newdecl1 = push_template_decl (decl1);
-      if (newdecl1 != error_mark_node)
-       decl1 = newdecl1;
+      if (newdecl1 == error_mark_node)
+       {
+         if (ctype || DECL_STATIC_FUNCTION_P (decl1))
+           pop_nested_class ();
+         return false;
+       }
+      decl1 = newdecl1;
     }
 
   /* We are now in the scope of the function being defined.  */
@@ -13142,7 +13274,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   /* This function may already have been parsed, in which case just
      return; our caller will skip over the body without parsing.  */
   if (DECL_INITIAL (decl1) != error_mark_node)
-    return;
+    return true;
 
   /* Initialize RTL machinery.  We cannot do this until
      CURRENT_FUNCTION_DECL and DECL_RESULT are set up.  We do this
@@ -13181,7 +13313,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       tree t = DECL_ARGUMENTS (decl1);
 
       gcc_assert (t != NULL_TREE && TREE_CODE (t) == PARM_DECL);
-      gcc_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE);
+      gcc_assert (TYPE_PTR_P (TREE_TYPE (t)));
 
       cp_function_chain->x_current_class_ref
        = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
@@ -13304,17 +13436,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   start_fname_decls ();
 
   store_parm_decls (current_function_parms);
+
+  return true;
 }
 
 
 /* Like start_preparsed_function, except that instead of a
    FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR.
 
-   Returns 1 on success.  If the DECLARATOR is not suitable for a function
-   (it defines a datum instead), we return 0, which tells
-   yyparse to report a parse error.  */
+   Returns true on success.  If the DECLARATOR is not suitable
+   for a function, we return false, which tells the parser to
+   skip the entire function.  */
 
-int
+bool
 start_function (cp_decl_specifier_seq *declspecs,
                const cp_declarator *declarator,
                tree attrs)
@@ -13323,13 +13457,13 @@ start_function (cp_decl_specifier_seq *declspecs,
 
   decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
   if (decl1 == error_mark_node)
-    return 0;
+    return false;
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
   if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
     {
       error ("invalid function declaration");
-      return 0;
+      return false;
     }
 
   if (DECL_MAIN_P (decl1))
@@ -13338,9 +13472,7 @@ start_function (cp_decl_specifier_seq *declspecs,
     gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
                             integer_type_node));
 
-  start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
-
-  return 1;
+  return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
 }
 \f
 /* Returns true iff an EH_SPEC_BLOCK should be created in the body of
@@ -13409,7 +13541,7 @@ store_parm_decls (tree current_function_parms)
          if (TREE_CODE (parm) == PARM_DECL)
            {
              if (DECL_NAME (parm) == NULL_TREE
-                 || TREE_CODE (parm) != VOID_TYPE)
+                 || !VOID_TYPE_P (parm))
                pushdecl (parm);
              else
                error ("parameter %qD declared void", parm);
@@ -13512,6 +13644,14 @@ begin_destructor_body (void)
       initialize_vtbl_ptrs (current_class_ptr);
       finish_compound_stmt (compound_stmt);
 
+      /* Insert a cleanup to let the back end know that the object is dead
+        when we exit the destructor, either normally or via exception.  */
+      tree clobber = build_constructor (current_class_type, NULL);
+      TREE_THIS_VOLATILE (clobber) = true;
+      tree exprstmt = build2 (MODIFY_EXPR, current_class_type,
+                             current_class_ref, clobber);
+      finish_decl_cleanup (NULL_TREE, exprstmt);
+
       /* And insert cleanups for our bases and members so that they
         will be properly destroyed if we throw.  */
       push_base_cleanups ();
@@ -13832,7 +13972,7 @@ finish_function (int flags)
 
   /* Complain if there's just no return statement.  */
   if (warn_return_type
-      && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
+      && !VOID_TYPE_P (TREE_TYPE (fntype))
       && !dependent_type_p (TREE_TYPE (fntype))
       && !current_function_returns_value && !current_function_returns_null
       /* Don't complain if we abort or throw.  */
@@ -14030,7 +14170,7 @@ grokmethod (cp_decl_specifier_seq *declspecs,
 void
 maybe_register_incomplete_var (tree var)
 {
-  gcc_assert (TREE_CODE (var) == VAR_DECL);
+  gcc_assert (VAR_P (var));
 
   /* Keep track of variables with incomplete types.  */
   if (!processing_template_decl && TREE_TYPE (var) != error_mark_node
@@ -14146,11 +14286,9 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
     }
   /* Handle ordinary C++ destructors.  */
   type = TREE_TYPE (decl);
-  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+  if (type_build_dtor_call (type))
     {
-      int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
-      bool has_vbases = (TREE_CODE (type) == RECORD_TYPE
-                        && CLASSTYPE_VBASECLASSES (type));
+      int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR;
       tree addr;
       tree call;
 
@@ -14159,14 +14297,12 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
       else
        addr = build_address (decl);
 
-      /* Optimize for space over speed here.  */
-      if (!has_vbases || flag_expensive_optimizations)
-       flags |= LOOKUP_NONVIRTUAL;
-
       call = build_delete (TREE_TYPE (addr), addr,
                           sfk_complete_destructor, flags, 0, complain);
       if (call == error_mark_node)
        cleanup = error_mark_node;
+      else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+       /* Discard the call.  */;
       else if (cleanup)
        cleanup = cp_build_compound_expr (cleanup, call, complain);
       else
@@ -14185,13 +14321,6 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
 }
 
 \f
-/* When a stmt has been parsed, this function is called.  */
-
-void
-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.  */
@@ -14211,8 +14340,9 @@ static_fn_type (tree memfntype)
     return memfntype;
   gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE);
   args = TYPE_ARG_TYPES (memfntype);
+  cp_ref_qualifier rqual = type_memfn_rqual (memfntype);
   fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args));
-  fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype));
+  fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype), rqual);
   fntype = (cp_build_type_attribute_variant
            (fntype, TYPE_ATTRIBUTES (memfntype)));
   fntype = (build_exception_variant
@@ -14228,9 +14358,10 @@ revert_static_member_fn (tree decl)
 {
   tree stype = static_fn_type (decl);
   cp_cv_quals quals = type_memfn_quals (stype);
+  cp_ref_qualifier rqual = type_memfn_rqual (stype);
 
-  if (quals != TYPE_UNQUALIFIED)
-    stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
+  if (quals != TYPE_UNQUALIFIED || rqual != REF_QUAL_NONE)
+    stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED, REF_QUAL_NONE);
 
   TREE_TYPE (decl) = stype;
 
@@ -14289,7 +14420,7 @@ cxx_comdat_group (tree decl)
   /* Virtual tables, construction virtual tables, and virtual table
      tables all go in a single COMDAT group, named after the primary
      virtual table.  */
-  if (TREE_CODE (decl) == VAR_DECL && DECL_VTABLE_OR_VTT_P (decl))
+  if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
     name = DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (DECL_CONTEXT (decl)));
   /* For all other DECLs, the COMDAT group is the mangled name of the
      declaration itself.  */
@@ -14314,4 +14445,43 @@ cxx_comdat_group (tree decl)
   return name;
 }
 
+/* Returns the return type for FN as written by the user, which may include
+   a placeholder for a deduced return type.  */
+
+tree
+fndecl_declared_return_type (tree fn)
+{
+  fn = STRIP_TEMPLATE (fn);
+  if (FNDECL_USED_AUTO (fn))
+    {
+      struct language_function *f = NULL;
+      if (DECL_STRUCT_FUNCTION (fn))
+       f = DECL_STRUCT_FUNCTION (fn)->language;
+      if (f == NULL)
+       f = DECL_SAVED_FUNCTION_DATA (fn);
+      return f->x_auto_return_pattern;
+    }
+  return TREE_TYPE (TREE_TYPE (fn));
+}
+
+/* Returns true iff DECL was declared with an auto return type and it has
+   not yet been deduced to a real type.  */
+
+bool
+undeduced_auto_decl (tree decl)
+{
+  if (cxx_dialect < cxx1y)
+    return false;
+  return type_uses_auto (TREE_TYPE (decl));
+}
+
+/* Complain if DECL has an undeduced return type.  */
+
+void
+require_deduced_type (tree decl)
+{
+  if (undeduced_auto_decl (decl))
+    error ("use of %qD before deduction of %<auto%>", decl);
+}
+
 #include "gt-cp-decl.h"