OSDN Git Service

* gcc.dg/tree-ssa/fre-vce-1.c: Cleanup "fre" tree dump.
[pf3gnuchains/gcc-fork.git] / gcc / cp / class.c
index 154c3b3..d86ff64 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions related to building classes and their related objects.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -284,7 +284,7 @@ build_base_path (enum tree_code code,
 
   if (!want_pointer)
     /* This must happen before the call to save_expr.  */
-    expr = build_unary_op (ADDR_EXPR, expr, 0);
+    expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error);
 
   offset = BINFO_OFFSET (binfo);
   fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
@@ -295,11 +295,11 @@ 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.  */
-  if (skip_evaluation)
+  if (cp_unevaluated_operand != 0)
     {
       expr = build_nop (build_pointer_type (target_type), expr);
       if (!want_pointer)
-       expr = build_indirect_ref (expr, NULL);
+       expr = build_indirect_ref (EXPR_LOCATION (expr), expr, NULL);
       return expr;
     }
 
@@ -345,7 +345,7 @@ build_base_path (enum tree_code code,
         interesting to the optimizers anyway.  */
       && !has_empty)
     {
-      expr = build_indirect_ref (expr, NULL);
+      expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
       expr = build_simple_base_path (expr, binfo);
       if (want_pointer)
        expr = build_address (expr);
@@ -370,10 +370,12 @@ build_base_path (enum tree_code code,
          t = TREE_TYPE (TYPE_VFIELD (current_class_type));
          t = build_pointer_type (t);
          v_offset = convert (t, current_vtt_parm);
-         v_offset = build_indirect_ref (v_offset, NULL);
+         v_offset = cp_build_indirect_ref (v_offset, NULL, 
+                                            tf_warning_or_error);
        }
       else
-       v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
+       v_offset = build_vfield_ref (cp_build_indirect_ref (expr, NULL,
+                                                            tf_warning_or_error),
                                     TREE_TYPE (TREE_TYPE (expr)));
 
       v_offset = build2 (POINTER_PLUS_EXPR, TREE_TYPE (v_offset),
@@ -381,9 +383,8 @@ build_base_path (enum tree_code code,
       v_offset = build1 (NOP_EXPR,
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
-      v_offset = build_indirect_ref (v_offset, NULL);
+      v_offset = cp_build_indirect_ref (v_offset, NULL, tf_warning_or_error);
       TREE_CONSTANT (v_offset) = 1;
-      TREE_INVARIANT (v_offset) = 1;
 
       offset = convert_to_integer (ptrdiff_type_node,
                                   size_diffop (offset,
@@ -425,7 +426,7 @@ build_base_path (enum tree_code code,
     null_test = NULL;
 
   if (!want_pointer)
-    expr = build_indirect_ref (expr, NULL);
+    expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
 
  out:
   if (null_test)
@@ -459,7 +460,7 @@ build_simple_base_path (tree expr, tree binfo)
         in the back end.  */
       temp = unary_complex_lvalue (ADDR_EXPR, expr);
       if (temp)
-       expr = build_indirect_ref (temp, NULL);
+       expr = cp_build_indirect_ref (temp, NULL, tf_warning_or_error);
 
       return expr;
     }
@@ -551,7 +552,8 @@ convert_to_base_statically (tree expr, tree base)
         when processing a template because they do not handle C++-specific
         trees.  */
       gcc_assert (!processing_template_decl);
-      expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1);
+      expr = cp_build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1, 
+                             tf_warning_or_error);
       if (!integer_zerop (BINFO_OFFSET (base)))
         expr = fold_build2 (POINTER_PLUS_EXPR, pointer_type, expr,
                            fold_convert (sizetype, BINFO_OFFSET (base)));
@@ -623,11 +625,9 @@ build_vtbl_ref_1 (tree instance, tree idx)
   if (!vtbl)
     vtbl = build_vfield_ref (instance, basetype);
 
-  assemble_external (vtbl);
 
-  aref = build_array_ref (vtbl, idx);
+  aref = build_array_ref (input_location, vtbl, idx);
   TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
-  TREE_INVARIANT (aref) = TREE_CONSTANT (aref);
 
   return aref;
 }
@@ -648,13 +648,16 @@ build_vfn_ref (tree instance_ptr, tree idx)
 {
   tree aref;
 
-  aref = build_vtbl_ref_1 (build_indirect_ref (instance_ptr, 0), idx);
+  aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, 0,
+                                                  tf_warning_or_error), 
+                           idx);
 
   /* When using function descriptors, the address of the
      vtable entry is treated as a function pointer.  */
   if (TARGET_VTABLE_USES_DESCRIPTORS)
     aref = build1 (NOP_EXPR, TREE_TYPE (aref),
-                  build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1));
+                  cp_build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1,
+                                   tf_warning_or_error));
 
   /* Remember this as a method reference, for later devirtualization.  */
   aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);
