class.c (fixup_type_variants): Do not copy TYPE_METHODS
[gcc.git] / gcc / cp / class.c
index 605dd16c7115dd28baf72944cd06822120425bdd..41607055493bc74fb08dbbb12d9cbe64d54595ab 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions related to building classes and their related objects.
-   Copyright (C) 1987-2013 Free Software Foundation, Inc.
+   Copyright (C) 1987-2015 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -24,18 +24,39 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "hash-set.h"
+#include "machmode.h"
+#include "vec.h"
+#include "double-int.h"
+#include "input.h"
+#include "alias.h"
+#include "symtab.h"
+#include "options.h"
+#include "wide-int.h"
+#include "inchash.h"
 #include "tm.h"
 #include "tree.h"
+#include "stringpool.h"
+#include "stor-layout.h"
+#include "attribs.h"
+#include "hash-table.h"
 #include "cp-tree.h"
 #include "flags.h"
 #include "toplev.h"
 #include "target.h"
 #include "convert.h"
+#include "hash-map.h"
+#include "is-a.h"
+#include "plugin-api.h"
+#include "hard-reg-set.h"
+#include "input.h"
+#include "function.h"
+#include "ipa-ref.h"
 #include "cgraph.h"
 #include "dumpfile.h"
 #include "splay-tree.h"
-#include "pointer-set.h"
-#include "hash-table.h"
+#include "gimplify.h"
+#include "wide-int.h"
 
 /* The number of nested classes being processed.  If we are not in the
    scope of any class, this is zero.  */
@@ -114,7 +135,7 @@ vec<tree, va_gc> *local_classes;
 static tree get_vfield_name (tree);
 static void finish_struct_anon (tree);
 static tree get_vtable_name (tree);
-static tree get_basefndecls (tree, tree);
+static void get_basefndecls (tree, tree, vec<tree> *);
 static int build_primary_vtable (tree, tree);
 static int build_secondary_vtable (tree);
 static void finish_vtbls (tree);
@@ -145,6 +166,7 @@ static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
 static void build_base_fields (record_layout_info, splay_tree, tree *);
 static void check_methods (tree);
 static void remove_zero_width_bit_fields (tree);
+static bool accessible_nvdtor_p (tree);
 static void check_bases (tree, int *, int *);
 static void check_bases_and_members (tree);
 static tree create_vtable_ptr (tree, tree *);
@@ -203,7 +225,6 @@ static int splay_tree_compare_integer_csts (splay_tree_key k1,
                                            splay_tree_key k2);
 static void warn_about_ambiguous_bases (tree);
 static bool type_requires_array_cookie (tree);
-static bool contains_empty_class_p (tree);
 static bool base_derived_from (tree, tree);
 static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
 static tree end_of_base (tree);
@@ -244,9 +265,10 @@ build_base_path (enum tree_code code,
   tree null_test = NULL;
   tree ptr_target_type;
   int fixed_type_p;
-  int want_pointer = TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE;
+  int want_pointer = TYPE_PTR_P (TREE_TYPE (expr));
   bool has_empty = false;
   bool virtual_access;
+  bool rvalue = false;
 
   if (expr == error_mark_node || binfo == error_mark_node || !binfo)
     return error_mark_node;
@@ -291,15 +313,40 @@ build_base_path (enum tree_code code,
   if (code == MINUS_EXPR && v_binfo)
     {
       if (complain & tf_error)
-       error ("cannot convert from base %qT to derived type %qT via "
-              "virtual base %qT", BINFO_TYPE (binfo), BINFO_TYPE (d_binfo),
-              BINFO_TYPE (v_binfo));
+       {
+         if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (v_binfo)))
+           {
+             if (want_pointer)
+               error ("cannot convert from pointer to base class %qT to "
+                      "pointer to derived class %qT because the base is "
+                      "virtual", BINFO_TYPE (binfo), BINFO_TYPE (d_binfo));
+             else
+               error ("cannot convert from base class %qT to derived "
+                      "class %qT because the base is virtual",
+                      BINFO_TYPE (binfo), BINFO_TYPE (d_binfo));
+           }         
+         else
+           {
+             if (want_pointer)
+               error ("cannot convert from pointer to base class %qT to "
+                      "pointer to derived class %qT via virtual base %qT",
+                      BINFO_TYPE (binfo), BINFO_TYPE (d_binfo),
+                      BINFO_TYPE (v_binfo));
+             else
+               error ("cannot convert from base class %qT to derived "
+                      "class %qT via virtual base %qT", BINFO_TYPE (binfo),
+                      BINFO_TYPE (d_binfo), BINFO_TYPE (v_binfo));
+           }
+       }
       return error_mark_node;
     }
 
   if (!want_pointer)
-    /* This must happen before the call to save_expr.  */
-    expr = cp_build_addr_expr (expr, complain);
+    {
+      rvalue = !real_lvalue_p (expr);
+      /* This must happen before the call to save_expr.  */
+      expr = cp_build_addr_expr (expr, complain);
+    }
   else
     expr = mark_rvalue_use (expr);
 
@@ -318,16 +365,14 @@ build_base_path (enum tree_code code,
 
   /* Don't bother with the calculations inside sizeof; they'll ICE if the
      source type is incomplete and the pointer value doesn't matter.  In a
-     template (even in fold_non_dependent_expr), we don't have vtables set
-     up properly yet, and the value doesn't matter there either; we're just
-     interested in the result of overload resolution.  */
+     template (even in instantiate_non_dependent_expr), we don't have vtables
+     set up properly yet, and the value doesn't matter there either; we're
+     just interested in the result of overload resolution.  */
   if (cp_unevaluated_operand != 0
       || in_template_function ())
     {
       expr = build_nop (ptr_target_type, expr);
-      if (!want_pointer)
-       expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
-      return expr;
+      goto indout;
     }
 
   /* If we're in an NSDMI, we don't have the full constructor context yet
@@ -338,9 +383,7 @@ build_base_path (enum tree_code code,
     {
       expr = build1 (CONVERT_EXPR, ptr_target_type, expr);
       CONVERT_EXPR_VBASE_PATH (expr) = true;
-      if (!want_pointer)
-       expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
-      return expr;
+      goto indout;
     }
 
   /* Do we need to check for a null pointer?  */
@@ -376,6 +419,8 @@ build_base_path (enum tree_code code,
     {
       expr = cp_build_indirect_ref (expr, RO_NULL, complain);
       expr = build_simple_base_path (expr, binfo);
+      if (rvalue)
+       expr = move (expr);
       if (want_pointer)
        expr = build_address (expr);
       target_type = TREE_TYPE (expr);
@@ -402,9 +447,22 @@ build_base_path (enum tree_code code,
          v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
        }
       else
-       v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL,
-                                                            complain),
-                                    TREE_TYPE (TREE_TYPE (expr)));
+       {
+         tree t = expr;
+         if ((flag_sanitize & SANITIZE_VPTR) && fixed_type_p == 0)
+           {
+             t = cp_ubsan_maybe_instrument_cast_to_vbase (input_location,
+                                                          probe, expr);
+             if (t == NULL_TREE)
+               t = expr;
+           }
+         v_offset = build_vfield_ref (cp_build_indirect_ref (t, RO_NULL,
+                                                             complain),
+         TREE_TYPE (TREE_TYPE (expr)));
+       }
+
+      if (v_offset == error_mark_node)
+       return error_mark_node;
 
       v_offset = fold_build_pointer_plus (v_offset, BINFO_VPTR_FIELD (v_binfo));
       v_offset = build1 (NOP_EXPR,
@@ -449,8 +507,13 @@ build_base_path (enum tree_code code,
   else
     null_test = NULL;
 
+ indout:
   if (!want_pointer)
-    expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+    {
+      expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+      if (rvalue)
+       expr = move (expr);
+    }
 
  out:
   if (null_test)
@@ -599,7 +662,9 @@ build_vfield_ref (tree datum, tree type)
 {
   tree vfield, vcontext;
 
-  if (datum == error_mark_node)
+  if (datum == error_mark_node
+      /* Can happen in case of duplicate base types (c++/59082).  */
+      || !TYPE_VFIELD (type))
     return error_mark_node;
 
   /* First, convert to the requested type.  */
@@ -735,11 +800,8 @@ build_vtable (tree class_type, tree name, tree vtable_type)
   TREE_READONLY (decl) = 1;
   DECL_VIRTUAL_P (decl) = 1;
   DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
+  DECL_USER_ALIGN (decl) = true;
   DECL_VTABLE_OR_VTT_P (decl) = 1;
-  /* At one time the vtable info was grabbed 2 words at a time.  This
-     fails on sparc unless you have 8-byte alignment.  (tiemann) */
-  DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
-                          DECL_ALIGN (decl));
   set_linkage_according_to_type (class_type, decl);
   /* The vtable has not been defined -- yet.  */
   DECL_EXTERNAL (decl) = 1;
@@ -1045,6 +1107,12 @@ add_method (tree type, tree method, tree using_decl)
         overloaded if any of them is a static member
         function declaration.
 
+        [over.load] Member function declarations with the same name and
+        the same parameter-type-list as well as member function template
+        declarations with the same name, the same parameter-type-list, and
+        the same template parameter lists cannot be overloaded if any of
+        them, but not all, have a ref-qualifier.
+
         [namespace.udecl] When a using-declaration brings names
         from a base class into a derived class scope, member
         functions in the derived class override and/or hide member
@@ -1060,11 +1128,13 @@ add_method (tree type, tree method, tree using_decl)
         coming from the using class in overload resolution.  */
       if (! DECL_STATIC_FUNCTION_P (fn)
          && ! DECL_STATIC_FUNCTION_P (method)
-         && TREE_TYPE (TREE_VALUE (parms1)) != error_mark_node
-         && TREE_TYPE (TREE_VALUE (parms2)) != error_mark_node
-         && (cp_type_quals (TREE_TYPE (TREE_VALUE (parms1)))
-             != cp_type_quals (TREE_TYPE (TREE_VALUE (parms2)))))
-       continue;
+         /* Either both or neither need to be ref-qualified for
+            differing quals to allow overloading.  */
+         && (FUNCTION_REF_QUALIFIED (fn_type)
+             == FUNCTION_REF_QUALIFIED (method_type))
+         && (type_memfn_quals (fn_type) != type_memfn_quals (method_type)
+             || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type)))
+         continue;
 
       /* For templates, the return type and template parameters
         must be identical.  */
@@ -1109,7 +1179,7 @@ add_method (tree type, tree method, tree using_decl)
                  if (DECL_ASSEMBLER_NAME_SET_P (method))
                    mangle_decl (method);
                }
-             record_function_versions (fn, method);
+             cgraph_node::record_function_versions (fn, method);
              continue;
            }
          if (DECL_INHERITED_CTOR_BASE (method))
@@ -1260,7 +1330,7 @@ handle_using_decl (tree using_decl, tree t)
        old_value = NULL_TREE;
     }
 
-  cp_emit_debug_info_for_using (decl, USING_DECL_SCOPE (using_decl));
+  cp_emit_debug_info_for_using (decl, t);
 
   if (is_overloaded_fn (decl))
     flist = decl;
@@ -1298,87 +1368,310 @@ handle_using_decl (tree using_decl, tree t)
     alter_access (t, decl, access);
 }
 \f
-/* walk_tree callback for check_abi_tags: if the type at *TP involves any
-   types with abi tags, add the corresponding identifiers to the VEC in
-   *DATA and set IDENTIFIER_MARKED.  */
+/* Data structure for find_abi_tags_r, below.  */
 
 struct abi_tag_data
 {
-  tree t;
-  tree subob;
+  tree t;              // The type that we're checking for missing tags.
+  tree subob;          // The subobject of T that we're getting tags from.
+  tree tags; // error_mark_node for diagnostics, or a list of missing tags.
 };
 
-static tree
-find_abi_tags_r (tree *tp, int */*walk_subtrees*/, void *data)
-{
-  if (!TAGGED_TYPE_P (*tp))
-    return NULL_TREE;
+/* Subroutine of find_abi_tags_r. Handle a single TAG found on the class TP
+   in the context of P.  TAG can be either an identifier (the DECL_NAME of
+   a tag NAMESPACE_DECL) or a STRING_CST (a tag attribute).  */
 
-  if (tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (*tp)))
+static void
+check_tag (tree tag, tree id, tree *tp, abi_tag_data *p)
+{
+  if (!IDENTIFIER_MARKED (id))
     {
-      struct abi_tag_data *p = static_cast<struct abi_tag_data*>(data);
-      for (tree list = TREE_VALUE (attributes); list;
-          list = TREE_CHAIN (list))
+      if (p->tags != error_mark_node)
        {
-         tree tag = TREE_VALUE (list);
-         tree id = get_identifier (TREE_STRING_POINTER (tag));
-         if (!IDENTIFIER_MARKED (id))
+         /* We're collecting tags from template arguments or from
+            the type of a variable or function return type.  */
+         p->tags = tree_cons (NULL_TREE, tag, p->tags);
+
+         /* Don't inherit this tag multiple times.  */
+         IDENTIFIER_MARKED (id) = true;
+
+         if (TYPE_P (p->t))
            {
-             if (TYPE_P (p->subob))
-               {
-                 warning (OPT_Wabi_tag, "%qT does not have the %E abi tag "
-                          "that base %qT has", p->t, tag, p->subob);
-                 inform (location_of (p->subob), "%qT declared here",
-                         p->subob);
-               }
-             else
-               {
-                 warning (OPT_Wabi_tag, "%qT does not have the %E abi tag "
-                          "that %qT (used in the type of %qD) has",
-                          p->t, tag, *tp, p->subob);
-                 inform (location_of (p->subob), "%qD declared here",
-                         p->subob);
-                 inform (location_of (*tp), "%qT declared here", *tp);
-               }
+             /* Tags inherited from type template arguments are only used
+                to avoid warnings.  */
+             ABI_TAG_IMPLICIT (p->tags) = true;
+             return;
+           }
+         /* For functions and variables we want to warn, too.  */
+       }
+
+      /* Otherwise we're diagnosing missing tags.  */
+      if (TREE_CODE (p->t) == FUNCTION_DECL)
+       {
+         if (warning (OPT_Wabi_tag, "%qD inherits the %E ABI tag "
+                      "that %qT (used in its return type) has",
+                      p->t, tag, *tp))
+           inform (location_of (*tp), "%qT declared here", *tp);
+       }
+      else if (TREE_CODE (p->t) == VAR_DECL)
+       {
+         if (warning (OPT_Wabi_tag, "%qD inherits the %E ABI tag "
+                      "that %qT (used in its type) has", p->t, tag, *tp))
+           inform (location_of (*tp), "%qT declared here", *tp);
+       }
+      else if (TYPE_P (p->subob))
+       {
+         if (warning (OPT_Wabi_tag, "%qT does not have the %E ABI tag "
+                      "that base %qT has", p->t, tag, p->subob))
+           inform (location_of (p->subob), "%qT declared here",
+                   p->subob);
+       }
+      else
+       {
+         if (warning (OPT_Wabi_tag, "%qT does not have the %E ABI tag "
+                      "that %qT (used in the type of %qD) has",
+                      p->t, tag, *tp, p->subob))
+           {
+             inform (location_of (p->subob), "%qD declared here",
+                     p->subob);
+             inform (location_of (*tp), "%qT declared here", *tp);
            }
        }
     }
+}
+
+/* Find all the ABI tags in the attribute list ATTR and either call
+   check_tag (if TP is non-null) or set IDENTIFIER_MARKED to val.  */
+
+static void
+mark_or_check_attr_tags (tree attr, tree *tp, abi_tag_data *p, bool val)
+{
+  if (!attr)
+    return;
+  for (; (attr = lookup_attribute ("abi_tag", attr));
+       attr = TREE_CHAIN (attr))
+    for (tree list = TREE_VALUE (attr); list;
+        list = TREE_CHAIN (list))
+      {
+       tree tag = TREE_VALUE (list);
+       tree id = get_identifier (TREE_STRING_POINTER (tag));
+       if (tp)
+         check_tag (tag, id, tp, p);
+       else
+         IDENTIFIER_MARKED (id) = val;
+      }
+}
+
+/* Find all the ABI tags on T and its enclosing scopes and either call
+   check_tag (if TP is non-null) or set IDENTIFIER_MARKED to val.  */
+
+static void
+mark_or_check_tags (tree t, tree *tp, abi_tag_data *p, bool val)
+{
+  while (t != global_namespace)
+    {
+      tree attr;
+      if (TYPE_P (t))
+       {
+         attr = TYPE_ATTRIBUTES (t);
+         t = CP_TYPE_CONTEXT (t);
+       }
+      else
+       {
+         attr = DECL_ATTRIBUTES (t);
+         t = CP_DECL_CONTEXT (t);
+       }
+      mark_or_check_attr_tags (attr, tp, p, val);
+    }
+}
+
+/* walk_tree callback for check_abi_tags: if the type at *TP involves any
+   types with ABI tags, add the corresponding identifiers to the VEC in
+   *DATA and set IDENTIFIER_MARKED.  */
+
+static tree
+find_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
+{
+  if (!OVERLOAD_TYPE_P (*tp))
+    return NULL_TREE;
+
+  /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
+     anyway, but let's make sure of it.  */
+  *walk_subtrees = false;
+
+  abi_tag_data *p = static_cast<struct abi_tag_data*>(data);
+
+  mark_or_check_tags (*tp, tp, p, false);
+
+  return NULL_TREE;
+}
+
+/* walk_tree callback for mark_abi_tags: if *TP is a class, set
+   IDENTIFIER_MARKED on its ABI tags.  */
+
+static tree
+mark_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
+{
+  if (!OVERLOAD_TYPE_P (*tp))
+    return NULL_TREE;
+
+  /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
+     anyway, but let's make sure of it.  */
+  *walk_subtrees = false;
+
+  bool *valp = static_cast<bool*>(data);
+
+  mark_or_check_tags (*tp, NULL, NULL, *valp);
+
   return NULL_TREE;
 }
 
-/* Check that class T has all the abi tags that subobject SUBOB has, or
-   warn if not.  */
+/* Set IDENTIFIER_MARKED on all the ABI tags on T and its enclosing
+   scopes.  */
 
 static void
-check_abi_tags (tree t, tree subob)
+mark_abi_tags (tree t, bool val)
 {
-  tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
-  if (attributes)
+  mark_or_check_tags (t, NULL, NULL, val);
+  if (DECL_P (t))
     {
-      for (tree list = TREE_VALUE (attributes); list;
-          list = TREE_CHAIN (list))
+      if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t)
+         && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
        {
-         tree tag = TREE_VALUE (list);
-         tree id = get_identifier (TREE_STRING_POINTER (tag));
-         IDENTIFIER_MARKED (id) = true;
+         /* Template arguments are part of the signature.  */
+         tree level = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t));
+         for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
+           {
+             tree arg = TREE_VEC_ELT (level, j);
+             cp_walk_tree_without_duplicates (&arg, mark_abi_tags_r, &val);
+           }
        }
+      if (TREE_CODE (t) == FUNCTION_DECL)
+       /* A function's parameter types are part of the signature, so
+          we don't need to inherit any tags that are also in them.  */
+       for (tree arg = FUNCTION_FIRST_USER_PARMTYPE (t); arg;
+            arg = TREE_CHAIN (arg))
+         cp_walk_tree_without_duplicates (&TREE_VALUE (arg),
+                                          mark_abi_tags_r, &val);
     }
+}
+
+/* Check that T has all the ABI tags that subobject SUBOB has, or
+   warn if not.  If T is a (variable or function) declaration, also
+   add any missing tags.  */
+
+static void
+check_abi_tags (tree t, tree subob)
+{
+  bool inherit = DECL_P (t);
+
+  if (!inherit && !warn_abi_tag)
+    return;
+
+  tree decl = TYPE_P (t) ? TYPE_NAME (t) : t;
+  if (!TREE_PUBLIC (decl))
+    /* No need to worry about things local to this TU.  */
+    return;
+
+  mark_abi_tags (t, true);
 
   tree subtype = TYPE_P (subob) ? subob : TREE_TYPE (subob);
-  struct abi_tag_data data = { t, subob };
+  struct abi_tag_data data = { t, subob, error_mark_node };
+  if (inherit)
+    data.tags = NULL_TREE;
 
   cp_walk_tree_without_duplicates (&subtype, find_abi_tags_r, &data);
 
-  if (attributes)
+  if (inherit && data.tags)
     {
-      for (tree list = TREE_VALUE (attributes); list;
-          list = TREE_CHAIN (list))
+      tree attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
+      if (attr)
+       TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
+      else
+       DECL_ATTRIBUTES (t)
+         = tree_cons (get_identifier ("abi_tag"), data.tags,
+                      DECL_ATTRIBUTES (t));
+    }
+
+  mark_abi_tags (t, false);
+}
+
+/* Check that DECL has all the ABI tags that are used in parts of its type
+   that are not reflected in its mangled name.  */
+
+void
+check_abi_tags (tree decl)
+{
+  if (TREE_CODE (decl) == VAR_DECL)
+    check_abi_tags (decl, TREE_TYPE (decl));
+  else if (TREE_CODE (decl) == FUNCTION_DECL
+          && !mangle_return_type_p (decl))
+    check_abi_tags (decl, TREE_TYPE (TREE_TYPE (decl)));
+}
+
+void
+inherit_targ_abi_tags (tree t)
+{
+  if (!CLASS_TYPE_P (t)
+      || CLASSTYPE_TEMPLATE_INFO (t) == NULL_TREE)
+    return;
+
+  mark_abi_tags (t, true);
+
+  tree args = CLASSTYPE_TI_ARGS (t);
+  struct abi_tag_data data = { t, NULL_TREE, NULL_TREE };
+  for (int i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+    {
+      tree level = TMPL_ARGS_LEVEL (args, i+1);
+      for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
        {
-         tree tag = TREE_VALUE (list);
-         tree id = get_identifier (TREE_STRING_POINTER (tag));
-         IDENTIFIER_MARKED (id) = false;
+         tree arg = TREE_VEC_ELT (level, j);
+         data.subob = arg;
+         cp_walk_tree_without_duplicates (&arg, find_abi_tags_r, &data);
        }
     }
+
+  // If we found some tags on our template arguments, add them to our
+  // abi_tag attribute.
+  if (data.tags)
+    {
+      tree attr = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
+      if (attr)
+       TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
+      else
+       TYPE_ATTRIBUTES (t)
+         = tree_cons (get_identifier ("abi_tag"), data.tags,
+                      TYPE_ATTRIBUTES (t));
+    }
+
+  mark_abi_tags (t, false);
+}
+
+/* Return true, iff class T has a non-virtual destructor that is
+   accessible from outside the class heirarchy (i.e. is public, or
+   there's a suitable friend.  */
+
+static bool
+accessible_nvdtor_p (tree t)
+{
+  tree dtor = CLASSTYPE_DESTRUCTORS (t);
+
+  /* An implicitly declared destructor is always public.  And,
+     if it were virtual, we would have created it by now.  */
+  if (!dtor)
+    return true;
+
+  if (DECL_VINDEX (dtor))
+    return false; /* Virtual */
+  
+  if (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor))
+    return true;  /* Public */
+
+  if (CLASSTYPE_FRIEND_CLASSES (t)
+      || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
+    return true;   /* Has friends */
+
+  return false;
 }
 
 /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
@@ -1417,13 +1710,6 @@ check_bases (tree t,
       if (!CLASSTYPE_LITERAL_P (basetype))
         CLASSTYPE_LITERAL_P (t) = false;
 
-      /* Effective C++ rule 14.  We only need to check TYPE_POLYMORPHIC_P
-        here because the case of virtual functions but non-virtual
-        dtor is handled in finish_struct_1.  */
-      if (!TYPE_POLYMORPHIC_P (basetype))
-       warning (OPT_Weffc__,
-                "base class %q#T has a non-virtual destructor", basetype);
-
       /* If the base class doesn't have copy constructors or
         assignment operators that take const references, then the
         derived class cannot have such a member automatically
@@ -1471,6 +1757,12 @@ check_bases (tree t,
        |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
       TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
                                    || TYPE_HAS_COMPLEX_DFLT (basetype));
+      SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT
+       (t, CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
+        | CLASSTYPE_READONLY_FIELDS_NEED_INIT (basetype));
+      SET_CLASSTYPE_REF_FIELDS_NEED_INIT
+       (t, CLASSTYPE_REF_FIELDS_NEED_INIT (t)
+        | CLASSTYPE_REF_FIELDS_NEED_INIT (basetype));
 
       /*  A standard-layout class is a class that:
          ...
@@ -1680,7 +1972,6 @@ fixup_type_variants (tree t)
 
       /* Copy whatever these are holding today.  */
       TYPE_VFIELD (variants) = TYPE_VFIELD (t);
-      TYPE_METHODS (variants) = TYPE_METHODS (t);
       TYPE_FIELDS (variants) = TYPE_FIELDS (t);
     }
 }
@@ -1697,14 +1988,23 @@ fixup_attribute_variants (tree t)
   if (!t)
     return;
 
+  tree attrs = TYPE_ATTRIBUTES (t);
+  unsigned align = TYPE_ALIGN (t);
+  bool user_align = TYPE_USER_ALIGN (t);
+
   for (variants = TYPE_NEXT_VARIANT (t);
        variants;
        variants = TYPE_NEXT_VARIANT (variants))
     {
       /* These are the two fields that check_qualified_type looks at and
         are affected by attributes.  */
-      TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
-      TYPE_ALIGN (variants) = TYPE_ALIGN (t);
+      TYPE_ATTRIBUTES (variants) = attrs;
+      unsigned valign = align;
+      if (TYPE_USER_ALIGN (variants))
+       valign = MAX (valign, TYPE_ALIGN (variants));
+      else
+       TYPE_USER_ALIGN (variants) = user_align;
+      TYPE_ALIGN (variants) = valign;
     }
 }
 \f
@@ -2058,12 +2358,12 @@ same_signature_p (const_tree fndecl, const_tree base_fndecl)
          && same_type_p (DECL_CONV_FN_TYPE (fndecl),
                          DECL_CONV_FN_TYPE (base_fndecl))))
     {
-      tree types, base_types;
-      types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
-      base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
-      if ((cp_type_quals (TREE_TYPE (TREE_VALUE (base_types)))
-          == cp_type_quals (TREE_TYPE (TREE_VALUE (types))))
-         && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types)))
+      tree fntype = TREE_TYPE (fndecl);
+      tree base_fntype = TREE_TYPE (base_fndecl);
+      if (type_memfn_quals (fntype) == type_memfn_quals (base_fntype)
+         && type_memfn_rqual (fntype) == type_memfn_rqual (base_fntype)
+         && compparms (FUNCTION_FIRST_USER_PARMTYPE (fndecl),
+                       FUNCTION_FIRST_USER_PARMTYPE (base_fndecl)))
        return 1;
     }
   return 0;
@@ -2541,6 +2841,10 @@ modify_all_vtables (tree t, tree virtuals)
   tree binfo = TYPE_BINFO (t);
   tree *fnsp;
 
+  /* Mangle the vtable name before entering dfs_walk (c++/51884).  */
+  if (TYPE_CONTAINS_VPTR_P (t))
+    get_vtable_decl (t, false);
+
   /* Update all of the vtables.  */
   dfs_walk_once (binfo, dfs_modify_vtables, NULL, t);
 
@@ -2574,16 +2878,16 @@ modify_all_vtables (tree t, tree virtuals)
 /* Get the base virtual function declarations in T that have the
    indicated NAME.  */
 