@@ -771,7 +774,7 @@ get_vtable_decl (tree type, int complete)
   if (complete)
     {
       DECL_EXTERNAL (decl) = 1;
-      finish_decl (decl, NULL_TREE, NULL_TREE);
+      cp_finish_decl (decl, NULL_TREE, false, NULL_TREE, 0);
     }
 
   return decl;
@@ -1435,16 +1438,17 @@ determine_primary_bases (tree t)
       BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary);
     }
 }
-\f
-/* Set memoizing fields and bits of T (and its variants) for later
-   use.  */
 
-static void
-finish_struct_bits (tree t)
+/* Update the variant types of T.  */
+
+void
+fixup_type_variants (tree t)
 {
   tree variants;
 
-  /* Fix up variants (if any).  */
+  if (!t)
+    return;
+
   for (variants = TYPE_NEXT_VARIANT (t);
        variants;
        variants = TYPE_NEXT_VARIANT (variants))
@@ -1468,6 +1472,17 @@ finish_struct_bits (tree t)
       /* All variants of a class have the same attributes.  */
       TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
     }
+}
+
+\f
+/* Set memoizing fields and bits of T (and its variants) for later
+   use.  */
+
+static void
+finish_struct_bits (tree t)
+{
+  /* Fix up variants (if any).  */
+  fixup_type_variants (t);
 
   if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
     /* For a class w/o baseclasses, 'finish_struct' has set
@@ -1490,7 +1505,7 @@ finish_struct_bits (tree t)
       DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
       for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
        {
-         TYPE_MODE (variants) = BLKmode;
+         SET_TYPE_MODE (variants, BLKmode);
          TREE_ADDRESSABLE (variants) = 1;
        }
     }
@@ -2493,10 +2508,10 @@ finish_struct_anon (tree t)
              if (TREE_CODE (elt) != FIELD_DECL)
                {
                  if (is_union)
-                   permerror ("%q+#D invalid; an anonymous union can "
+                   permerror (input_location, "%q+#D invalid; an anonymous union can "
                               "only have non-static data members", elt);
                  else
-                   permerror ("%q+#D invalid; an anonymous struct can "
+                   permerror (input_location, "%q+#D invalid; an anonymous struct can "
                               "only have non-static data members", elt);
                  continue;
                }
@@ -2504,16 +2519,16 @@ finish_struct_anon (tree t)
              if (TREE_PRIVATE (elt))
                {
                  if (is_union)
-                   permerror ("private member %q+#D in anonymous union", elt);
+                   permerror (input_location, "private member %q+#D in anonymous union", elt);
                  else
-                   permerror ("private member %q+#D in anonymous struct", elt);
+                   permerror (input_location, "private member %q+#D in anonymous struct", elt);
                }
              else if (TREE_PROTECTED (elt))
                {
                  if (is_union)
-                   permerror ("protected member %q+#D in anonymous union", elt);
+                   permerror (input_location, "protected member %q+#D in anonymous union", elt);
                  else
-                   permerror ("protected member %q+#D in anonymous struct", elt);
+                   permerror (input_location, "protected member %q+#D in anonymous struct", elt);
                }
 
              TREE_PRIVATE (elt) = TREE_PRIVATE (field);
@@ -2690,7 +2705,7 @@ check_bitfield_decl (tree field)
   DECL_INITIAL (field) = NULL_TREE;
 
   /* Detect invalid bit-field type.  */
-  if (!INTEGRAL_TYPE_P (type))
+  if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     {
       error ("bit-field %q+#D with non-integral type", field);
       w = error_mark_node;
@@ -2724,10 +2739,11 @@ check_bitfield_decl (tree field)
        warning (0, "width of %q+D exceeds its type", field);
       else if (TREE_CODE (type) == ENUMERAL_TYPE
               && (0 > compare_tree_int (w,
-                                        min_precision (TYPE_MIN_VALUE (type),
-                                                       TYPE_UNSIGNED (type)))
+                                        tree_int_cst_min_precision
+                                        (TYPE_MIN_VALUE (type),
+                                         TYPE_UNSIGNED (type)))
                   ||  0 > compare_tree_int (w,
-                                            min_precision
+                                            tree_int_cst_min_precision
                                             (TYPE_MAX_VALUE (type),
                                              TYPE_UNSIGNED (type)))))
        warning (0, "%q+D is too small to hold all values of %q#T", field, type);
@@ -2969,7 +2985,8 @@ check_field_decls (tree t, tree *access_decls,
                 x);
              cant_pack = 1;
            }