-static tree
-get_basefndecls (tree name, tree t)
+static void
+get_basefndecls (tree name, tree t, vec<tree> *base_fndecls)
 {
   tree methods;
-  tree base_fndecls = NULL_TREE;
   int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
   int i;
 
   /* Find virtual functions in T with the indicated NAME.  */
   i = lookup_fnfields_1 (t, name);
+  bool found_decls = false;
   if (i != -1)
     for (methods = (*CLASSTYPE_METHOD_VEC (t))[i];
         methods;
@@ -2593,20 +2897,20 @@ get_basefndecls (tree name, tree t)
 
        if (TREE_CODE (method) == FUNCTION_DECL
            && DECL_VINDEX (method))
-         base_fndecls = tree_cons (NULL_TREE, method, base_fndecls);
+         {
+           base_fndecls->safe_push (method);
+           found_decls = true;
+         }
       }
 
-  if (base_fndecls)
-    return base_fndecls;
+  if (found_decls)
+    return;
 
   for (i = 0; i < n_baseclasses; i++)
     {
       tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), i));
-      base_fndecls = chainon (get_basefndecls (name, basetype),
-                             base_fndecls);
+      get_basefndecls (name, basetype, base_fndecls);
     }
-
-  return base_fndecls;
 }
 
 /* If this declaration supersedes the declaration of
@@ -2634,6 +2938,10 @@ check_for_override (tree decl, tree ctype)
     {
       DECL_VINDEX (decl) = decl;
       overrides_found = true;
+      if (warn_override && !DECL_OVERRIDE_P (decl)
+         && !DECL_DESTRUCTOR_P (decl))
+       warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wsuggest_override,
+                   "%q+D can be marked override", decl);
     }
 
   if (DECL_VIRTUAL_P (decl))
@@ -2645,9 +2953,9 @@ check_for_override (tree decl, tree ctype)
        TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
     }
   else if (DECL_FINAL_P (decl))
-    error ("%q+#D marked final, but is not virtual", decl);
+    error ("%q+#D marked %<final%>, but is not virtual", decl);
   if (DECL_OVERRIDE_P (decl) && !overrides_found)
-    error ("%q+#D marked override, but does not override", decl);
+    error ("%q+#D marked %<override%>, but does not override", decl);
 }
 
 /* Warn about hidden virtual functions that are not overridden in t.
@@ -2668,7 +2976,6 @@ warn_hidden (tree t)
       tree fn;
       tree name;
       tree fndecl;
-      tree base_fndecls;
       tree base_binfo;
       tree binfo;
       int j;
@@ -2677,49 +2984,130 @@ warn_hidden (tree t)
         have the same name.  Figure out what name that is.  */
       name = DECL_NAME (OVL_CURRENT (fns));
       /* There are no possibly hidden functions yet.  */
-      base_fndecls = NULL_TREE;
+      auto_vec<tree, 20> base_fndecls;
       /* Iterate through all of the base classes looking for possibly
         hidden functions.  */
       for (binfo = TYPE_BINFO (t), j = 0;
           BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
        {
          tree basetype = BINFO_TYPE (base_binfo);
-         base_fndecls = chainon (get_basefndecls (name, basetype),
-                                 base_fndecls);
+         get_basefndecls (name, basetype, &base_fndecls);
        }
 
       /* If there are no functions to hide, continue.  */
-      if (!base_fndecls)
+      if (base_fndecls.is_empty ())
        continue;
 
       /* Remove any overridden functions.  */
       for (fn = fns; fn; fn = OVL_NEXT (fn))
        {
          fndecl = OVL_CURRENT (fn);
-         if (DECL_VINDEX (fndecl))
+         if (TREE_CODE (fndecl) == FUNCTION_DECL
+             && DECL_VINDEX (fndecl))
            {
-             tree *prev = &base_fndecls;
-
-             while (*prev)
                /* If the method from the base class has the same
                   signature as the method from the derived class, it
                   has been overridden.  */
-               if (same_signature_p (fndecl, TREE_VALUE (*prev)))
-                 *prev = TREE_CHAIN (*prev);
-               else
-                 prev = &TREE_CHAIN (*prev);
+               for (size_t k = 0; k < base_fndecls.length (); k++)
+               if (base_fndecls[k]
+                   && same_signature_p (fndecl, base_fndecls[k]))
+                 base_fndecls[k] = NULL_TREE;
            }
        }
 
       /* Now give a warning for all base functions without overriders,
         as they are hidden.  */
-      while (base_fndecls)
+      size_t k;
+      tree base_fndecl;
+      FOR_EACH_VEC_ELT (base_fndecls, k, base_fndecl)
+       if (base_fndecl)
+         {
+             /* Here we know it is a hider, and no overrider exists.  */
+             warning (OPT_Woverloaded_virtual, "%q+D was hidden", base_fndecl);
+             warning (OPT_Woverloaded_virtual, "  by %q+D", fns);
+         }
+    }
+}
+
+/* Recursive helper for finish_struct_anon.  */
+
+static void
+finish_struct_anon_r (tree field, bool complain)
+{
+  bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
+  tree elt = TYPE_FIELDS (TREE_TYPE (field));
+  for (; elt; elt = DECL_CHAIN (elt))
+    {
+      /* We're generally only interested in entities the user
+        declared, but we also find nested classes by noticing
+        the TYPE_DECL that we create implicitly.  You're
+        allowed to put one anonymous union inside another,
+        though, so we explicitly tolerate that.  We use
+        TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that
+        we also allow unnamed types used for defining fields.  */
+      if (DECL_ARTIFICIAL (elt)
+         && (!DECL_IMPLICIT_TYPEDEF_P (elt)
+             || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
+       continue;
+
+      if (TREE_CODE (elt) != FIELD_DECL)
+       {
+         /* We already complained about static data members in
+            finish_static_data_member_decl.  */
+         if (complain && TREE_CODE (elt) != VAR_DECL)
+           {
+             if (is_union)
+               permerror (input_location,
+                          "%q+#D invalid; an anonymous union can "
+                          "only have non-static data members", elt);
+             else
+               permerror (input_location,
+                          "%q+#D invalid; an anonymous struct can "
+                          "only have non-static data members", elt);
+           }
+         continue;
+       }
+
+      if (complain)
        {
-         /* Here we know it is a hider, and no overrider exists.  */
-         warning (OPT_Woverloaded_virtual, "%q+D was hidden", TREE_VALUE (base_fndecls));
-         warning (OPT_Woverloaded_virtual, "  by %q+D", fns);
-         base_fndecls = TREE_CHAIN (base_fndecls);
+         if (TREE_PRIVATE (elt))
+           {
+             if (is_union)
+               permerror (input_location,
+                          "private member %q+#D in anonymous union", elt);
+             else
+               permerror (input_location,
+                          "private member %q+#D in anonymous struct", elt);
+           }
+         else if (TREE_PROTECTED (elt))
+           {
+             if (is_union)
+               permerror (input_location,
+                          "protected member %q+#D in anonymous union", elt);
+             else
+               permerror (input_location,
+                          "protected member %q+#D in anonymous struct", elt);
+           }
        }
+
+      TREE_PRIVATE (elt) = TREE_PRIVATE (field);
+      TREE_PROTECTED (elt) = TREE_PROTECTED (field);
+
+      /* Recurse into the anonymous aggregates to handle correctly
+        access control (c++/24926):
+
+        class A {
+          union {
+            union {
+              int i;
+            };
+          };
+        };
+
+        int j=A().i;  */
+      if (DECL_NAME (elt) == NULL_TREE
+         && ANON_AGGR_TYPE_P (TREE_TYPE (elt)))
+       finish_struct_anon_r (elt, /*complain=*/false);
     }
 }
 
@@ -2729,9 +3117,7 @@ warn_hidden (tree t)
 static void
 finish_struct_anon (tree t)
 {
-  tree field;
-
-  for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+  for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
     {
       if (TREE_STATIC (field))
        continue;
@@ -2740,53 +3126,7 @@ finish_struct_anon (tree t)
 
       if (DECL_NAME (field) == NULL_TREE
          && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
-       {
-         bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
-         tree elt = TYPE_FIELDS (TREE_TYPE (field));
-         for (; elt; elt = DECL_CHAIN (elt))
-           {
-             /* We're generally only interested in entities the user
-                declared, but we also find nested classes by noticing
-                the TYPE_DECL that we create implicitly.  You're
-                allowed to put one anonymous union inside another,
-                though, so we explicitly tolerate that.  We use
-                TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that
-                we also allow unnamed types used for defining fields.  */
-             if (DECL_ARTIFICIAL (elt)
-                 && (!DECL_IMPLICIT_TYPEDEF_P (elt)
-                     || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
-               continue;
-
-             if (TREE_CODE (elt) != FIELD_DECL)
-               {
-                 if (is_union)
-                   permerror (input_location, "%q+#D invalid; an anonymous union can "
-                              "only have non-static data members", elt);
-                 else
-                   permerror (input_location, "%q+#D invalid; an anonymous struct can "
-                              "only have non-static data members", elt);
-                 continue;
-               }
-
-             if (TREE_PRIVATE (elt))
-               {
-                 if (is_union)
-                   permerror (input_location, "private member %q+#D in anonymous union", elt);
-                 else
-                   permerror (input_location, "private member %q+#D in anonymous struct", elt);
-               }
-             else if (TREE_PROTECTED (elt))
-               {
-                 if (is_union)
-                   permerror (input_location, "protected member %q+#D in anonymous union", elt);
-                 else
-                   permerror (input_location, "protected member %q+#D in anonymous struct", elt);
-               }
-
-             TREE_PRIVATE (elt) = TREE_PRIVATE (field);
-             TREE_PROTECTED (elt) = TREE_PROTECTED (field);
-           }
-       }
+       finish_struct_anon_r (field, /*complain=*/true);
     }
 }
 
@@ -2897,6 +3237,7 @@ one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
     parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
   tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
                                   t, false, ctor, parmlist);
+  gcc_assert (TYPE_MAIN_VARIANT (t) == t);
   if (add_method (t, fn, NULL_TREE))
     {
       DECL_CHAIN (fn) = TYPE_METHODS (t);
@@ -2923,9 +3264,9 @@ one_inherited_ctor (tree ctor, tree t)
   one_inheriting_sig (t, ctor, new_parms, i);
   if (parms == NULL_TREE)
     {
-      warning (OPT_Winherited_variadic_ctor,
-              "the ellipsis in %qD is not inherited", ctor);
-      inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor);
+      if (warning (OPT_Winherited_variadic_ctor,
+                  "the ellipsis in %qD is not inherited", ctor))
+       inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor);
     }
 }
 
@@ -2943,7 +3284,7 @@ add_implicitly_declared_members (tree t, tree* access_decls,
 {
   bool move_ok = false;
 
-  if (cxx_dialect >= cxx0x && !CLASSTYPE_DESTRUCTORS (t)
+  if (cxx_dialect >= cxx11 && !CLASSTYPE_DESTRUCTORS (t)
       && !TYPE_HAS_COPY_CTOR (t) && !TYPE_HAS_COPY_ASSIGN (t)
       && !type_has_move_constructor (t) && !type_has_move_assign (t))
     move_ok = true;
@@ -2970,7 +3311,7 @@ add_implicitly_declared_members (tree t, tree* access_decls,
     {
       TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
       CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
-      if (cxx_dialect >= cxx0x)
+      if (cxx_dialect >= cxx11)
        TYPE_HAS_CONSTEXPR_CTOR (t)
          /* This might force the declaration.  */
          = type_has_constexpr_default_constructor (t);
@@ -2998,7 +3339,7 @@ add_implicitly_declared_members (tree t, tree* access_decls,
       TYPE_HAS_COPY_ASSIGN (t) = 1;
       TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment;
       CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1;
-      if (move_ok)
+      if (move_ok && !LAMBDA_TYPE_P (t))
        CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1;
     }
 
@@ -3010,11 +3351,10 @@ add_implicitly_declared_members (tree t, tree* access_decls,
     {
       tree using_decl = TREE_VALUE (*access_decls);
       tree decl = USING_DECL_DECLS (using_decl);
-      if (DECL_SELF_REFERENCE_P (decl))
+      if (DECL_NAME (using_decl) == ctor_identifier)
        {
          /* declare, then remove the decl */
-         tree ctor_list = lookup_fnfields_slot (TREE_TYPE (decl),
-                                                ctor_identifier);
+         tree ctor_list = decl;
          location_t loc = input_location;
          input_location = DECL_SOURCE_LOCATION (using_decl);
          if (ctor_list)
@@ -3129,9 +3469,12 @@ check_bitfield_decl (tree field)
          error ("zero width for bit-field %q+D", field);
          w = error_mark_node;
        }
-      else if (compare_tree_int (w, TYPE_PRECISION (type)) > 0
-              && TREE_CODE (type) != ENUMERAL_TYPE
-              && TREE_CODE (type) != BOOLEAN_TYPE)
+      else if ((TREE_CODE (type) != ENUMERAL_TYPE
+               && TREE_CODE (type) != BOOLEAN_TYPE
+               && compare_tree_int (w, TYPE_PRECISION (type)) > 0)
+              || ((TREE_CODE (type) == ENUMERAL_TYPE
+                   || TREE_CODE (type) == BOOLEAN_TYPE)
+                  && tree_int_cst_lt (TYPE_SIZE (type), w)))
        warning (0, "width of %q+D exceeds its type", field);
       else if (TREE_CODE (type) == ENUMERAL_TYPE
               && (0 > (compare_tree_int
@@ -3169,7 +3512,7 @@ check_field_decl (tree field,
 
   /* In C++98 an anonymous union cannot contain any fields which would change
      the settings of CANT_HAVE_CONST_CTOR and friends.  */
-  if (ANON_UNION_TYPE_P (type) && cxx_dialect < cxx0x)
+  if (ANON_UNION_TYPE_P (type) && cxx_dialect < cxx11)
     ;
   /* And, we don't set TYPE_HAS_CONST_COPY_CTOR, etc., for anonymous
      structs.  So, we recurse through their fields here.  */
@@ -3190,7 +3533,7 @@ check_field_decl (tree field,
         make it through without complaint.  */
       abstract_virtuals_error (field, type);
 
-      if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx0x)
+      if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx11)
        {
          static bool warned;
          int oldcount = errorcount;
@@ -3318,22 +3661,25 @@ check_field_decls (tree t, tree *access_decls,
       /* When this goes into scope, it will be a non-local reference.  */
       DECL_NONLOCAL (x) = 1;
 
-      if (TREE_CODE (t) == UNION_TYPE)
+      if (TREE_CODE (t) == UNION_TYPE
+         && cxx_dialect < cxx11)
        {
-         /* [class.union]
+         /* [class.union] (C++98)
 
             If a union contains a static data member, or a member of
-            reference type, the program is ill-formed.  */
-         if (TREE_CODE (x) == VAR_DECL)
+            reference type, the program is ill-formed.
+
+            In C++11 this limitation doesn't exist anymore.  */
+         if (VAR_P (x))
            {
-             error ("%q+D may not be static because it is a member of a union", x);
+             error ("in C++98 %q+D may not be static because it is "
+                    "a member of a union", x);
              continue;
            }
          if (TREE_CODE (type) == REFERENCE_TYPE)
            {
-             error ("%q+D may not have reference type %qT because"
-                    " it is a member of a union",
-                    x, type);
+             error ("in C++98 %q+D may not have reference type %qT "
+                    "because it is a member of a union", x, type);
              continue;
            }
        }
@@ -3356,7 +3702,7 @@ check_field_decls (tree t, tree *access_decls,
       if (type == error_mark_node)
        continue;
 
-      if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
+      if (TREE_CODE (x) == CONST_DECL || VAR_P (x))
        continue;
 
       /* Now it can only be a FIELD_DECL.  */
@@ -3365,9 +3711,11 @@ check_field_decls (tree t, tree *access_decls,
        CLASSTYPE_NON_AGGREGATE (t) = 1;
 
       /* If at least one non-static data member is non-literal, the whole
-         class becomes non-literal.  Note: if the type is incomplete we
-        will complain later on.  */
-      if (COMPLETE_TYPE_P (type) && !literal_type_p (type))
+         class becomes non-literal.  Per Core/1453, volatile non-static
+        data members and base classes are also not allowed.
+        Note: if the type is incomplete we will complain later on.  */
+      if (COMPLETE_TYPE_P (type)
+         && (!literal_type_p (type) || CP_TYPE_VOLATILE_P (type))) 
         CLASSTYPE_LITERAL_P (t) = false;
 
       /* A standard-layout class is a class that:
@@ -3387,13 +3735,15 @@ check_field_decls (tree t, tree *access_decls,
          CLASSTYPE_NON_STD_LAYOUT (t) = 1;
          if (DECL_INITIAL (x) == NULL_TREE)
            SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
-
-         /* ARM $12.6.2: [A member initializer list] (or, for an
-            aggregate, initialization by a brace-enclosed list) is the
-            only way to initialize nonstatic const and reference
-            members.  */
-         TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
-         TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
+         if (cxx_dialect < cxx11)
+           {
+             /* ARM $12.6.2: [A member initializer list] (or, for an
+                aggregate, initialization by a brace-enclosed list) is the
+                only way to initialize nonstatic const and reference
+                members.  */
+             TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+             TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
+           }
        }
 
       type = strip_array_types (type);
@@ -3448,6 +3798,22 @@ check_field_decls (tree t, tree *access_decls,
       if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
        CLASSTYPE_HAS_MUTABLE (t) = 1;
 
+      if (DECL_MUTABLE_P (x))
+       {
+         if (CP_TYPE_CONST_P (type))
+           {
+             error ("member %q+D cannot be declared both %<const%> "
+                    "and %<mutable%>", x);
+             continue;
+           }
+         if (TREE_CODE (type) == REFERENCE_TYPE)
+           {
+             error ("member %q+D cannot be declared as a %<mutable%> "
+                    "reference", x);
+             continue;
+           }
+       }
+
       if (! layout_pod_type_p (type))
        /* DR 148 now allows pointers to members (which are POD themselves),
           to be allowed in POD structs.  */
@@ -3469,8 +3835,8 @@ check_field_decls (tree t, tree *access_decls,
 
       /* Now that we've removed bit-field widths from DECL_INITIAL,
         anything left in DECL_INITIAL is an NSDMI that makes the class
-        non-aggregate.  */
-      if (DECL_INITIAL (x))
+        non-aggregate in C++11.  */
+      if (DECL_INITIAL (x) && cxx_dialect < cxx14)
        CLASSTYPE_NON_AGGREGATE (t) = true;
 
       /* If any field is const, the structure type is pseudo-const.  */
@@ -3479,13 +3845,15 @@ check_field_decls (tree t, tree *access_decls,
          C_TYPE_FIELDS_READONLY (t) = 1;
          if (DECL_INITIAL (x) == NULL_TREE)
            SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
-
-         /* ARM $12.6.2: [A member initializer list] (or, for an
-            aggregate, initialization by a brace-enclosed list) is the
-            only way to initialize nonstatic const and reference
-            members.  */
-         TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
-         TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
+         if (cxx_dialect < cxx11)
+           {
+             /* ARM $12.6.2: [A member initializer list] (or, for an
+                aggregate, initialization by a brace-enclosed list) is the
+                only way to initialize nonstatic const and reference
+                members.  */
+             TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+             TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
+           }
        }
       /* A field that is pseudo-const makes the structure likewise.  */
       else if (CLASS_TYPE_P (type))
@@ -3631,7 +3999,7 @@ walk_subobject_offsets (tree type,
 
   /* If this OFFSET is bigger than the MAX_OFFSET, then we should
      stop.  */
-  if (max_offset && INT_CST_LT (max_offset, offset))
+  if (max_offset && tree_int_cst_lt (max_offset, offset))
     return 0;
 
   if (type == error_mark_node)
@@ -3639,8 +4007,7 @@ walk_subobject_offsets (tree type,
 
   if (!TYPE_P (type))
     {
-      if (abi_version_at_least (2))
-       type_binfo = type;
+      type_binfo = type;
       type = BINFO_TYPE (type);
     }
 
@@ -3666,43 +4033,29 @@ walk_subobject_offsets (tree type,
        {
          tree binfo_offset;
 
-         if (abi_version_at_least (2)
-             && BINFO_VIRTUAL_P (binfo))
+         if (BINFO_VIRTUAL_P (binfo))
            continue;
 
-         if (!vbases_p
-             && BINFO_VIRTUAL_P (binfo)
-             && !BINFO_PRIMARY_P (binfo))
-           continue;
-
-         if (!abi_version_at_least (2))
-           binfo_offset = size_binop (PLUS_EXPR,
-                                      offset,
-                                      BINFO_OFFSET (binfo));
-         else
-           {
-             tree orig_binfo;
-             /* We cannot rely on BINFO_OFFSET being set for the base
-                class yet, but the offsets for direct non-virtual
-                bases can be calculated by going back to the TYPE.  */
-             orig_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
-             binfo_offset = size_binop (PLUS_EXPR,
-                                        offset,
-                                        BINFO_OFFSET (orig_binfo));
-           }
+         tree orig_binfo;
+         /* We cannot rely on BINFO_OFFSET being set for the base
+            class yet, but the offsets for direct non-virtual
+            bases can be calculated by going back to the TYPE.  */
+         orig_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
+         binfo_offset = size_binop (PLUS_EXPR,
+                                    offset,
+                                    BINFO_OFFSET (orig_binfo));
 
          r = walk_subobject_offsets (binfo,
                                      f,
                                      binfo_offset,
                                      offsets,
                                      max_offset,
-                                     (abi_version_at_least (2)
-                                      ? /*vbases_p=*/0 : vbases_p));
+                                     /*vbases_p=*/0);
          if (r)
            return r;
        }
 
-      if (abi_version_at_least (2) && CLASSTYPE_VBASECLASSES (type))
+      if (CLASSTYPE_VBASECLASSES (type))
        {
          unsigned ix;
          vec<tree, va_gc> *vbases;
@@ -3749,15 +4102,13 @@ walk_subobject_offsets (tree type,
 
       /* Iterate through the fields of TYPE.  */
       for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
-       if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field))
+       if (TREE_CODE (field) == FIELD_DECL
+           && TREE_TYPE (field) != error_mark_node
+           && !DECL_ARTIFICIAL (field))
          {
            tree field_offset;
 
-           if (abi_version_at_least (2))
-             field_offset = byte_position (field);
-           else
-             /* In G++ 3.2, DECL_FIELD_OFFSET was used.  */
-             field_offset = DECL_FIELD_OFFSET (field);
+           field_offset = byte_position (field);
 
            r = walk_subobject_offsets (TREE_TYPE (field),
                                        f,
@@ -3784,10 +4135,7 @@ walk_subobject_offsets (tree type,
 
       /* Step through each of the elements in the array.  */
       for (index = size_zero_node;
-          /* G++ 3.2 had an off-by-one error here.  */
-          (abi_version_at_least (2)
-           ? !INT_CST_LT (TYPE_MAX_VALUE (domain), index)
-           : INT_CST_LT (index, TYPE_MAX_VALUE (domain)));
+          !tree_int_cst_lt (TYPE_MAX_VALUE (domain), index);
           index = size_binop (PLUS_EXPR, index, size_one_node))
        {
          r = walk_subobject_offsets (TREE_TYPE (type),
@@ -3803,7 +4151,7 @@ walk_subobject_offsets (tree type,
          /* If this new OFFSET is bigger than the MAX_OFFSET, then
             there's no point in iterating through the remaining
             elements of the array.  */
-         if (max_offset && INT_CST_LT (max_offset, offset))
+         if (max_offset && tree_int_cst_lt (max_offset, offset))
            break;
        }
     }
@@ -3931,10 +4279,6 @@ layout_nonempty_base_or_field (record_layout_info rli,
         offset zero.  */
       if (TREE_CODE (rli->t) == UNION_TYPE)
        break;
-      /* G++ 3.2 did not check for overlaps when placing a non-empty
-        virtual base.  */
-      if (!abi_version_at_least (2) && binfo && BINFO_VIRTUAL_P (binfo))
-       break;
       if (layout_conflict_p (field_p ? type : binfo, offset,
                             offsets, field_p))
        {
@@ -3999,17 +4343,9 @@ layout_empty_base (record_layout_info rli, tree binfo,
   alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype));
 
   if (!integer_zerop (BINFO_OFFSET (binfo)))
-    {
-      if (abi_version_at_least (2))
-       propagate_binfo_offsets
-         (binfo, size_diffop_loc (input_location,
+    propagate_binfo_offsets
+      (binfo, size_diffop_loc (input_location,
                               size_zero_node, BINFO_OFFSET (binfo)));
-      else
-       warning (OPT_Wabi,
-                "offset of empty base %qT may not be ABI-compliant and may"
-                "change in a future version of GCC",
-                BINFO_TYPE (binfo));
-    }
 
   /* This is an empty base class.  We first try to put it at offset
      zero.  */
@@ -4128,14 +4464,7 @@ build_base_field (record_layout_info rli, tree binfo,
                                           /*offsets=*/NULL,
                                           /*max_offset=*/NULL_TREE,
                                           /*vbases_p=*/true))
-           {
-             if (abi_version_at_least (2))
-               CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
-             else
-               warning (OPT_Wabi,
-                        "class %qT will be considered nearly empty in a "
-                        "future version of GCC", t);
-           }
+           CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
        }
 
       /* We do not create a FIELD_DECL for empty base classes because
@@ -4214,11 +4543,11 @@ check_methods (tree t)
   for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
     {
       check_for_override (x, t);
-      if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
+      if (DECL_PURE_VIRTUAL_P (x) && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x)))
        error ("initializer specified for non-virtual method %q+D", x);
       /* The name of the field is the original field name
         Save this in auxiliary field for later overloading.  */
-      if (DECL_VINDEX (x))
+      if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
        {
          TYPE_POLYMORPHIC_P (t) = 1;
          if (DECL_PURE_VIRTUAL_P (x))
@@ -4246,7 +4575,6 @@ build_clone (tree fn, tree name)
   clone = copy_decl (fn);
   /* Reset the function name.  */
   DECL_NAME (clone) = name;
-  SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
   /* Remember where this function came from.  */
   DECL_ABSTRACT_ORIGIN (clone) = fn;
   /* Make it easy to find the CLONE given the FN.  */
@@ -4264,6 +4592,7 @@ build_clone (tree fn, tree name)
       return clone;
     }
 
+  SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
   DECL_CLONED_FUNCTION (clone) = fn;
   /* There's no pending inline data for this function.  */
   DECL_PENDING_INLINE_INFO (clone) = NULL;
@@ -4438,7 +4767,7 @@ clone_function_decl (tree fn, int update_method_vec_p)
     }
 
   /* Note that this is an abstract function that is never emitted.  */
-  DECL_ABSTRACT (fn) = 1;
+  DECL_ABSTRACT_P (fn) = true;
 }
 
 /* DECL is an in charge constructor, which is being defined. This will
@@ -4543,11 +4872,7 @@ deduce_noexcept_on_destructor (tree dtor)
 {
   if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (dtor)))
     {
-      tree ctx = DECL_CONTEXT (dtor);
-      tree implicit_fn = implicitly_declare_fn (sfk_destructor, ctx,
-                                               /*const_p=*/false,
-                                               NULL, NULL);
-      tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
+      tree eh_spec = unevaluated_noexcept_spec ();
       TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor), eh_spec);
     }
 }
@@ -4561,14 +4886,12 @@ deduce_noexcept_on_destructor (tree dtor)
 static void
 deduce_noexcept_on_destructors (tree t)
 {
-  tree fns;
-
   /* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail
      out now.  */
   if (!CLASSTYPE_METHOD_VEC (t))
     return;
 
-  for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+  for (tree fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
     deduce_noexcept_on_destructor (OVL_CURRENT (fns));
 }
 
@@ -4771,7 +5094,8 @@ user_provided_p (tree fn)
     return true;
   else
     return (!DECL_ARTIFICIAL (fn)
-           && !DECL_DEFAULTED_IN_CLASS_P (fn));
+           && !(DECL_INITIALIZED_IN_CLASS_P (fn)
+                && (DECL_DEFAULTED_FN (fn) || DECL_DELETED_FN (fn))));
 }
 
 /* Returns true iff class T has a user-provided constructor.  */
@@ -4798,21 +5122,25 @@ type_has_user_provided_constructor (tree t)
   return false;
 }
 
-/* Returns true iff class T has a user-provided default constructor.  */
+/* Returns true iff class T has a non-user-provided (i.e. implicitly
+   declared or explicitly defaulted in the class body) default
+   constructor.  */
 
 bool
-type_has_user_provided_default_constructor (tree t)
+type_has_non_user_provided_default_constructor (tree t)
 {
   tree fns;
 
-  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+  if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (t))
     return false;
+  if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
+    return true;
 
   for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
     {
       tree fn = OVL_CURRENT (fns);
       if (TREE_CODE (fn) == FUNCTION_DECL
-         && user_provided_p (fn)
+         && !user_provided_p (fn)
          && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)))
        return true;
     }
@@ -4820,6 +5148,44 @@ type_has_user_provided_default_constructor (tree t)
   return false;
 }
 
+/* TYPE is being used as a virtual base, and has a non-trivial move
+   assignment.  Return true if this is due to there being a user-provided
+   move assignment in TYPE or one of its subobjects; if there isn't, then
+   multiple move assignment can't cause any harm.  */
+
+bool
+vbase_has_user_provided_move_assign (tree type)
+{
+  /* Does the type itself have a user-provided move assignment operator?  */
+  for (tree fns
+        = lookup_fnfields_slot_nolazy (type, ansi_assopname (NOP_EXPR));
+       fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (move_fn_p (fn) && user_provided_p (fn))
+       return true;
+    }
+
+  /* Do any of its bases?  */
+  tree binfo = TYPE_BINFO (type);
+  tree base_binfo;
+  for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+    if (vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
+      return true;
+
+  /* Or non-static data members?  */
+  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+    {
+      if (TREE_CODE (field) == FIELD_DECL
+         && CLASS_TYPE_P (TREE_TYPE (field))
+         && vbase_has_user_provided_move_assign (TREE_TYPE (field)))
+       return true;
+    }
+
+  /* Seems not.  */
+  return false;
+}
+
 /* If default-initialization leaves part of TYPE uninitialized, returns
    a DECL for the field or TYPE itself (DR 253).  */
 
@@ -4832,7 +5198,7 @@ default_init_uninitialized_part (tree type)
   type = strip_array_types (type);
   if (!CLASS_TYPE_P (type))
     return type;
-  if (type_has_user_provided_default_constructor (type))
+  if (!type_has_non_user_provided_default_constructor (type))
     return NULL_TREE;
   for (binfo = TYPE_BINFO (type), i = 0;
        BINFO_BASE_ITERATE (binfo, i, t); ++i)
@@ -4998,7 +5364,7 @@ type_has_user_declared_move_assign (tree t)
 }
 
 /* Nonzero if we need to build up a constructor call when initializing an
-   object of this class, either because it has a user-provided constructor
+   object of this class, either because it has a user-declared constructor
    or because it doesn't have a default constructor (so we need to give an
    error if no initializer is provided).  Use TYPE_NEEDS_CONSTRUCTING when
    what you care about is whether or not an object can be produced by a
@@ -5014,8 +5380,50 @@ type_build_ctor_call (tree t)
   if (TYPE_NEEDS_CONSTRUCTING (t))
     return true;
   inner = strip_array_types (t);
-  return (CLASS_TYPE_P (inner) && !TYPE_HAS_DEFAULT_CONSTRUCTOR (inner)
-         && !ANON_AGGR_TYPE_P (inner));
+  if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner))
+    return false;
+  if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (inner))
+    return true;
+  if (cxx_dialect < cxx11)
+    return false;
+  /* A user-declared constructor might be private, and a constructor might
+     be trivial but deleted.  */
+  for (tree fns = lookup_fnfields_slot (inner, complete_ctor_identifier);
+       fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (!DECL_ARTIFICIAL (fn)
+         || DECL_DELETED_FN (fn))
+       return true;
+    }
+  return false;
+}
+
+/* Like type_build_ctor_call, but for destructors.  */
+
+bool
+type_build_dtor_call (tree t)
+{
+  tree inner;
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+    return true;
+  inner = strip_array_types (t);
+  if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner)
+      || !COMPLETE_TYPE_P (inner))
+    return false;
+  if (cxx_dialect < cxx11)
+    return false;
+  /* A user-declared destructor might be private, and a destructor might
+     be trivial but deleted.  */
+  for (tree fns = lookup_fnfields_slot (inner, complete_dtor_identifier);
+       fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (!DECL_ARTIFICIAL (fn)
+         || DECL_DELETED_FN (fn))
+       return true;
+    }
+  return false;
 }
 
 /* Remove all zero-width bit-fields from T.  */
@@ -5035,7 +5443,8 @@ remove_zero_width_bit_fields (tree t)
             DECL_INITIAL (*fieldsp).
             check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
             to that width.  */
-         && integer_zerop (DECL_SIZE (*fieldsp)))
+         && (DECL_SIZE (*fieldsp) == NULL_TREE
+             || integer_zerop (DECL_SIZE (*fieldsp))))
        *fieldsp = DECL_CHAIN (*fieldsp);
       else
        fieldsp = &DECL_CHAIN (*fieldsp);
@@ -5111,7 +5520,7 @@ finalize_literal_type_property (tree t)
 {
   tree fn;
 
-  if (cxx_dialect < cxx0x
+  if (cxx_dialect < cxx11
       || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
     CLASSTYPE_LITERAL_P (t) = false;
   else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
@@ -5142,15 +5551,15 @@ finalize_literal_type_property (tree t)
 void
 explain_non_literal_class (tree t)
 {
-  static struct pointer_set_t *diagnosed;
+  static hash_set<tree> *diagnosed;
 
   if (!CLASS_TYPE_P (t))
     return;
   t = TYPE_MAIN_VARIANT (t);
 
   if (diagnosed == NULL)
-    diagnosed = pointer_set_create ();
-  if (pointer_set_insert (diagnosed, t) != 0)
+    diagnosed = new hash_set<tree>;
+  if (diagnosed->add (t))
     /* Already explained.  */
     return;
 
@@ -5164,8 +5573,7 @@ explain_non_literal_class (tree t)
       inform (0, "  %q+T is not an aggregate, does not have a trivial "
              "default constructor, and has no constexpr constructor that "
              "is not a copy or move constructor", t);
-      if (TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
-         && !type_has_user_provided_default_constructor (t))
+      if (type_has_non_user_provided_default_constructor (t))
        {
          /* Note that we can't simply call locate_ctor because when the
             constructor is deleted it just returns NULL_TREE.  */
@@ -5216,6 +5624,9 @@ explain_non_literal_class (tree t)
              if (CLASS_TYPE_P (ftype))
                explain_non_literal_class (ftype);
            }
+         if (CP_TYPE_VOLATILE_P (ftype))
+           inform (0, "  non-static data member %q+D has "
+                   "volatile type", field);
        }
     }
 }
@@ -5245,14 +5656,15 @@ check_bases_and_members (tree t)
   cant_have_const_ctor = 0;
   no_const_asn_ref = 0;
 
-  /* Deduce noexcept on destructors.  */
-  if (cxx_dialect >= cxx0x)
-    deduce_noexcept_on_destructors (t);
-
   /* Check all the base-classes.  */
   check_bases (t, &cant_have_const_ctor,
               &no_const_asn_ref);
 
+  /* Deduce noexcept on destructors.  This needs to happen after we've set
+     triviality flags appropriately for our bases.  */
+  if (cxx_dialect >= cxx11)
+    deduce_noexcept_on_destructors (t);
+
   /* Check all the method declarations.  */
   check_methods (t);
 
@@ -5305,6 +5717,37 @@ check_bases_and_members (tree t)
   TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
   TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
 
+  /* If the only explicitly declared default constructor is user-provided,
+     set TYPE_HAS_COMPLEX_DFLT.  */
+  if (!TYPE_HAS_COMPLEX_DFLT (t)
+      && TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
+      && !type_has_non_user_provided_default_constructor (t))
+    TYPE_HAS_COMPLEX_DFLT (t) = true;
+
+  /* Warn if a public base of a polymorphic type has an accessible
+     non-virtual destructor.  It is only now that we know the class is
+     polymorphic.  Although a polymorphic base will have a already
+     been diagnosed during its definition, we warn on use too.  */
+  if (TYPE_POLYMORPHIC_P (t) && warn_nonvdtor)
+    {
+      tree binfo = TYPE_BINFO (t);
+      vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (binfo);
+      tree base_binfo;
+      unsigned i;
+      
+      for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+       {
+         tree basetype = TREE_TYPE (base_binfo);
+
+         if ((*accesses)[i] == access_public_node
+             && (TYPE_POLYMORPHIC_P (basetype) || warn_ecpp)
+             && accessible_nvdtor_p (basetype))
+           warning (OPT_Wnon_virtual_dtor,
+                    "base class %q#T has accessible non-virtual destructor",
+                    basetype);
+       }
+    }
+  
   /* If the class has no user-declared constructor, but does have
      non-static const or reference data members that can never be
      initialized, issue a warning.  */
@@ -5367,13 +5810,6 @@ check_bases_and_members (tree t)
 
   if (LAMBDA_TYPE_P (t))
     {
-      /* "The closure type associated with a lambda-expression has a deleted
-        default constructor and a deleted copy assignment operator."  */
-      TYPE_NEEDS_CONSTRUCTING (t) = 1;
-      TYPE_HAS_COMPLEX_DFLT (t) = 1;
-      TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
-      CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 0;
-
       /* "This class type is not an aggregate."  */
       CLASSTYPE_NON_AGGREGATE (t) = 1;
     }
@@ -5413,7 +5849,8 @@ create_vtable_ptr (tree t, tree* virtuals_p)
 
   /* Collect the virtual functions declared in T.  */
   for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
-    if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
+    if (TREE_CODE (fn) == FUNCTION_DECL
+       && DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
        && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
       {
        tree new_virtual = make_node (TREE_LIST);
@@ -5522,27 +5959,11 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
 {
   tree vbase;
   tree t = rli->t;
-  bool first_vbase = true;
   tree *next_field;
 
   if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) == 0)
     return;
 
-  if (!abi_version_at_least(2))
-    {
-      /* In G++ 3.2, we incorrectly rounded the size before laying out
-        the virtual bases.  */
-      finish_record_layout (rli, /*free_p=*/false);
-#ifdef STRUCTURE_SIZE_BOUNDARY
-      /* Packed structures don't need to have minimum size.  */
-      if (! TYPE_PACKED (t))
-       TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), (unsigned) STRUCTURE_SIZE_BOUNDARY);
-#endif
-      rli->offset = TYPE_SIZE_UNIT (t);
-      rli->bitpos = bitsize_zero_node;
-      rli->record_align = TYPE_ALIGN (t);
-    }
-
   /* Find the last field.  The artificial fields created for virtual
      bases will go after the last extant field to date.  */
   next_field = &TYPE_FIELDS (t);
@@ -5559,35 +5980,10 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
 
       if (!BINFO_PRIMARY_P (vbase))
        {
-         tree basetype = TREE_TYPE (vbase);
-
          /* This virtual base is not a primary base of any class in the
             hierarchy, so we have to add space for it.  */
          next_field = build_base_field (rli, vbase,
                                         offsets, next_field);
-
-         /* If the first virtual base might have been placed at a
-            lower address, had we started from CLASSTYPE_SIZE, rather
-            than TYPE_SIZE, issue a warning.  There can be both false
-            positives and false negatives from this warning in rare
-            cases; to deal with all the possibilities would probably
-            require performing both layout algorithms and comparing
-            the results which is not particularly tractable.  */
-         if (warn_abi
-             && first_vbase
-             && (tree_int_cst_lt
-                 (size_binop (CEIL_DIV_EXPR,
-                              round_up_loc (input_location,
-                                        CLASSTYPE_SIZE (t),
-                                        CLASSTYPE_ALIGN (basetype)),
-                              bitsize_unit_node),
-                  BINFO_OFFSET (vbase))))
-           warning (OPT_Wabi,
-                    "offset of virtual base %qT is not ABI-compliant and "
-                    "may change in a future version of GCC",
-                    basetype);
-
-         first_vbase = false;
        }
     }
 }
@@ -5637,17 +6033,16 @@ end_of_class (tree t, int include_virtuals_p)
        continue;
 
       offset = end_of_base (base_binfo);
-      if (INT_CST_LT_UNSIGNED (result, offset))
+      if (tree_int_cst_lt (result, offset))
        result = offset;
     }
 
-  /* G++ 3.2 did not check indirect virtual bases.  */
-  if (abi_version_at_least (2) && include_virtuals_p)
+  if (include_virtuals_p)
     for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
         vec_safe_iterate (vbases, i, &base_binfo); i++)
       {
        offset = end_of_base (base_binfo);
-       if (INT_CST_LT_UNSIGNED (result, offset))
+       if (tree_int_cst_lt (result, offset))
          result = offset;
       }
 
@@ -5727,19 +6122,11 @@ include_empty_classes (record_layout_info rli)
                      CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
   rli_size = rli_size_unit_so_far (rli);
   if (TREE_CODE (rli_size) == INTEGER_CST
-      && INT_CST_LT_UNSIGNED (rli_size, eoc))
-    {
-      if (!abi_version_at_least (2))
-       /* In version 1 of the ABI, the size of a class that ends with
-          a bitfield was not rounded up to a whole multiple of a
-          byte.  Because rli_size_unit_so_far returns only the number
-          of fully allocated bytes, any extra bits were not included
-          in the size.  */
-       rli->bitpos = round_down (rli->bitpos, BITS_PER_UNIT);
-      else
-       /* The size should have been rounded to a whole byte.  */
-       gcc_assert (tree_int_cst_equal
-                   (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT)));
+      && tree_int_cst_lt (rli_size, eoc))
+    {
+      /* The size should have been rounded to a whole byte.  */
+      gcc_assert (tree_int_cst_equal
+                 (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT)));
       rli->bitpos
        = size_binop (PLUS_EXPR,
                      rli->bitpos,
@@ -5766,7 +6153,7 @@ layout_class_type (tree t, tree *virtuals_p)
   /* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of
      types that appear at that offset.  */
   splay_tree empty_base_offsets;
-  /* True if the last field layed out was a bit-field.  */
+  /* True if the last field laid out was a bit-field.  */
   bool last_field_was_bitfield = false;
   /* The location at which the next field should be inserted.  */
   tree *next_field;
@@ -5822,7 +6209,7 @@ layout_class_type (tree t, tree *virtuals_p)
 
             At this point, finish_record_layout will be called, but
             S1 is still incomplete.)  */
-         if (TREE_CODE (field) == VAR_DECL)
+         if (VAR_P (field))
            {
              maybe_register_incomplete_var (field);
              /* The visibility of static data members is determined
@@ -5843,7 +6230,7 @@ layout_class_type (tree t, tree *virtuals_p)
         type, then there are some special rules for allocating
         it.  */
       if (DECL_C_BIT_FIELD (field)
-         && INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
+         && tree_int_cst_lt (TYPE_SIZE (type), DECL_SIZE (field)))
        {
          unsigned int itk;
          tree integer_type;
@@ -5854,10 +6241,10 @@ layout_class_type (tree t, tree *virtuals_p)
             bits as additional padding.  */
          for (itk = itk_char; itk != itk_none; ++itk)
            if (integer_types[itk] != NULL_TREE
-               && (INT_CST_LT (size_int (MAX_FIXED_MODE_SIZE),
-                               TYPE_SIZE (integer_types[itk]))
-                   || INT_CST_LT (DECL_SIZE (field),
-                                  TYPE_SIZE (integer_types[itk]))))
+               && (tree_int_cst_lt (size_int (MAX_FIXED_MODE_SIZE),
+                                    TYPE_SIZE (integer_types[itk]))
+                   || tree_int_cst_lt (DECL_SIZE (field),
+                                       TYPE_SIZE (integer_types[itk]))))
              break;
 
          /* ITK now indicates a type that is too large for the
@@ -5869,28 +6256,18 @@ layout_class_type (tree t, tree *virtuals_p)
            integer_type = integer_types[itk];
          } while (itk > 0 && integer_type == NULL_TREE);
 
-         /* Figure out how much additional padding is required.  GCC
-            3.2 always created a padding field, even if it had zero
-            width.  */
-         if (!abi_version_at_least (2)
-             || INT_CST_LT (TYPE_SIZE (integer_type), DECL_SIZE (field)))
+         /* Figure out how much additional padding is required.  */
+         if (tree_int_cst_lt (TYPE_SIZE (integer_type), DECL_SIZE (field)))
            {
-             if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
+             if (TREE_CODE (t) == UNION_TYPE)
                /* In a union, the padding field must have the full width
                   of the bit-field; all fields start at offset zero.  */
                padding = DECL_SIZE (field);
              else
-               {
-                 if (TREE_CODE (t) == UNION_TYPE)
-                   warning (OPT_Wabi, "size assigned to %qT may not be "
-                            "ABI-compliant and may change in a future "
-                            "version of GCC",
-                            t);
-                 padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
-                                       TYPE_SIZE (integer_type));
-               }
+               padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
+                                     TYPE_SIZE (integer_type));
            }
-#ifdef PCC_BITFIELD_TYPE_MATTERS
+
          /* An unnamed bitfield does not normally affect the
             alignment of the containing class on a target where
             PCC_BITFIELD_TYPE_MATTERS.  But, the C++ ABI does not
@@ -5902,7 +6279,7 @@ layout_class_type (tree t, tree *virtuals_p)
              was_unnamed_p = true;
              DECL_NAME (field) = make_anon_name ();
            }
-#endif
+
          DECL_SIZE (field) = TYPE_SIZE (integer_type);
          DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
          DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
@@ -5915,26 +6292,17 @@ layout_class_type (tree t, tree *virtuals_p)
             field is effectively invisible.  */
          DECL_SIZE (field) = TYPE_SIZE (type);
          /* We must also reset the DECL_MODE of the field.  */
-         if (abi_version_at_least (2))
-           DECL_MODE (field) = TYPE_MODE (type);
-         else if (warn_abi
-                  && DECL_MODE (field) != TYPE_MODE (type))
-           /* Versions of G++ before G++ 3.4 did not reset the
-              DECL_MODE.  */
-           warning (OPT_Wabi,
-                    "the offset of %qD may not be ABI-compliant and may "
-                    "change in a future version of GCC", field);
+         DECL_MODE (field) = TYPE_MODE (type);
        }
       else
        layout_nonempty_base_or_field (rli, field, NULL_TREE,
                                       empty_base_offsets);
 
       /* Remember the location of any empty classes in FIELD.  */