-         else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
+         else if (DECL_C_BIT_FIELD (x)
+                  || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
            DECL_PACKED (x) = 1;
        }
 
@@ -3041,10 +3058,10 @@ check_field_decls (tree t, tree *access_decls,
 
       /* Core issue 80: A nonstatic data member is required to have a
         different name from the class iff the class has a
-        user-defined constructor.  */
+        user-declared constructor.  */
       if (constructor_name_p (DECL_NAME (x), t)
          && TYPE_HAS_USER_CONSTRUCTOR (t))
-       permerror ("field %q+#D with same name as class", x);
+       permerror (input_location, "field %q+#D with same name as class", x);
 
       /* We set DECL_C_BIT_FIELD in grokbitfield.
         If the type and width are valid, we'll also set DECL_BIT_FIELD.  */
@@ -3619,7 +3636,8 @@ build_base_field (record_layout_info rli, tree binfo,
       CLASSTYPE_EMPTY_P (t) = 0;
 
       /* Create the FIELD_DECL.  */
-      decl = build_decl (FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
+      decl = build_decl (input_location,
+                        FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
       DECL_ARTIFICIAL (decl) = 1;
       DECL_IGNORED_P (decl) = 1;
       DECL_FIELD_CONTEXT (decl) = t;
@@ -3763,8 +3781,8 @@ check_methods (tree t)
          if (DECL_PURE_VIRTUAL_P (x))
            VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
        }
-      /* All user-declared destructors are non-trivial.  */
-      if (DECL_DESTRUCTOR_P (x))
+      /* All user-provided destructors are non-trivial.  */
+      if (DECL_DESTRUCTOR_P (x) && !DECL_DEFAULTED_FN (x))
        TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
     }
 }
@@ -4054,13 +4072,105 @@ type_has_user_nondefault_constructor (tree t)
     {
       tree fn = OVL_CURRENT (fns);
       if (!DECL_ARTIFICIAL (fn)
-         && skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn)) != NULL_TREE)
+         && (TREE_CODE (fn) == TEMPLATE_DECL
+             || (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn))
+                 != NULL_TREE)))
        return true;
     }
 
   return false;
 }
 
+/* Returns true iff FN is a user-provided function, i.e. user-declared
+   and not defaulted at its first declaration.  */
+
+static bool
+user_provided_p (tree fn)
+{
+  if (TREE_CODE (fn) == TEMPLATE_DECL)
+    return true;
+  else
+    return (!DECL_ARTIFICIAL (fn)
+           && !(DECL_DEFAULTED_FN (fn)
+                && DECL_INITIALIZED_IN_CLASS_P (fn)));
+}
+
+/* Returns true iff class T has a user-provided constructor.  */
+
+bool
+type_has_user_provided_constructor (tree t)
+{
+  tree fns;
+
+  if (!CLASS_TYPE_P (t))
+    return false;
+
+  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+    return false;
+
+  /* This can happen in error cases; avoid crashing.  */
+  if (!CLASSTYPE_METHOD_VEC (t))
+    return false;
+
+  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+    if (user_provided_p (OVL_CURRENT (fns)))
+      return true;
+
+  return false;
+}
+
+/* Returns true iff class T has a user-provided default constructor.  */
+
+bool
+type_has_user_provided_default_constructor (tree t)
+{
+  tree fns, args;
+
+  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+    return false;
+
+  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))
+       {
+         args = FUNCTION_FIRST_USER_PARMTYPE (fn);
+         while (args && TREE_PURPOSE (args))
+           args = TREE_CHAIN (args);
+         if (!args || args == void_list_node)
+           return true;
+       }
+    }
+
+  return false;
+}
+
+/* Returns true if FN can be explicitly defaulted.  */
+
+bool
+defaultable_fn_p (tree fn)
+{
+  if (DECL_CONSTRUCTOR_P (fn))
+    {
+      if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
+       return true;
+      else if (copy_fn_p (fn) > 0
+              && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
+                  == void_list_node))
+       return true;
+      else
+       return false;
+    }
+  else if (DECL_DESTRUCTOR_P (fn))
+    return true;
+  else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
+          && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR)
+    return copy_fn_p (fn);
+  else
+    return false;
+}
+
 /* Remove all zero-width bit-fields from T.  */
 
 static void