-      if (abi_version_at_least (2))
-       record_subobject_offsets (TREE_TYPE (field),
-                                 byte_position(field),
-                                 empty_base_offsets,
-                                 /*is_data_member=*/true);
+      record_subobject_offsets (TREE_TYPE (field),
+                               byte_position(field),
+                               empty_base_offsets,
+                               /*is_data_member=*/true);
 
       /* If a bit-field does not immediately follow another bit-field,
         and yet it starts in the middle of a byte, we have failed to
@@ -5953,17 +6321,6 @@ layout_class_type (tree t, tree *virtuals_p)
        warning (OPT_Wabi, "offset of %q+D is not ABI-compliant and may "
                 "change in a future version of GCC", field);
 
-      /* G++ used to use DECL_FIELD_OFFSET as if it were the byte
-        offset of the field.  */
-      if (warn_abi
-         && !abi_version_at_least (2)
-         && !tree_int_cst_equal (DECL_FIELD_OFFSET (field),
-                                 byte_position (field))
-         && contains_empty_class_p (TREE_TYPE (field)))
-       warning (OPT_Wabi, "%q+D contains empty classes which may cause base "
-                "classes to be placed at different locations in a "
-                "future version of GCC", field);
-
       /* The middle end uses the type of expressions to determine the
         possible range of expression values.  In order to optimize
         "x.i > 7" to "false" for a 2-bit bitfield "i", the middle end
@@ -5979,7 +6336,7 @@ layout_class_type (tree t, tree *virtuals_p)
        {
          unsigned HOST_WIDE_INT width;
          tree ftype = TREE_TYPE (field);
-         width = tree_low_cst (DECL_SIZE (field), /*unsignedp=*/1);
+         width = tree_to_uhwi (DECL_SIZE (field));
          if (width != TYPE_PRECISION (ftype))
            {
              TREE_TYPE (field)
@@ -6014,7 +6371,7 @@ layout_class_type (tree t, tree *virtuals_p)
       last_field_was_bitfield = DECL_C_BIT_FIELD (field);
     }
 
-  if (abi_version_at_least (2) && !integer_zerop (rli->bitpos))
+  if (!integer_zerop (rli->bitpos))
     {
       /* Make sure that we are on a byte boundary so that the size of
         the class without virtual bases will always be a round number
@@ -6023,11 +6380,6 @@ layout_class_type (tree t, tree *virtuals_p)
       normalize_rli (rli);
     }
 
-  /* G++ 3.2 does not allow virtual bases to be overlaid with tail
-     padding.  */
-  if (!abi_version_at_least (2))
-    include_empty_classes(rli);
-
   /* Delete all zero-width bit-fields from the list of fields.  Now
      that the type is laid out they are no longer important.  */
   remove_zero_width_bit_fields (t);
@@ -6039,45 +6391,30 @@ layout_class_type (tree t, tree *virtuals_p)
     {
       base_t = make_node (TREE_CODE (t));
 
-      /* Set the size and alignment for the new type.  In G++ 3.2, all
-        empty classes were considered to have size zero when used as
-        base classes.  */
-      if (!abi_version_at_least (2) && CLASSTYPE_EMPTY_P (t))
-       {
-         TYPE_SIZE (base_t) = bitsize_zero_node;
-         TYPE_SIZE_UNIT (base_t) = size_zero_node;
-         if (warn_abi && !integer_zerop (rli_size_unit_so_far (rli)))
-           warning (OPT_Wabi,
-                    "layout of classes derived from empty class %qT "
-                    "may change in a future version of GCC",
-                    t);
-       }
-      else
-       {
-         tree eoc;
-
-         /* If the ABI version is not at least two, and the last
-            field was a bit-field, RLI may not be on a byte
-            boundary.  In particular, rli_size_unit_so_far might
-            indicate the last complete byte, while rli_size_so_far
-            indicates the total number of bits used.  Therefore,
-            rli_size_so_far, rather than rli_size_unit_so_far, is
-            used to compute TYPE_SIZE_UNIT.  */
-         eoc = end_of_class (t, /*include_virtuals_p=*/0);
-         TYPE_SIZE_UNIT (base_t)
-           = size_binop (MAX_EXPR,
-                         convert (sizetype,
-                                  size_binop (CEIL_DIV_EXPR,
-                                              rli_size_so_far (rli),
-                                              bitsize_int (BITS_PER_UNIT))),
-                         eoc);
-         TYPE_SIZE (base_t)
-           = size_binop (MAX_EXPR,
-                         rli_size_so_far (rli),
-                         size_binop (MULT_EXPR,
-                                     convert (bitsizetype, eoc),
-                                     bitsize_int (BITS_PER_UNIT)));
-       }
+      /* Set the size and alignment for the new type.  */
+      tree eoc;
+
+      /* If the ABI version is not at least two, and the last
+        field was a bit-field, RLI may not be on a byte
+        boundary.  In particular, rli_size_unit_so_far might
+        indicate the last complete byte, while rli_size_so_far
+        indicates the total number of bits used.  Therefore,
+        rli_size_so_far, rather than rli_size_unit_so_far, is
+        used to compute TYPE_SIZE_UNIT.  */
+      eoc = end_of_class (t, /*include_virtuals_p=*/0);
+      TYPE_SIZE_UNIT (base_t)
+       = size_binop (MAX_EXPR,
+                     convert (sizetype,
+                              size_binop (CEIL_DIV_EXPR,
+                                          rli_size_so_far (rli),
+                                          bitsize_int (BITS_PER_UNIT))),
+                     eoc);
+      TYPE_SIZE (base_t)
+       = size_binop (MAX_EXPR,
+                     rli_size_so_far (rli),
+                     size_binop (MULT_EXPR,
+                                 convert (bitsizetype, eoc),
+                                 bitsize_int (BITS_PER_UNIT)));
       TYPE_ALIGN (base_t) = rli->record_align;
       TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t);
 
@@ -6139,6 +6476,12 @@ layout_class_type (tree t, tree *virtuals_p)
   /* Let the back end lay out the type.  */
   finish_record_layout (rli, /*free_p=*/true);
 
+  if (TYPE_SIZE_UNIT (t)
+      && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
+      && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))
+      && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
+    error ("type %qT is too large", t);
+
   /* Warn about bases that can't be talked about due to ambiguity.  */
   warn_about_ambiguous_bases (t);
 
@@ -6176,7 +6519,8 @@ determine_key_method (tree type)
      this function until the end of the translation unit.  */
   for (method = TYPE_METHODS (type); method != NULL_TREE;
        method = DECL_CHAIN (method))
-    if (DECL_VINDEX (method) != NULL_TREE
+    if (TREE_CODE (method) == FUNCTION_DECL
+       && DECL_VINDEX (method) != NULL_TREE
        && ! DECL_DECLARED_INLINE_P (method)
        && ! DECL_PURE_VIRTUAL_P (method))
       {
@@ -6195,7 +6539,7 @@ static struct sorted_fields_type *
 sorted_fields_type_new (int n)
 {
   struct sorted_fields_type *sft;
-  sft = ggc_alloc_sorted_fields_type (sizeof (struct sorted_fields_type)
+  sft = (sorted_fields_type *) ggc_internal_alloc (sizeof (sorted_fields_type)
                                      + n * sizeof (tree));
   sft->len = n;
 
@@ -6252,7 +6596,9 @@ finish_struct_1 (tree t)
        determine_key_method (t);
 
       /* If a polymorphic class has no key method, we may emit the vtable
-        in every translation unit where the class definition appears.  */
+        in every translation unit where the class definition appears.  If
+        we're devirtualizing, we can look into the vtable even if we
+        aren't emitting it.  */
       if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE)
        keyed_classes = tree_cons (NULL_TREE, t, keyed_classes);
     }
@@ -6323,7 +6669,7 @@ finish_struct_1 (tree t)
   /* Complete the rtl for any static member objects of the type we're
      working on.  */
   for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
-    if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x)
+    if (VAR_P (x) && TREE_STATIC (x)
         && TREE_TYPE (x) != error_mark_node
        && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
       DECL_MODE (x) = TYPE_MODE (t);
@@ -6349,25 +6695,12 @@ finish_struct_1 (tree t)
 
   /* This warning does not make sense for Java classes, since they
      cannot have destructors.  */
-  if (!TYPE_FOR_JAVA (t) && warn_nonvdtor && TYPE_POLYMORPHIC_P (t))
-    {
-      tree dtor;
-
-      dtor = CLASSTYPE_DESTRUCTORS (t);
-      if (/* An implicitly declared destructor is always public.  And,
-            if it were virtual, we would have created it by now.  */
-         !dtor
-         || (!DECL_VINDEX (dtor)
-             && (/* public non-virtual */
-                 (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor))
-                  || (/* non-public non-virtual with friends */
-                      (TREE_PRIVATE (dtor) || TREE_PROTECTED (dtor))
-                       && (CLASSTYPE_FRIEND_CLASSES (t)
-                       || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))))))
-       warning (OPT_Wnon_virtual_dtor,
-                "%q#T has virtual functions and accessible"
-                " non-virtual destructor", t);
-    }
+  if (!TYPE_FOR_JAVA (t) && warn_nonvdtor
+      && TYPE_POLYMORPHIC_P (t) && accessible_nvdtor_p (t)
+      && !CLASSTYPE_FINAL (t))
+    warning (OPT_Wnon_virtual_dtor,
+            "%q#T has virtual functions and accessible"
+            " non-virtual destructor", t);
 
   complete_vars (t);
 