@@ -4121,6 +4231,10 @@ type_requires_array_cookie (tree type)
       second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
       if (second_parm == void_list_node)
        return false;
+      /* Do not consider this function if its second argument is an
+        ellipsis.  */
+      if (!second_parm)
+       continue;
       /* Otherwise, if we have a two-argument function and the second
         argument is `size_t', it will be the usual deallocation
         function -- unless there is one-argument function, too.  */
@@ -4148,6 +4262,8 @@ check_bases_and_members (tree t)
      should take a non-const reference argument.  */
   int no_const_asn_ref;
   tree access_decls;
+  bool saved_complex_asn_ref;
+  bool saved_nontrivial_dtor;
 
   /* By default, we use const reference arguments and generate default
      constructors.  */
@@ -4161,6 +4277,12 @@ check_bases_and_members (tree t)
   /* Check all the method declarations.  */
   check_methods (t);
 
+  /* Save the initial values of these flags which only indicate whether
+     or not the class has user-provided functions.  As we analyze the
+     bases and members we can set these flags for other reasons.  */
+  saved_complex_asn_ref = TYPE_HAS_COMPLEX_ASSIGN_REF (t);
+  saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
+
   /* Check all the data member declarations.  We cannot call
      check_field_decls until we have called check_bases check_methods,
      as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR
@@ -4176,37 +4298,33 @@ check_bases_and_members (tree t)
 
   /* Do some bookkeeping that will guide the generation of implicitly
      declared member functions.  */
-  TYPE_HAS_COMPLEX_INIT_REF (t)
-    |= (TYPE_HAS_INIT_REF (t) || TYPE_CONTAINS_VPTR_P (t));
+  TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_CONTAINS_VPTR_P (t);
   /* We need to call a constructor for this class if it has a
-     user-declared constructor, or if the default constructor is going
+     user-provided constructor, or if the default constructor is going
      to initialize the vptr.  (This is not an if-and-only-if;
      TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members
      themselves need constructing.)  */
   TYPE_NEEDS_CONSTRUCTING (t)
-    |= (TYPE_HAS_USER_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
+    |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t));
   /* [dcl.init.aggr]
 
-     An aggregate is an arry or a class with no user-declared
+     An aggregate is an array or a class with no user-provided
      constructors ... and no virtual functions.  
 
      Again, other conditions for being an aggregate are checked
      elsewhere.  */
   CLASSTYPE_NON_AGGREGATE (t)
-    |= (TYPE_HAS_USER_CONSTRUCTOR (t) || TYPE_POLYMORPHIC_P (t));
+    |= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t));
   CLASSTYPE_NON_POD_P (t)
     |= (CLASSTYPE_NON_AGGREGATE (t)
-       || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
-       || TYPE_HAS_ASSIGN_REF (t));
-  TYPE_HAS_COMPLEX_ASSIGN_REF (t)
-    |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
-  TYPE_HAS_COMPLEX_DFLT (t)
-    |= (TYPE_HAS_DEFAULT_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
+       || saved_nontrivial_dtor || saved_complex_asn_ref);
+  TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_CONTAINS_VPTR_P (t);
+  TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
 
   /* 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.  */