@@ -6381,6 +6714,9 @@ finish_struct_1 (tree t)
 
   maybe_suppress_debug_info (t);
 
+  if (flag_vtable_verify)
+    vtv_save_class_info (t);
+
   dump_class_hierarchy (t);
 
   /* Finish debugging output for this type.  */
@@ -6551,6 +6887,29 @@ finish_struct (tree t, tree attributes)
   else
     finish_struct_1 (t);
 
+  if (is_std_init_list (t))
+    {
+      /* People keep complaining that the compiler crashes on an invalid
+        definition of initializer_list, so I guess we should explicitly
+        reject it.  What the compiler internals care about is that it's a
+        template and has a pointer field followed by an integer field.  */
+      bool ok = false;
+      if (processing_template_decl)
+       {
+         tree f = next_initializable_field (TYPE_FIELDS (t));
+         if (f && TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE)
+           {
+             f = next_initializable_field (DECL_CHAIN (f));
+             if (f && same_type_p (TREE_TYPE (f), size_type_node))
+               ok = true;
+           }
+       }
+      if (!ok)
+       fatal_error (input_location,
+                    "definition of std::initializer_list does not match "
+                    "#include <initializer_list>");
+    }
+
   input_location = saved_loc;
 
   TYPE_BEING_DEFINED (t) = 0;
@@ -6569,7 +6928,7 @@ finish_struct (tree t, tree attributes)
 }
 \f
 /* Hash table to avoid endless recursion when handling references.  */
-static hash_table <pointer_hash <tree_node> > fixed_type_or_null_ref_ht;
+static hash_table<pointer_hash<tree_node> > *fixed_type_or_null_ref_ht;
 
 /* Return the dynamic type of INSTANCE, if known.
    Used to determine whether the virtual function table is needed
@@ -6686,8 +7045,9 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
       else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
        {
          /* We only need one hash table because it is always left empty.  */
-         if (!fixed_type_or_null_ref_ht.is_created ())
-           fixed_type_or_null_ref_ht.create (37); 
+         if (!fixed_type_or_null_ref_ht)
+           fixed_type_or_null_ref_ht
+             = new hash_table<pointer_hash<tree_node> > (37); 
 
          /* Reference variables should be references to objects.  */
          if (nonnull)
@@ -6696,18 +7056,18 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
          /* Enter the INSTANCE in a table to prevent recursion; a
             variable's initializer may refer to the variable
             itself.  */
-         if (TREE_CODE (instance) == VAR_DECL
+         if (VAR_P (instance)
              && DECL_INITIAL (instance)
              && !type_dependent_expression_p_push (DECL_INITIAL (instance))
-             && !fixed_type_or_null_ref_ht.find (instance))
+             && !fixed_type_or_null_ref_ht->find (instance))
            {
              tree type;
              tree_node **slot;
 
-             slot = fixed_type_or_null_ref_ht.find_slot (instance, INSERT);
+             slot = fixed_type_or_null_ref_ht->find_slot (instance, INSERT);
              *slot = instance;
              type = RECUR (DECL_INITIAL (instance));
-             fixed_type_or_null_ref_ht.remove_elt (instance);
+             fixed_type_or_null_ref_ht->remove_elt (instance);
 
              return type;
            }
@@ -6725,7 +7085,7 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
    INSTANCE is really a pointer. Return negative if this is a
    ctor/dtor. There the dynamic type is known, but this might not be
    the most derived base of the original object, and hence virtual
-   bases may not be layed out according to this type.
+   bases may not be laid out according to this type.
 
    Used to determine whether the virtual function table is needed
    or not.
@@ -6742,7 +7102,8 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
   tree fixed;
 
   /* processing_template_decl can be false in a template if we're in
-     fold_non_dependent_expr, but we still want to suppress this check.  */
+     instantiate_non_dependent_expr, but we still want to suppress
+     this check.  */
   if (in_template_function ())
     {
       /* In a template we only care about the type of the result.  */
@@ -6967,6 +7328,29 @@ currently_open_derived_class (tree t)
   return NULL_TREE;
 }
 
+/* Return the outermost enclosing class type that is still open, or
+   NULL_TREE.  */
+
+tree
+outermost_open_class (void)
+{
+  if (!current_class_type)
+    return NULL_TREE;
+  tree r = NULL_TREE;
+  if (TYPE_BEING_DEFINED (current_class_type))
+    r = current_class_type;
+  for (int i = current_class_depth - 1; i > 0; --i)
+    {
+      if (current_class_stack[i].hidden)
+       break;
+      tree t = current_class_stack[i].type;
+      if (!TYPE_BEING_DEFINED (t))
+       break;
+      r = t;
+    }
+  return r;
+}
+
 /* Returns the innermost class type which is not a lambda closure type.  */
 
 tree
@@ -7096,7 +7480,7 @@ pop_lang_context (void)
 static tree
 resolve_address_of_overloaded_function (tree target_type,
                                        tree overload,
-                                       tsubst_flags_t flags,
+                                       tsubst_flags_t complain,
                                        bool template_only,
                                        tree explicit_targs,
                                        tree access_path)
@@ -7138,13 +7522,14 @@ resolve_address_of_overloaded_function (tree target_type,
   /* By the time we get here, we should be seeing only real
      pointer-to-member types, not the internal POINTER_TYPE to
      METHOD_TYPE representation.  */
-  gcc_assert (TREE_CODE (target_type) != POINTER_TYPE
+  gcc_assert (!TYPE_PTR_P (target_type)
              || TREE_CODE (TREE_TYPE (target_type)) != METHOD_TYPE);
 
   gcc_assert (is_overloaded_fn (overload));
 
   /* Check that the TARGET_TYPE is reasonable.  */
-  if (TYPE_PTRFN_P (target_type))
+  if (TYPE_PTRFN_P (target_type)
+      || TYPE_REFFN_P (target_type))
     /* This is OK.  */;
   else if (TYPE_PTRMEMFUNC_P (target_type))
     /* This is OK, too.  */
@@ -7155,7 +7540,7 @@ resolve_address_of_overloaded_function (tree target_type,
     target_type = build_reference_type (target_type);
   else
     {
-      if (flags & tf_error)
+      if (complain & tf_error)
        error ("cannot resolve overloaded function %qD based on"
               " conversion to type %qT",
               DECL_NAME (OVL_FUNCTION (overload)), target_type);
@@ -7243,16 +7628,33 @@ resolve_address_of_overloaded_function (tree target_type,
               one, or vice versa.  */
            continue;
 
+         tree ret = target_ret_type;
+
+         /* If the template has a deduced return type, don't expose it to
+            template argument deduction.  */
+         if (undeduced_auto_decl (fn))
+           ret = NULL_TREE;
+
          /* Try to do argument deduction.  */
          targs = make_tree_vec (DECL_NTPARMS (fn));
          instantiation = fn_type_unification (fn, explicit_targs, targs, args,
-                                             nargs, target_ret_type,
+                                              nargs, ret,
                                              DEDUCE_EXACT, LOOKUP_NORMAL,
-                                              false);
+                                              false, false);
          if (instantiation == error_mark_node)
            /* Instantiation failed.  */
            continue;
 
+         /* And now force instantiation to do return type deduction.  */
+         if (undeduced_auto_decl (instantiation))
+           {
+             ++function_depth;
+             instantiate_decl (instantiation, /*defer*/false, /*class*/false);
+             --function_depth;
+
+             require_deduced_type (instantiation);
+           }
+
          /* See if there's a match.  */
          if (same_type_p (target_fn_type, static_fn_type (instantiation)))
            matches = tree_cons (instantiation, fn, matches);
@@ -7274,7 +7676,7 @@ resolve_address_of_overloaded_function (tree target_type,
   if (matches == NULL_TREE)
     {
       /* There were *no* matches.  */
-      if (flags & tf_error)
+      if (complain & tf_error)
        {
          error ("no matches converting function %qD to type %q#T",
                 DECL_NAME (OVL_CURRENT (overload)),
@@ -7302,7 +7704,7 @@ resolve_address_of_overloaded_function (tree target_type,
 
       if (match)
        {
-         if (flags & tf_error)
+         if (complain & tf_error)
            {
              error ("converting overloaded function %qD to type %q#T is ambiguous",
                     DECL_NAME (OVL_FUNCTION (overload)),
@@ -7324,11 +7726,11 @@ resolve_address_of_overloaded_function (tree target_type,
   fn = TREE_PURPOSE (matches);
 
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
-      && !(flags & tf_ptrmem_ok) && !flag_ms_extensions)
+      && !(complain & tf_ptrmem_ok) && !flag_ms_extensions)
     {
       static int explained;
 
-      if (!(flags & tf_error))
+      if (!(complain & tf_error))
        return error_mark_node;
 
       permerror (input_location, "assuming pointer to member %qD", fn);
@@ -7349,7 +7751,7 @@ resolve_address_of_overloaded_function (tree target_type,
       if (fn == NULL)
        return error_mark_node;
       /* Mark all the versions corresponding to the dispatcher as used.  */
-      if (!(flags & tf_conv))
+      if (!(complain & tf_conv))
        mark_versions_used (fn);
     }
 
@@ -7357,13 +7759,13 @@ resolve_address_of_overloaded_function (tree target_type,
      determining conversion sequences, we should not consider the
      function used.  If this conversion sequence is selected, the
      function will be marked as used at this point.  */
-  if (!(flags & tf_conv))
+  if (!(complain & tf_conv))
     {
       /* Make =delete work with SFINAE.  */
-      if (DECL_DELETED_FN (fn) && !(flags & tf_error))
+      if (DECL_DELETED_FN (fn) && !(complain & tf_error))
+       return error_mark_node;
+      if (!mark_used (fn, complain) && !(complain & tf_error))
        return error_mark_node;
-      
-      mark_used (fn);
     }
 
   /* We could not check access to member functions when this
@@ -7372,11 +7774,11 @@ resolve_address_of_overloaded_function (tree target_type,
   if (DECL_FUNCTION_MEMBER_P (fn))
     {
       gcc_assert (access_path);
-      perform_or_defer_access_check (access_path, fn, fn, flags);
+      perform_or_defer_access_check (access_path, fn, fn, complain);
     }
 
   if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
-    return cp_build_addr_expr (fn, flags);
+    return cp_build_addr_expr (fn, complain);
   else
     {
       /* The target must be a REFERENCE_TYPE.  Above, cp_build_unary_op
@@ -7390,7 +7792,7 @@ resolve_address_of_overloaded_function (tree target_type,
 
 /* This function will instantiate the type of the expression given in
    RHS to match the type of LHSTYPE.  If errors exist, then return
-   error_mark_node. FLAGS is a bit mask.  If TF_ERROR is set, then
+   error_mark_node. COMPLAIN is a bit mask.  If TF_ERROR is set, then
    we complain on errors.  If we are not complaining, never modify rhs,
    as overload resolution wants to try many possible instantiations, in
    the hope that at least one will work.
@@ -7399,35 +7801,36 @@ resolve_address_of_overloaded_function (tree target_type,
    function, or a pointer to member function.  */
 
 tree
-instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
+instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
 {
-  tsubst_flags_t flags_in = flags;
+  tsubst_flags_t complain_in = complain;
   tree access_path = NULL_TREE;
 
-  flags &= ~tf_ptrmem_ok;
+  complain &= ~tf_ptrmem_ok;
 
   if (lhstype == unknown_type_node)
     {
-      if (flags & tf_error)
+      if (complain & tf_error)
        error ("not enough type information");
       return error_mark_node;
     }
 
   if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
     {
-      if (same_type_p (lhstype, TREE_TYPE (rhs)))
+      tree fntype = non_reference (lhstype);
+      if (same_type_p (fntype, TREE_TYPE (rhs)))
        return rhs;
       if (flag_ms_extensions
-         && TYPE_PTRMEMFUNC_P (lhstype)
+         && TYPE_PTRMEMFUNC_P (fntype)
          && !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
        /* Microsoft allows `A::f' to be resolved to a
           pointer-to-member.  */
        ;
       else
        {
-         if (flags & tf_error)
+         if (complain & tf_error)
            error ("cannot convert %qE from type %qT to type %qT",
-                  rhs, TREE_TYPE (rhs), lhstype);
+                  rhs, TREE_TYPE (rhs), fntype);
          return error_mark_node;
        }
     }
@@ -7442,7 +7845,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
      deduce any type information.  */
   if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
     {
-      if (flags & tf_error)
+      if (complain & tf_error)
        error ("not enough type information");
       return error_mark_node;
     }
@@ -7451,7 +7854,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
      dependent on overload resolution.  */
   gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
              || TREE_CODE (rhs) == COMPONENT_REF
-             || really_overloaded_fn (rhs)
+             || is_overloaded_fn (rhs)
              || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));
 
   /* This should really only be used when attempting to distinguish
@@ -7465,7 +7868,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       {
        tree member = TREE_OPERAND (rhs, 1);
 
-       member = instantiate_type (lhstype, member, flags);
+       member = instantiate_type (lhstype, member, complain);
        if (member != error_mark_node
            && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
          /* Do not lose object's side effects.  */
@@ -7477,7 +7880,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     case OFFSET_REF:
       rhs = TREE_OPERAND (rhs, 1);
       if (BASELINK_P (rhs))
-       return instantiate_type (lhstype, rhs, flags_in);
+       return instantiate_type (lhstype, rhs, complain_in);
 
       /* This can happen if we are forming a pointer-to-member for a
         member template.  */
@@ -7491,7 +7894,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
        tree args = TREE_OPERAND (rhs, 1);
 
        return
-         resolve_address_of_overloaded_function (lhstype, fns, flags_in,
+         resolve_address_of_overloaded_function (lhstype, fns, complain_in,
                                                  /*template_only=*/true,
                                                  args, access_path);
       }
@@ -7499,7 +7902,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     case OVERLOAD:
     case FUNCTION_DECL:
       return
-       resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
+       resolve_address_of_overloaded_function (lhstype, rhs, complain_in,
                                                /*template_only=*/false,
                                                /*explicit_targs=*/NULL_TREE,
                                                access_path);
@@ -7507,9 +7910,9 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     case ADDR_EXPR:
     {
       if (PTRMEM_OK_P (rhs))
-       flags |= tf_ptrmem_ok;
+       complain |= tf_ptrmem_ok;
 
-      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
+      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
     }
 
     case ERROR_MARK:
@@ -7608,41 +8011,7 @@ is_empty_class (tree type)
   if (! CLASS_TYPE_P (type))
     return 0;
 
-  /* In G++ 3.2, whether or not a class was empty was determined by
-     looking at its size.  */
-  if (abi_version_at_least (2))
-    return CLASSTYPE_EMPTY_P (type);
-  else
-    return integer_zerop (CLASSTYPE_SIZE (type));
-}
-
-/* Returns true if TYPE contains an empty class.  */
-
-static bool
-contains_empty_class_p (tree type)
-{
-  if (is_empty_class (type))
-    return true;
-  if (CLASS_TYPE_P (type))
-    {
-      tree field;
-      tree binfo;
-      tree base_binfo;
-      int i;
-
-      for (binfo = TYPE_BINFO (type), i = 0;
-          BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
-       if (contains_empty_class_p (BINFO_TYPE (base_binfo)))
-         return true;
-      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
-       if (TREE_CODE (field) == FIELD_DECL
-           && !DECL_ARTIFICIAL (field)
-           && is_empty_class (TREE_TYPE (field)))
-         return true;
-    }
-  else if (TREE_CODE (type) == ARRAY_TYPE)
-    return contains_empty_class_p (TREE_TYPE (type));
-  return false;
+  return CLASSTYPE_EMPTY_P (type);
 }
 
 /* Returns true if TYPE contains no actual data, just various
@@ -7760,7 +8129,7 @@ get_vtbl_decl_for_binfo (tree binfo)
       decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
     }
   if (decl)
-    gcc_assert (TREE_CODE (decl) == VAR_DECL);
+    gcc_assert (VAR_P (decl));
   return decl;
 }
 
@@ -7821,7 +8190,7 @@ dump_class_hierarchy_r (FILE *stream,
   igo = TREE_CHAIN (binfo);
 
   fprintf (stream, HOST_WIDE_INT_PRINT_DEC,
-          tree_low_cst (BINFO_OFFSET (binfo), 0));
+          tree_to_shwi (BINFO_OFFSET (binfo)));
   if (is_empty_class (BINFO_TYPE (binfo)))
     fprintf (stream, " empty");
   else if (CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (binfo)))
@@ -7897,10 +8266,10 @@ dump_class_hierarchy_1 (FILE *stream, int flags, tree t)
 {
   fprintf (stream, "Class %s\n", type_as_string (t, TFF_PLAIN_IDENTIFIER));
   fprintf (stream, "   size=%lu align=%lu\n",
-          (unsigned long)(tree_low_cst (TYPE_SIZE (t), 0) / BITS_PER_UNIT),
+          (unsigned long)(tree_to_shwi (TYPE_SIZE (t)) / BITS_PER_UNIT),
           (unsigned long)(TYPE_ALIGN (t) / BITS_PER_UNIT));
   fprintf (stream, "   base size=%lu base align=%lu\n",
-          (unsigned long)(tree_low_cst (TYPE_SIZE (CLASSTYPE_AS_BASE (t)), 0)
+          (unsigned long)(tree_to_shwi (TYPE_SIZE (CLASSTYPE_AS_BASE (t)))
                           / BITS_PER_UNIT),
           (unsigned long)(TYPE_ALIGN (CLASSTYPE_AS_BASE (t))
                           / BITS_PER_UNIT));
@@ -7920,12 +8289,11 @@ static void
 dump_class_hierarchy (tree t)
 {
   int flags;
-  FILE *stream = dump_begin (TDI_class, &flags);
+  FILE *stream = get_dump_info (TDI_class, &flags);
 
   if (stream)
     {
       dump_class_hierarchy_1 (stream, flags, t);
-      dump_end (TDI_class, stream);
     }
 }
 
@@ -7937,7 +8305,7 @@ dump_array (FILE * stream, tree decl)
   HOST_WIDE_INT elt;
   tree size = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (decl)));
 
-  elt = (tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))), 0)
+  elt = (tree_to_shwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))))
         / BITS_PER_UNIT);
   fprintf (stream, "%s:", decl_as_string (decl, TFF_PLAIN_IDENTIFIER));
   fprintf (stream, " %s entries",
@@ -7955,7 +8323,7 @@ static void
 dump_vtable (tree t, tree binfo, tree vtable)
 {
   int flags;
-  FILE *stream = dump_begin (TDI_class, &flags);
+  FILE *stream = get_dump_info (TDI_class, &flags);
 
   if (!stream)
     return;
@@ -7978,15 +8346,13 @@ dump_vtable (tree t, tree binfo, tree vtable)
       dump_array (stream, vtable);
       fprintf (stream, "\n");
     }
-
-  dump_end (TDI_class, stream);
 }
 
 static void
 dump_vtt (tree t, tree vtt)
 {
   int flags;
-  FILE *stream = dump_begin (TDI_class, &flags);
+  FILE *stream = get_dump_info (TDI_class, &flags);
 
   if (!stream)
     return;
@@ -7998,8 +8364,6 @@ dump_vtt (tree t, tree vtt)
       dump_array (stream, vtt);
       fprintf (stream, "\n");
     }
-
-  dump_end (TDI_class, stream);
 }
 
 /* Dump a function or thunk and its thunkees.  */
@@ -8026,10 +8390,10 @@ dump_thunk (FILE *stream, int indent, tree thunk)
        /*NOP*/;
       else if (DECL_THIS_THUNK_P (thunk))
        fprintf (stream, " vcall="  HOST_WIDE_INT_PRINT_DEC,
-                tree_low_cst (virtual_adjust, 0));
+                tree_to_shwi (virtual_adjust));
       else
        fprintf (stream, " vbase=" HOST_WIDE_INT_PRINT_DEC "(%s)",
-                tree_low_cst (BINFO_VPTR_FIELD (virtual_adjust), 0),
+                tree_to_shwi (BINFO_VPTR_FIELD (virtual_adjust)),
                 type_as_string (BINFO_TYPE (virtual_adjust), TFF_SCOPE));
       if (THUNK_ALIAS (thunk))
        fprintf (stream, " alias to %p", (void *)THUNK_ALIAS (thunk));
@@ -8356,6 +8720,12 @@ build_ctor_vtbl_group (tree binfo, tree t)
      construction vtable group.  */
   vtbl = build_vtable (t, id, ptr_type_node);
   DECL_CONSTRUCTION_VTABLE_P (vtbl) = 1;
+  /* Don't export construction vtables from shared libraries.  Even on
+     targets that don't support hidden visibility, this tells
+     can_refer_decl_in_current_unit_p not to assume that it's safe to
+     access from a different compilation unit (bz 54314).  */
+  DECL_VISIBILITY (vtbl) = VISIBILITY_HIDDEN;
+  DECL_VISIBILITY_SPECIFIED (vtbl) = true;
 
   v = NULL;
   accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
@@ -8723,7 +9093,7 @@ build_vtbl_initializer (tree binfo,
              if (!get_global_value_if_present (fn, &fn))
                fn = push_library_fn (fn, (build_function_type_list
                                           (void_type_node, NULL_TREE)),
-                                     NULL_TREE);
+                                     NULL_TREE, ECF_NORETURN);
              if (!TARGET_VTABLE_USES_DESCRIPTORS)
                init = fold_convert (vfunc_ptr_type_node,
                                     build_fold_addr_expr (fn));
@@ -8741,6 +9111,16 @@ build_vtbl_initializer (tree binfo,
              if (!TARGET_VTABLE_USES_DESCRIPTORS)
                init = fold_convert (vfunc_ptr_type_node,
                                     build_fold_addr_expr (fn));
+             /* Don't refer to a virtual destructor from a constructor
+                vtable or a vtable for an abstract class, since destroying
+                an object under construction is undefined behavior and we
+                don't want it to be considered a candidate for speculative
+                devirtualization.  But do create the thunk for ABI
+                compliance.  */
+             if (DECL_DESTRUCTOR_P (fn_original)
+                 && (CLASSTYPE_PURE_VIRTUALS (DECL_CONTEXT (fn_original))
+                     || orig_binfo != binfo))
+               init = size_zero_node;
            }
        }
 
@@ -8962,83 +9342,15 @@ static void
 add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
 {
   /* Make entries for the rest of the virtuals.  */
-  if (abi_version_at_least (2))
-    {
-      tree orig_fn;
-
-      /* The ABI requires that the methods be processed in declaration
-        order.  G++ 3.2 used the order in the vtable.  */
-      for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo));
-          orig_fn;
-          orig_fn = DECL_CHAIN (orig_fn))
-       if (DECL_VINDEX (orig_fn))
-         add_vcall_offset (orig_fn, binfo, vid);
-    }
-  else
-    {
-      tree derived_virtuals;
-      tree base_virtuals;
-      tree orig_virtuals;
-      /* If BINFO is a primary base, the most derived class which has
-        BINFO as a primary base; otherwise, just BINFO.  */
-      tree non_primary_binfo;
-
-      /* We might be a primary base class.  Go up the inheritance hierarchy
-        until we find the most derived class of which we are a primary base:
-        it is the BINFO_VIRTUALS there that we need to consider.  */
-      non_primary_binfo = binfo;
-      while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
-       {
-         tree b;
-
-         /* If we have reached a virtual base, then it must be vid->vbase,
-            because we ignore other virtual bases in
-            add_vcall_offset_vtbl_entries_r.  In turn, it must be a primary
-            base (possibly multi-level) of vid->binfo, or we wouldn't
-            have called build_vcall_and_vbase_vtbl_entries for it.  But it
-            might be a lost primary, so just skip down to vid->binfo.  */
-         if (BINFO_VIRTUAL_P (non_primary_binfo))
-           {
-             gcc_assert (non_primary_binfo == vid->vbase);
-             non_primary_binfo = vid->binfo;
-             break;
-           }
-
-         b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
-         if (get_primary_binfo (b) != non_primary_binfo)
-           break;
-         non_primary_binfo = b;
-       }
-
-      if (vid->ctor_vtbl_p)
-       /* For a ctor vtable we need the equivalent binfo within the hierarchy
-          where rtti_binfo is the most derived type.  */
-       non_primary_binfo
-         = original_binfo (non_primary_binfo, vid->rtti_binfo);
-
-      for (base_virtuals = BINFO_VIRTUALS (binfo),
-            derived_virtuals = BINFO_VIRTUALS (non_primary_binfo),
-            orig_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
-          base_virtuals;
-          base_virtuals = TREE_CHAIN (base_virtuals),
-            derived_virtuals = TREE_CHAIN (derived_virtuals),
-            orig_virtuals = TREE_CHAIN (orig_virtuals))
-       {
-         tree orig_fn;
-
-         /* Find the declaration that originally caused this function to
-            be present in BINFO_TYPE (binfo).  */
-         orig_fn = BV_FN (orig_virtuals);
-
-         /* When processing BINFO, we only want to generate vcall slots for
-            function slots introduced in BINFO.  So don't try to generate
-            one if the function isn't even defined in BINFO.  */
-         if (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), DECL_CONTEXT (orig_fn)))
-           continue;
+  tree orig_fn;
 
-         add_vcall_offset (orig_fn, binfo, vid);
-       }
-    }
+  /* The ABI requires that the methods be processed in declaration
+     order.  */
+  for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo));
+       orig_fn;
+       orig_fn = DECL_CHAIN (orig_fn))
+    if (TREE_CODE (orig_fn) == FUNCTION_DECL && DECL_VINDEX (orig_fn))
+      add_vcall_offset (orig_fn, binfo, vid);
 }
 
 /* Add a vcall offset entry for ORIG_FN to the vtable.  */
@@ -9179,4 +9491,30 @@ publicly_uniquely_derived_p (tree parent, tree type)
   return base && base != error_mark_node;
 }
 
+/* CTX1 and CTX2 are declaration contexts.  Return the innermost common
+   class between them, if any.  */
+
+tree
+common_enclosing_class (tree ctx1, tree ctx2)
+{
+  if (!TYPE_P (ctx1) || !TYPE_P (ctx2))
+    return NULL_TREE;
+  gcc_assert (ctx1 == TYPE_MAIN_VARIANT (ctx1)
+             && ctx2 == TYPE_MAIN_VARIANT (ctx2));
+  if (ctx1 == ctx2)
+    return ctx1;
+  for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
+    TYPE_MARKED_P (t) = true;
+  tree found = NULL_TREE;
+  for (tree t = ctx2; TYPE_P (t); t = TYPE_CONTEXT (t))
+    if (TYPE_MARKED_P (t))
+      {
+       found = t;
+       break;
+      }
+  for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
+    TYPE_MARKED_P (t) = false;
+  return found;
+}
+
 #include "gt-cp-class.h"