-  if (extra_warnings
+  if (warn_uninitialized
       /* Classes with user-declared constructors are presumed to
         initialize these members.  */
       && !TYPE_HAS_USER_CONSTRUCTOR (t)
@@ -4225,13 +4343,13 @@ check_bases_and_members (tree t)
 
          type = TREE_TYPE (field);
          if (TREE_CODE (type) == REFERENCE_TYPE)
-           warning (OPT_Wextra, "non-static reference %q+#D in class "
-                    "without a constructor", field);
+           warning (OPT_Wuninitialized, "non-static reference %q+#D "
+                    "in class without a constructor", field);
          else if (CP_TYPE_CONST_P (type)
                   && (!CLASS_TYPE_P (type)
                       || !TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
-           warning (OPT_Wextra, "non-static const member %q+#D in class "
-                    "without a constructor", field);
+           warning (OPT_Wuninitialized, "non-static const member %q+#D "
+                    "in class without a constructor", field);
        }
     }
 
@@ -4311,7 +4429,8 @@ create_vtable_ptr (tree t, tree* virtuals_p)
         stores cannot alias stores to void*!  */
       tree field;
 
-      field = build_decl (FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
+      field = build_decl (input_location, 
+                         FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
       DECL_VIRTUAL_P (field) = 1;
       DECL_ARTIFICIAL (field) = 1;
       DECL_FIELD_CONTEXT (field) = t;
@@ -4747,7 +4866,7 @@ layout_class_type (tree t, tree *virtuals_p)
       if (DECL_C_BIT_FIELD (field)
          && INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
        {
-         integer_type_kind itk;
+         unsigned int itk;
          tree integer_type;
          bool was_unnamed_p = false;
          /* We must allocate the bits as if suitably aligned for the
@@ -4891,7 +5010,8 @@ layout_class_type (tree t, tree *virtuals_p)
        {
          tree padding_field;
 
-         padding_field = build_decl (FIELD_DECL,
+         padding_field = build_decl (input_location,
+                                     FIELD_DECL,
                                      NULL_TREE,
                                      char_type_node);
          DECL_BIT_FIELD (padding_field) = 1;
@@ -4979,7 +5099,8 @@ layout_class_type (tree t, tree *virtuals_p)
       for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
        if (TREE_CODE (field) == FIELD_DECL)
          {
-           *next_field = build_decl (FIELD_DECL,
+           *next_field = build_decl (input_location,
+                                     FIELD_DECL,
                                      DECL_NAME (field),
                                      TREE_TYPE (field));
            DECL_CONTEXT (*next_field) = base_t;
@@ -5020,7 +5141,8 @@ layout_class_type (tree t, tree *virtuals_p)
   /* Make sure not to create any structures with zero size.  */
   if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
     place_field (rli,
-                build_decl (FIELD_DECL, NULL_TREE, char_type_node));
+                build_decl (input_location,
+                            FIELD_DECL, NULL_TREE, char_type_node));
 
   /* Let the back end lay out the type.  */
   finish_record_layout (rli, /*free_p=*/true);
@@ -5405,8 +5527,7 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
 
       return NULL_TREE;
 
-    case NOP_EXPR:
-    case CONVERT_EXPR:
+    CASE_CONVERT:
       return RECUR (TREE_OPERAND (instance, 0));
 
     case ADDR_EXPR:
@@ -5682,6 +5803,9 @@ currently_open_class (tree t)
 {
   int i;
 
+  if (!CLASS_TYPE_P (t))
+    return false;
+
   /* We start looking from 1 because entry 0 is from global scope,
      and has no type.  */
   for (i = current_class_depth; i > 0; --i)
@@ -5824,9 +5948,13 @@ pop_lang_context (void)
    control of FLAGS.  Permit pointers to member function if FLAGS
    permits.  If TEMPLATE_ONLY, the name of the overloaded function was
    a template-id, and EXPLICIT_TARGS are the explicitly provided
-   template arguments.  If OVERLOAD is for one or more member
-   functions, then ACCESS_PATH is the base path used to reference
-   those member functions.  */
+   template arguments.  
+
+   If OVERLOAD is for one or more member functions, then ACCESS_PATH
+   is the base path used to reference those member functions.  If
+   TF_NO_ACCESS_CONTROL is not set in FLAGS, and the address is
+   resolved to a member function, access checks will be performed and
+   errors issued if appropriate.  */
 
 static tree
 resolve_address_of_overloaded_function (tree target_type,
@@ -5949,6 +6077,9 @@ resolve_address_of_overloaded_function (tree target_type,
       tree target_arg_types;
       tree target_ret_type;
       tree fns;
+      tree *args;
+      unsigned int nargs, ia;
+      tree arg;
 
       if (is_ptrmem)
        target_fn_type
@@ -5962,6 +6093,14 @@ resolve_address_of_overloaded_function (tree target_type,
       if (TREE_CODE (target_fn_type) == METHOD_TYPE)
        target_arg_types = TREE_CHAIN (target_arg_types);
 
+      nargs = list_length (target_arg_types);
+      args = XALLOCAVEC (tree, nargs);
+      for (arg = target_arg_types, ia = 0;
+          arg != NULL_TREE && arg != void_list_node;
+          arg = TREE_CHAIN (arg), ++ia)
+       args[ia] = TREE_VALUE (arg);
+      nargs = ia;
+
       for (fns = overload; fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
@@ -5981,9 +6120,9 @@ resolve_address_of_overloaded_function (tree target_type,
 
          /* Try to do argument deduction.  */
          targs = make_tree_vec (DECL_NTPARMS (fn));
-         if (fn_type_unification (fn, explicit_targs, targs,
-                                  target_arg_types, target_ret_type,
-                                  DEDUCE_EXACT, LOOKUP_NORMAL))
+         if (fn_type_unification (fn, explicit_targs, targs, args, nargs,
+                                  target_ret_type, DEDUCE_EXACT,
+                                  LOOKUP_NORMAL))
            /* Argument deduction failed.  */
            continue;
 
@@ -6024,7 +6163,7 @@ resolve_address_of_overloaded_function (tree target_type,
       if (flags & tf_error)
        {
          error ("no matches converting function %qD to type %q#T",
-                DECL_NAME (OVL_FUNCTION (overload)),
+                DECL_NAME (OVL_CURRENT (overload)),
                 target_type);
 
          /* print_candidates expects a chain with the functions in
@@ -6040,25 +6179,33 @@ resolve_address_of_overloaded_function (tree target_type,
     }
   else if (TREE_CHAIN (matches))
     {
-      /* There were too many matches.  */
+      /* There were too many matches.  First check if they're all
+        the same function.  */
+      tree match;
 
-      if (flags & tf_error)
+      fn = TREE_PURPOSE (matches);
+      for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
+       if (!decls_match (fn, TREE_PURPOSE (matches)))
+         break;
+
+      if (match)
        {
-         tree match;
+         if (flags & tf_error)
+           {
+             error ("converting overloaded function %qD to type %q#T is ambiguous",
+                    DECL_NAME (OVL_FUNCTION (overload)),
+                    target_type);
 
-         error ("converting overloaded function %qD to type %q#T is ambiguous",
-                   DECL_NAME (OVL_FUNCTION (overload)),
-                   target_type);
+             /* Since print_candidates expects the functions in the
+                TREE_VALUE slot, we flip them here.  */
+             for (match = matches; match; match = TREE_CHAIN (match))
+               TREE_VALUE (match) = TREE_PURPOSE (match);
 
-         /* Since print_candidates expects the functions in the
-            TREE_VALUE slot, we flip them here.  */
-         for (match = matches; match; match = TREE_CHAIN (match))
-           TREE_VALUE (match) = TREE_PURPOSE (match);
+             print_candidates (matches);
+           }
 
-         print_candidates (matches);
+         return error_mark_node;
        }
-
-      return error_mark_node;
     }
 
   /* Good, exactly one match.  Now, convert it to the correct type.  */
@@ -6072,10 +6219,10 @@ resolve_address_of_overloaded_function (tree target_type,
       if (!(flags & tf_error))
        return error_mark_node;
 
-      permerror ("assuming pointer to member %qD", fn);
+      permerror (input_location, "assuming pointer to member %qD", fn);
       if (!explained)
        {
-         inform ("(a pointer to member can only be formed with %<&%E%>)", fn);
+         inform (input_location, "(a pointer to member can only be formed with %<&%E%>)", fn);
          explained = 1;
        }
     }
@@ -6086,22 +6233,28 @@ resolve_address_of_overloaded_function (tree target_type,
      function will be marked as used at this point.  */
   if (!(flags & tf_conv))
     {
+      /* Make =delete work with SFINAE.  */
+      if (DECL_DELETED_FN (fn) && !(flags & tf_error))
+       return error_mark_node;
+      
       mark_used (fn);
-      /* We could not check access when this expression was originally
-        created since we did not know at that time to which function
-        the expression referred.  */
-      if (DECL_FUNCTION_MEMBER_P (fn))
-       {
-         gcc_assert (access_path);
-         perform_or_defer_access_check (access_path, fn, fn);
-       }
+    }
+
+  /* We could not check access to member functions when this
+     expression was originally created since we did not know at that
+     time to which function the expression referred.  */
+  if (!(flags & tf_no_access_control) 
+      && DECL_FUNCTION_MEMBER_P (fn))
+    {
+      gcc_assert (access_path);
+      perform_or_defer_access_check (access_path, fn, fn);
     }
 
   if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
-    return build_unary_op (ADDR_EXPR, fn, 0);
+    return cp_build_unary_op (ADDR_EXPR, fn, 0, flags);
   else
     {
-      /* The target must be a REFERENCE_TYPE.  Above, build_unary_op
+      /* The target must be a REFERENCE_TYPE.  Above, cp_build_unary_op
         will mark the function as addressed, but here we must do it
         explicitly.  */
       cxx_mark_addressable (fn);
@@ -6173,13 +6326,8 @@ 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
-             || TREE_CODE (rhs) == COMPOUND_EXPR
-             || really_overloaded_fn (rhs));
-
-  /* We don't overwrite rhs if it is an overloaded function.
-     Copying it would destroy the tree link.  */
-  if (TREE_CODE (rhs) != OVERLOAD)
-    rhs = copy_node (rhs);
+             || really_overloaded_fn (rhs)
+             || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));
 
   /* This should really only be used when attempting to distinguish
      what sort of a pointer to function we have.  For now, any
@@ -6231,19 +6379,6 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
                                                /*explicit_targs=*/NULL_TREE,
                                                access_path);
 
-    case COMPOUND_EXPR:
-      TREE_OPERAND (rhs, 0)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
-      if (TREE_OPERAND (rhs, 0) == error_mark_node)
-       return error_mark_node;
-      TREE_OPERAND (rhs, 1)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
-      if (TREE_OPERAND (rhs, 1) == error_mark_node)
-       return error_mark_node;
-
-      TREE_TYPE (rhs) = lhstype;
-      return rhs;
-
     case ADDR_EXPR:
     {
       if (PTRMEM_OK_P (rhs))
@@ -6343,7 +6478,7 @@ is_empty_class (tree type)
   if (type == error_mark_node)
     return 0;
 
-  if (! MAYBE_CLASS_TYPE_P (type))
+  if (! CLASS_TYPE_P (type))
     return 0;
 
   /* In G++ 3.2, whether or not a class was empty was determined by
@@ -6383,6 +6518,37 @@ contains_empty_class_p (tree type)
   return false;
 }
 
+/* Returns true if TYPE contains no actual data, just various
+   possible combinations of empty classes.  */
+
+bool
+is_really_empty_class (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 (!is_really_empty_class (BINFO_TYPE (base_binfo)))
+         return false;
+      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+       if (TREE_CODE (field) == FIELD_DECL
+           && !DECL_ARTIFICIAL (field)
+           && !is_really_empty_class (TREE_TYPE (field)))
+         return false;
+      return true;
+    }
+  else if (TREE_CODE (type) == ARRAY_TYPE)
+    return is_really_empty_class (TREE_TYPE (type));
+  return false;
+}
+
 /* Note that NAME was looked up while the current class was being
    defined and that the result of that lookup was DECL.  */
 
@@ -6435,8 +6601,8 @@ note_name_declared_in_class (tree name, tree decl)
         A name N used in a class S shall refer to the same declaration
         in its context and when re-evaluated in the completed scope of
         S.  */
-      permerror ("declaration of %q#D", decl);
-      permerror ("changes meaning of %qD from %q+#D",
+      permerror (input_location, "declaration of %q#D", decl);
+      permerror (input_location, "changes meaning of %qD from %q+#D",
               DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
     }
 }
@@ -7377,7 +7543,7 @@ build_vtbl_initializer (tree binfo,
 
         We first check this in update_vtable_entry_for_fn, so we handle
         restored primary bases properly; we also need to do it here so we
-        zero out unused slots in ctor vtables, rather than filling themff
+        zero out unused slots in ctor vtables, rather than filling them
         with erroneous values (though harmless, apart from relocation
         costs).  */
       for (b = binfo; ; b = get_primary_binfo (b))
@@ -7442,7 +7608,6 @@ build_vtbl_initializer (tree binfo,
                                     TREE_OPERAND (init, 0),
                                     build_int_cst (NULL_TREE, i));
                TREE_CONSTANT (fdesc) = 1;
-               TREE_INVARIANT (fdesc) = 1;
 
                vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits);
              }