OSDN Git Service

* diagnostic.c (warning): Accept parameter to classify warning option.
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 4eeb5e5..e40e61f 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions related to invoking methods and overloaded functions.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 
-   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) and
    modified by Brendan Kehoe (brendan@cygnus.com).
 
@@ -92,6 +92,9 @@ struct conversion {
      copy constructor must be accessible, even though it is not being
      used.  */
   BOOL_BITFIELD check_copy_constructor_p : 1;
+  /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion
+     from a pointer-to-derived to pointer-to-base is being performed.  */ 
+  BOOL_BITFIELD base_p : 1;
   /* The type of the expression resulting from the conversion.  */
   tree type;
   union {
@@ -125,12 +128,15 @@ static int compare_ics (conversion *, conversion *);
 static tree build_over_call (struct z_candidate *, int);
 static tree build_java_interface_fn_ref (tree, tree);
 #define convert_like(CONV, EXPR)                               \
-  convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0,          \
-                    /*issue_conversion_warnings=*/true)
+  convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0,          \
+                    /*issue_conversion_warnings=*/true,        \
+                    /*c_cast_p=*/false)
 #define convert_like_with_context(CONV, EXPR, FN, ARGNO)       \
-  convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0,                 \
-                    /*issue_conversion_warnings=*/true)
-static tree convert_like_real (conversion *, tree, tree, int, int, bool);
+  convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0,         \
+                    /*issue_conversion_warnings=*/true,        \
+                     /*c_cast_p=*/false)
+static tree convert_like_real (conversion *, tree, tree, int, int, bool,
+                              bool);
 static void op_error (enum tree_code, enum tree_code, tree, tree,
                            tree, const char *);
 static tree build_object_call (tree, tree);
@@ -164,7 +170,7 @@ static struct z_candidate *add_conv_candidate
 static struct z_candidate *add_function_candidate 
        (struct z_candidate **, tree, tree, tree, tree, tree, int);
 static conversion *implicit_conversion (tree, tree, tree, int);
-static conversion *standard_conversion (tree, tree, tree);
+static conversion *standard_conversion (tree, tree, tree, int);
 static conversion *reference_binding (tree, tree, tree, int);
 static conversion *build_conv (conversion_kind, tree, conversion *);
 static bool is_subseq (conversion *, conversion *);
@@ -182,29 +188,14 @@ static conversion *direct_reference_binding (tree, conversion *);
 static bool promoted_arithmetic_type_p (tree);
 static conversion *conditional_conversion (tree, tree);
 static char *name_as_c_string (tree, tree, bool *);
-static tree call_builtin_trap (tree);
+static tree call_builtin_trap (void);
 static tree prep_operand (tree);
 static void add_candidates (tree, tree, tree, bool, tree, tree,
                            int, struct z_candidate **);
 static conversion *merge_conversion_sequences (conversion *, conversion *);
 static bool magic_varargs_p (tree);
-
-tree
-build_vfield_ref (tree datum, tree type)
-{
-  if (datum == error_mark_node)
-    return error_mark_node;
-
-  if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE)
-    datum = convert_from_reference (datum);
-
-  if (TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
-      && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
-    datum = convert_to_base (datum, type, /*check_access=*/false);
-
-  return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
-               datum, TYPE_VFIELD (type));
-}
+static tree build_temp (tree, tree, int, void (**)(const char *, ...));
+static void check_constructor_callable (tree, tree);
 
 /* Returns nonzero iff the destructor name specified in NAME
    (a BIT_NOT_EXPR) matches BASETYPE.  The operand of NAME can take many
@@ -232,17 +223,18 @@ check_dtor_name (tree basetype, tree name)
       else
        name = get_type_value (name);
     }
-  /* In the case of:
-      
-       template <class T> struct S { ~S(); };
-       int i;
-       i.~S();
-
-     NAME will be a class template.  */
-  else if (DECL_CLASS_TEMPLATE_P (name))
-    return false;
   else
-    abort ();
+    {
+      /* In the case of:
+               
+        template <class T> struct S { ~S(); };
+        int i;
+                i.~S();
+         
+        NAME will be a class template.  */
+      gcc_assert (DECL_CLASS_TEMPLATE_P (name));
+      return false;
+    }
 
   if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name))
     return true;
@@ -326,11 +318,10 @@ build_call (tree function, tree parms)
       /* We invoke build_call directly for several library functions.
         These may have been declared normally if we're building libgcc,
         so we can't just check DECL_ARTIFICIAL.  */
-      if (DECL_ARTIFICIAL (decl)
-         || !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "__", 2))
-       mark_used (decl);
-      else
-       abort ();
+      gcc_assert (DECL_ARTIFICIAL (decl)
+                 || !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)),
+                              "__", 2));
+      mark_used (decl);
     }
 
   /* Don't pass empty class objects by value.  This is useful
@@ -341,12 +332,12 @@ build_call (tree function, tree parms)
       if (is_empty_class (TREE_TYPE (TREE_VALUE (tmp)))
          && ! TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (tmp))))
        {
-         tree t = build (EMPTY_CLASS_EXPR, TREE_TYPE (TREE_VALUE (tmp)));
-         TREE_VALUE (tmp) = build (COMPOUND_EXPR, TREE_TYPE (t),
-                                   TREE_VALUE (tmp), t);
+         tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (TREE_VALUE (tmp)));
+         TREE_VALUE (tmp) = build2 (COMPOUND_EXPR, TREE_TYPE (t),
+                                    TREE_VALUE (tmp), t);
        }
 
-  function = build (CALL_EXPR, result_type, function, parms);
+  function = build3 (CALL_EXPR, result_type, function, parms, NULL_TREE);
   TREE_HAS_CONSTRUCTOR (function) = is_constructor;
   TREE_NOTHROW (function) = nothrow;
   
@@ -422,11 +413,14 @@ struct z_candidate {
      the `this' pointer must correspond to the most derived class
      indicated by the CONVERSION_PATH.  */
   tree conversion_path;
-  tree template;
+  tree template_decl;
   candidate_warning *warnings;
   z_candidate *next;
 };
 
+/* Returns true iff T is a null pointer constant in the sense of
+   [conv.ptr].  */
+
 bool
 null_ptr_cst_p (tree t)
 {
@@ -434,13 +428,13 @@ null_ptr_cst_p (tree t)
 
      A null pointer constant is an integral constant expression
      (_expr.const_) rvalue of integer type that evaluates to zero.  */
+  t = integral_constant_value (t);
   if (t == null_node
       || (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t)))
     return true;
   return false;
 }
 
-
 /* Returns nonzero if PARMLIST consists of only default parms and/or
    ellipsis.  */
 
@@ -491,9 +485,8 @@ void
 validate_conversion_obstack (void)
 {
   if (conversion_obstack_initialized)
-    my_friendly_assert ((obstack_next_free (&conversion_obstack) 
-                        == obstack_base (&conversion_obstack)),
-                       20040208);
+    gcc_assert ((obstack_next_free (&conversion_obstack) 
+                == obstack_base (&conversion_obstack)));
 }
 
 #endif /* ENABLE_CHECKING */
@@ -540,12 +533,12 @@ build_conv (conversion_kind code, tree type, conversion *from)
   t->rank = rank;
   t->user_conv_p = (code == ck_user || from->user_conv_p);
   t->bad_p = from->bad_p;
+  t->base_p = false;
   return t;
 }
 
 /* Build a representation of the identity conversion from EXPR to
-   itself.  The TYPE should match the the type of EXPR, if EXPR is
-   non-NULL.  */
+   itself.  The TYPE should match the type of EXPR, if EXPR is non-NULL.  */
 
 static conversion *
 build_identity_conv (tree type, tree expr)
@@ -588,7 +581,7 @@ strip_top_quals (tree t)
    also pass the expression EXPR to convert from.  */
 
 static conversion *
-standard_conversion (tree to, tree from, tree expr)
+standard_conversion (tree to, tree from, tree expr, int flags)
 {
   enum tree_code fcode, tcode;
   conversion *conv;
@@ -638,7 +631,7 @@ standard_conversion (tree to, tree from, tree expr)
          the standard conversion sequence to perform componentwise
          conversion.  */
       conversion *part_conv = standard_conversion
-        (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE);
+        (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, flags);
       
       if (part_conv)
         {
@@ -657,12 +650,6 @@ standard_conversion (tree to, tree from, tree expr)
   if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to))
       && expr && null_ptr_cst_p (expr))
     conv = build_conv (ck_std, to, conv);
-  else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
-          && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
-          && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
-          && ((*targetm.vector_opaque_p) (TREE_TYPE (to))
-              || (*targetm.vector_opaque_p) (TREE_TYPE (from))))
-    conv = build_conv (ck_std, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
           || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
     {
@@ -711,6 +698,8 @@ standard_conversion (tree to, tree from, tree expr)
                                        TYPE_PTRMEM_POINTED_TO_TYPE (from));
              conv = build_conv (ck_pmem, from, conv);
            }
+         else if (!same_type_p (fbase, tbase))
+           return NULL;
        }
       else if (IS_AGGR_TYPE (TREE_TYPE (from))
               && IS_AGGR_TYPE (TREE_TYPE (to))
@@ -722,9 +711,9 @@ standard_conversion (tree to, tree from, tree expr)
                  _class.derived_) of D.  If B is an inaccessible
                  (clause _class.access_) or ambiguous
                  (_class.member.lookup_) base class of D, a program
-                 that necessitates this conversion is ill-formed.  */
-              /* Therefore, we use DERIVED_FROM_P, and not
-                 ACCESSIBLY_UNIQUELY_DERIVED_FROM_P, in this test.  */
+                 that necessitates this conversion is ill-formed.
+                 Therefore, we use DERIVED_FROM_P, and do not check
+                 access or uniqueness.  */
               && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
        {
          from = 
@@ -732,6 +721,7 @@ standard_conversion (tree to, tree from, tree expr)
                                     cp_type_quals (TREE_TYPE (from)));
          from = build_pointer_type (from);
          conv = build_conv (ck_ptr, from, conv);
+         conv->base_p = true;
        }
 
       if (tcode == POINTER_TYPE)
@@ -782,6 +772,7 @@ standard_conversion (tree to, tree from, tree expr)
                                         TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
       from = build_ptrmemfunc_type (build_pointer_type (from));
       conv = build_conv (ck_pmem, from, conv);
+      conv->base_p = true;
     }
   else if (tcode == BOOLEAN_TYPE)
     {
@@ -820,10 +811,10 @@ standard_conversion (tree to, tree from, tree expr)
        conv->rank = cr_promotion;
     }
   else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (from)
-         || (*targetm.vector_opaque_p) (to)))
+          && vector_types_convertible_p (from, to))
     return build_conv (ck_std, to, conv);
-  else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
+  else if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE)
+          && IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
           && is_properly_derived_from (from, to))
     {
       if (conv->kind == ck_rvalue)
@@ -913,8 +904,7 @@ convert_class_to_reference (tree t, tree s, tree expr)
      error messages, which we should not issue now because we are just
      trying to find a conversion operator.  Therefore, we use NULL,
      cast to the appropriate type.  */
-  arglist = build_int_2 (0, 0);
-  TREE_TYPE (arglist) = build_pointer_type (s);
+  arglist = build_int_cst (build_pointer_type (s), 0);
   arglist = build_tree_list (NULL_TREE, arglist);
 
   reference_type = build_reference_type (t);
@@ -1028,8 +1018,8 @@ direct_reference_binding (tree type, conversion *conv)
 {
   tree t;
 
-  my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 20030306);
-  my_friendly_assert (TREE_CODE (conv->type) != REFERENCE_TYPE, 20030306);
+  gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+  gcc_assert (TREE_CODE (conv->type) != REFERENCE_TYPE);
 
   t = TREE_TYPE (type);
 
@@ -1192,7 +1182,8 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
     {
       conv = build_identity_conv (from, expr);
       conv = direct_reference_binding (rto, conv);
-      conv->u.next->check_copy_constructor_p = true;
+      if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE))
+       conv->u.next->check_copy_constructor_p = true;
       return conv;
     }
 
@@ -1235,7 +1226,7 @@ implicit_conversion (tree to, tree from, tree expr, int flags)
   if (TREE_CODE (to) == REFERENCE_TYPE)
     conv = reference_binding (to, from, expr, flags);
   else
-    conv = standard_conversion (to, from, expr);
+    conv = standard_conversion (to, from, expr, flags);
 
   if (conv)
     return conv;
@@ -1910,7 +1901,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
          return;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
       type1 = build_reference_type (type1);
       break;
@@ -1947,7 +1938,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   /* If we're dealing with two pointer types or two enumeral types,
@@ -2191,12 +2182,12 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
 
   if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
        || DECL_BASE_CONSTRUCTOR_P (tmpl))
-      && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (tmpl)))
+      && CLASSTYPE_VBASECLASSES (DECL_CONTEXT (tmpl)))
     args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
 
   i = fn_type_unification (tmpl, explicit_targs, targs,
                           args_without_in_chrg,
-                          return_type, strict, -1);
+                          return_type, strict);
 
   if (i != 0)
     return NULL;
@@ -2261,9 +2252,9 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
        for this will point at template <class T> template <> S<T>::f(int),
        so that we can find the definition.  For the purposes of
        overload resolution, however, we want the original TMPL.  */
-    cand->template = tree_cons (tmpl, targs, NULL_TREE);
+    cand->template_decl = tree_cons (tmpl, targs, NULL_TREE);
   else
-    cand->template = DECL_TEMPLATE_INFO (fn);
+    cand->template_decl = DECL_TEMPLATE_INFO (fn);
 
   return cand;
 }
@@ -2341,10 +2332,18 @@ any_strictly_viable (struct z_candidate *cands)
   return false;
 }
 
+/* OBJ is being used in an expression like "OBJ.f (...)".  In other
+   words, it is about to become the "this" pointer for a member
+   function call.  Take the address of the object.  */
+
 static tree
 build_this (tree obj)
 {
-  /* Fix this to work on non-lvalues.  */
+  /* In a template, we are only concerned about the type of the
+     expression, so we can take a shortcut.  */
+  if (processing_template_decl)
+    return build_address (obj);
+
   return build_unary_op (ADDR_EXPR, obj, 0);
 }
 
@@ -2450,7 +2449,7 @@ print_z_candidates (struct z_candidate *candidates)
 /* USER_SEQ is a user-defined conversion sequence, beginning with a
    USER_CONV.  STD_SEQ is the standard conversion sequence applied to
    the result of the conversion function to convert it to the final
-   desired type.  Merge the the two sequences into a single sequence,
+   desired type.  Merge the two sequences into a single sequence,
    and return the merged sequence.  */
 
 static conversion *
@@ -2458,7 +2457,7 @@ merge_conversion_sequences (conversion *user_seq, conversion *std_seq)
 {
   conversion **t;
 
-  my_friendly_assert (user_seq->kind == ck_user, 20030306);
+  gcc_assert (user_seq->kind == ck_user);
 
   /* Find the end of the second conversion sequence.  */
   t = &(std_seq); 
@@ -2495,13 +2494,11 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
   /* We represent conversion within a hierarchy using RVALUE_CONV and
      BASE_CONV, as specified by [over.best.ics]; these become plain
      constructor calls, as specified in [dcl.init].  */
-  my_friendly_assert (!IS_AGGR_TYPE (fromtype) || !IS_AGGR_TYPE (totype)
-                     || !DERIVED_FROM_P (totype, fromtype), 20011226);
+  gcc_assert (!IS_AGGR_TYPE (fromtype) || !IS_AGGR_TYPE (totype)
+             || !DERIVED_FROM_P (totype, fromtype));
 
   if (IS_AGGR_TYPE (totype))
-    ctors = lookup_fnfields (TYPE_BINFO (totype),
-                            complete_ctor_identifier,
-                            0);
+    ctors = lookup_fnfields (totype, complete_ctor_identifier, 0);
 
   if (IS_AGGR_TYPE (fromtype))
     conv_fns = lookup_conversions (fromtype);
@@ -2515,14 +2512,12 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
 
       ctors = BASELINK_FUNCTIONS (ctors);
 
-      t = build_int_2 (0, 0);
-      TREE_TYPE (t) = build_pointer_type (totype);
+      t = build_int_cst (build_pointer_type (totype), 0);
       args = build_tree_list (NULL_TREE, expr);
       /* We should never try to call the abstract or base constructor
         from here.  */
-      my_friendly_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
-                         && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)),
-                         20011226);
+      gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
+                 && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)));
       args = tree_cons (NULL_TREE, t, args);
     }
   for (; ctors; ctors = OVL_NEXT (ctors))
@@ -2616,7 +2611,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
     {
       if (flags & LOOKUP_COMPLAIN)
        {
-         error ("conversion from `%T' to `%T' is ambiguous",
+         error ("conversion from %qT to %qT is ambiguous",
                    fromtype, totype);
          print_z_candidates (candidates);
        }
@@ -2661,7 +2656,8 @@ build_user_type_conversion (tree totype, tree expr, int flags)
     {
       if (cand->second_conv->kind == ck_ambig)
        return error_mark_node;
-      return convert_from_reference (convert_like (cand->second_conv, expr));
+      expr = convert_like (cand->second_conv, expr);
+      return convert_from_reference (expr);
     }
   return NULL_TREE;
 }
@@ -2683,8 +2679,6 @@ resolve_args (tree args)
          error ("invalid use of void expression");
          return error_mark_node;
        }
-      arg = convert_from_reference (arg);
-      TREE_VALUE (t) = arg;
     }
   return args;
 }
@@ -2715,13 +2709,11 @@ perform_overload_resolution (tree fn,
   *any_viable_p = true;
 
   /* Check FN and ARGS.  */
-  my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL 
-                     || TREE_CODE (fn) == TEMPLATE_DECL
-                     || TREE_CODE (fn) == OVERLOAD
-                     || TREE_CODE (fn) == TEMPLATE_ID_EXPR,
-                     20020712);
-  my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
-                     20020712);
+  gcc_assert (TREE_CODE (fn) == FUNCTION_DECL 
+             || TREE_CODE (fn) == TEMPLATE_DECL
+             || TREE_CODE (fn) == OVERLOAD
+             || TREE_CODE (fn) == TEMPLATE_ID_EXPR);
+  gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
 
   if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
     {
@@ -2772,10 +2764,10 @@ build_new_function_call (tree fn, tree args)
       if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
        fn = TREE_OPERAND (fn, 0);
       if (!any_viable_p)
-       error ("no matching function for call to `%D(%A)'",
+       error ("no matching function for call to %<%D(%A)%>",
               DECL_NAME (OVL_CURRENT (fn)), args);
       else
-       error ("call of overloaded `%D(%A)' is ambiguous",
+       error ("call of overloaded %<%D(%A)%> is ambiguous",
               DECL_NAME (OVL_CURRENT (fn)), args);
       if (candidates)
        print_z_candidates (candidates);
@@ -2811,7 +2803,16 @@ build_operator_new_call (tree fnname, tree args, tree *size, tree *cookie_size)
   if (args == error_mark_node)
     return args;
 
-  fns = lookup_function_nonclass (fnname, args);
+  /* Based on:
+
+       [expr.new]
+
+       If this lookup fails to find the name, or if the allocated type
+       is not a class type, the allocation function's name is looked
+       up in the global scope.
+
+     we disregard block-scope declarations of "operator new".  */
+  fns = lookup_function_nonclass (fnname, args, /*block_p=*/false);
 
   /* Figure out what function is being called.  */
   cand = perform_overload_resolution (fns, args, &candidates, &any_viable_p);
@@ -2821,10 +2822,10 @@ build_operator_new_call (tree fnname, tree args, tree *size, tree *cookie_size)
   if (!cand)
     {
       if (!any_viable_p)
-       error ("no matching function for call to `%D(%A)'",
+       error ("no matching function for call to %<%D(%A)%>",
               DECL_NAME (OVL_CURRENT (fns)), args);
       else
-       error ("call of overloaded `%D(%A)' is ambiguous",
+       error ("call of overloaded %<%D(%A)%> is ambiguous",
               DECL_NAME (OVL_CURRENT (fns)), args);
       if (candidates)
        print_z_candidates (candidates);
@@ -2961,7 +2962,7 @@ build_object_call (tree obj, tree args)
   candidates = splice_viable (candidates, pedantic, &any_viable_p);
   if (!any_viable_p)
     {
-      error ("no match for call to `(%T) (%A)'", TREE_TYPE (obj), args);
+      error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args);
       print_z_candidates (candidates);
       result = error_mark_node;
     }
@@ -2970,7 +2971,7 @@ build_object_call (tree obj, tree args)
       cand = tourney (candidates);
       if (cand == 0)
        {
-         error ("call of `(%T) (%A)' is ambiguous", TREE_TYPE (obj), args);
+         error ("call of %<(%T) (%A)%> is ambiguous", TREE_TYPE (obj), args);
          print_z_candidates (candidates);
          result = error_mark_node;
        }
@@ -2983,6 +2984,7 @@ build_object_call (tree obj, tree args)
       else
        {
          obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1);
+         obj = convert_from_reference (obj);
          result = build_function_call (obj, args);
        }
     }
@@ -3007,30 +3009,30 @@ op_error (enum tree_code code, enum tree_code code2,
   switch (code)
     {
     case COND_EXPR:
-      error ("%s for ternary 'operator?:' in '%E ? %E : %E'",
+      error ("%s for ternary %<operator?:%> in %<%E ? %E : %E%>",
              problem, arg1, arg2, arg3);
       break;
       
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
-      error ("%s for 'operator%s' in '%E%s'", problem, opname, arg1, opname);
+      error ("%s for %<operator%s%> in %<%E%s%>", problem, opname, arg1, opname);
       break;
       
     case ARRAY_REF:
-      error ("%s for 'operator[]' in '%E[%E]'", problem, arg1, arg2);
+      error ("%s for %<operator[]%> in %<%E[%E]%>", problem, arg1, arg2);
       break;
 
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      error ("%s for '%s' in '%s %E'", problem, opname, opname, arg1);
+      error ("%s for %qs in %<%s %E%>", problem, opname, opname, arg1);
       break;
       
     default:
       if (arg2)
-       error ("%s for 'operator%s' in '%E %s %E'",
+       error ("%s for %<operator%s%> in %<%E %s %E%>",
                problem, opname, arg1, opname, arg2);
       else
-       error ("%s for 'operator%s' in '%s%E'",
+       error ("%s for %<operator%s%> in %<%s%E%>",
                problem, opname, opname, arg1);
       break;
     }
@@ -3072,10 +3074,7 @@ conditional_conversion (tree e1, tree e2)
      same cv-qualification as, or a greater cv-qualification than, the
      cv-qualification of T1.  If the conversion is applied, E1 is
      changed to an rvalue of type T2 that still refers to the original
-     source class object (or the appropriate subobject thereof).
-
-     FIXME we can't express an rvalue that refers to the original object;
-     we have to create a new one.  */
+     source class object (or the appropriate subobject thereof).  */
   if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
       && ((good_base = DERIVED_FROM_P (t2, t1)) || DERIVED_FROM_P (t1, t2)))
     {
@@ -3084,10 +3083,7 @@ conditional_conversion (tree e1, tree e2)
          conv = build_identity_conv (t1, e1);
          if (!same_type_p (TYPE_MAIN_VARIANT (t1), 
                            TYPE_MAIN_VARIANT (t2)))
-           {
-             conv = build_conv (ck_base, t2, conv);
-             conv->need_temporary_p = true;
-           }
+           conv = build_conv (ck_base, t2, conv);
          else
            conv = build_conv (ck_rvalue, t2, conv);
          return conv;
@@ -3178,18 +3174,24 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
           type of the other and is an rvalue.
 
         --Both the second and the third operands have type void; the
-          result is of type void and is an rvalue.  */
+          result is of type void and is an rvalue.  
+
+         We must avoid calling force_rvalue for expressions of type
+        "void" because it will complain that their value is being
+        used.  */
       if (TREE_CODE (arg2) == THROW_EXPR 
          && TREE_CODE (arg3) != THROW_EXPR)
        {
-         arg3 = force_rvalue (arg3);
+         if (!VOID_TYPE_P (arg3_type))
+           arg3 = force_rvalue (arg3);
          arg3_type = TREE_TYPE (arg3);
          result_type = arg3_type;
        }
       else if (TREE_CODE (arg2) != THROW_EXPR 
               && TREE_CODE (arg3) == THROW_EXPR)
        {
-         arg2 = force_rvalue (arg2);
+         if (!VOID_TYPE_P (arg2_type))
+           arg2 = force_rvalue (arg2);
          arg2_type = TREE_TYPE (arg2);
          result_type = arg2_type;
        }
@@ -3197,7 +3199,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
        result_type = void_type_node;
       else
        {
-         error ("`%E' has type `void' and is not a throw-expression",
+         error ("%qE has type %<void%> and is not a throw-expression",
                    VOID_TYPE_P (arg2_type) ? arg2 : arg3);
          return error_mark_node;
        }
@@ -3400,14 +3402,14 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
       
       if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
           && TREE_CODE (arg3_type) == ENUMERAL_TYPE)
-         warning ("enumeral mismatch in conditional expression: `%T' vs `%T'",
+         warning (0, "enumeral mismatch in conditional expression: %qT vs %qT",
                    arg2_type, arg3_type);
       else if (extra_warnings
                && ((TREE_CODE (arg2_type) == ENUMERAL_TYPE
                     && !same_type_p (arg3_type, type_promotes_to (arg2_type)))
                    || (TREE_CODE (arg3_type) == ENUMERAL_TYPE
                        && !same_type_p (arg2_type, type_promotes_to (arg3_type)))))
-        warning ("enumeral and non-enumeral type in conditional expression");
+        warning (0, "enumeral and non-enumeral type in conditional expression");
       
       arg2 = perform_implicit_conversion (result_type, arg2);
       arg3 = perform_implicit_conversion (result_type, arg3);
@@ -3451,7 +3453,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
     }
 
  valid_operands:
-  result = fold (build (COND_EXPR, result_type, arg1, arg2, arg3));
+  result = fold_if_not_in_template (build3 (COND_EXPR, result_type, arg1, 
+                                           arg2, arg3));
   /* We can't use result_type below, as fold might have returned a
      throw_expr.  */
 
@@ -3478,7 +3481,6 @@ prep_operand (tree operand)
 {
   if (operand)
     {
-      operand = convert_from_reference (operand);
       if (CLASS_TYPE_P (TREE_TYPE (operand))
          && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (operand)))
        /* Make sure the template type is instantiated now.  */
@@ -3555,7 +3557,8 @@ add_candidates (tree fns, tree args,
 }
 
 tree
-build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
+build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
+             bool *overloaded_p)
 {
   struct z_candidate *candidates = 0, *cand;
   tree arglist, fnname;
@@ -3591,7 +3594,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
     case VEC_DELETE_EXPR:
     case DELETE_EXPR:
       /* Use build_op_new_call and build_op_delete_call instead.  */
-      abort ();
+      gcc_unreachable ();
 
     case CALL_EXPR:
       return build_object_call (arg1, arg2);
@@ -3631,7 +3634,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
 
   /* Add namespace-scope operators to the list of functions to
      consider.  */
-  add_candidates (lookup_function_nonclass (fnname, arglist),
+  add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true),
                  arglist, NULL_TREE, false, NULL_TREE, NULL_TREE,
                  flags, &candidates);
   /* Add class-member operators to the candidate set.  */
@@ -3639,7 +3642,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
     {
       tree fns;
 
-      fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1);
+      fns = lookup_fnfields (TREE_TYPE (arg1), fnname, 1);
       if (fns == error_mark_node)
        {
          result = error_mark_node;
@@ -3700,14 +3703,16 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
          /* Look for an `operator++ (int)'.  If they didn't have
             one, then we fall back to the old way of doing things.  */
          if (flags & LOOKUP_COMPLAIN)
-           pedwarn ("no `%D(int)' declared for postfix `%s', trying prefix operator instead",
-                       fnname, 
-                       operator_name_info[code].name);
+           pedwarn ("no %<%D(int)%> declared for postfix %qs, "
+                     "trying prefix operator instead",
+                     fnname, 
+                     operator_name_info[code].name);
          if (code == POSTINCREMENT_EXPR)
            code = PREINCREMENT_EXPR;
          else
            code = PREDECREMENT_EXPR;   
-         result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE);
+         result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE,
+                                overloaded_p);
          break;
 
          /* The caller will deal with these.  */
@@ -3742,24 +3747,21 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
        }
       else if (TREE_CODE (cand->fn) == FUNCTION_DECL)
        {
-         if (warn_synth
-             && fnname == ansi_assopname (NOP_EXPR)
-             && DECL_ARTIFICIAL (cand->fn)
-             && candidates->next
-             && ! candidates->next->next)
-           {
-             warning ("using synthesized `%#D' for copy assignment",
-                         cand->fn);
-             cp_warning_at ("  where cfront would use `%#D'",
-                            cand == candidates
-                            ? candidates->next->fn
-                            : candidates->fn);
-           }
+         if (overloaded_p)
+           *overloaded_p = true;
 
          result = build_over_call (cand, LOOKUP_NORMAL);
        }
       else
        {
+         /* Give any warnings we noticed during overload resolution.  */
+         if (cand->warnings)
+           {
+             struct candidate_warning *w;
+             for (w = cand->warnings; w; w = w->next)
+               joust (cand, w->loser, 1);
+           }
+
          /* Check for comparison of different enum types.  */
          switch (code)
            {
@@ -3774,8 +3776,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
                  && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1))
                      != TYPE_MAIN_VARIANT (TREE_TYPE (arg2))))
                {
-                 warning ("comparison between `%#T' and `%#T'", 
-                             TREE_TYPE (arg1), TREE_TYPE (arg2));
+                 warning (0, "comparison between %q#T and %q#T", 
+                           TREE_TYPE (arg1), TREE_TYPE (arg2));
                }
              break;
            default:
@@ -3815,7 +3817,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
   if (result || result_valid_p)
     return result;
 
-builtin:
+ builtin:
   switch (code)
     {
     case MODIFY_EXPR:
@@ -3865,8 +3867,7 @@ builtin:
       return build_conditional_expr (arg1, arg2, arg3);
 
     case MEMBER_REF:
-      return build_m_component_ref
-       (build_indirect_ref (arg1, NULL), arg2);
+      return build_m_component_ref (build_indirect_ref (arg1, NULL), arg2);
 
       /* The caller will deal with these.  */
     case ADDR_EXPR:
@@ -3875,9 +3876,9 @@ builtin:
       return NULL_TREE;
 
     default:
-      abort ();
-      return NULL_TREE;
+      gcc_unreachable ();
     }
+  return NULL_TREE;
 }
 
 /* Build a call to operator delete.  This has to be handled very specially,
@@ -3908,7 +3909,9 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
 
   fnname = ansi_opname (code);
 
-  if (IS_AGGR_TYPE (type) && !global_p)
+  if (CLASS_TYPE_P (type) 
+      && COMPLETE_TYPE_P (complete_type (type))
+      && !global_p)
     /* In [class.free]
 
        If the result of the lookup is ambiguous or inaccessible, or if
@@ -3936,7 +3939,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
       call_expr = placement;
       /* Extract the function.  */
       alloc_fn = get_callee_fndecl (call_expr);
-      my_friendly_assert (alloc_fn != NULL_TREE, 20020327);
+      gcc_assert (alloc_fn != NULL_TREE);
       /* Then the second parm type.  */
       argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
       /* Also the second argument.  */
@@ -3974,15 +3977,15 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
          /* On the first pass, check the rest of the arguments.  */
          if (pass == 0)
            {
-             while (argtypes && t)
+             tree a = argtypes;
+             while (a && t)
                {
-                 if (!same_type_p (TREE_VALUE (argtypes),
-                                   TREE_VALUE (t)))
+                 if (!same_type_p (TREE_VALUE (a), TREE_VALUE (t)))
                    break;
-                 argtypes = TREE_CHAIN (argtypes);
+                 a = TREE_CHAIN (a);
                  t = TREE_CHAIN (t);
                }
-             if (!argtypes && !t)
+             if (!a && !t)
                break;
            }
          /* On the second pass, the second argument must be
@@ -4021,7 +4024,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
          /* The placement args might not be suitable for overload
             resolution at this point, so build the call directly.  */
          mark_used (fn);
-         return build_cxx_call (fn, args, args);
+         return build_cxx_call (fn, args);
        }
       else
        return build_function_call (fn, args);
@@ -4032,7 +4035,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
   if (placement)
     return NULL_TREE;
 
-  error ("no suitable `operator %s' for `%T'",
+  error ("no suitable %<operator %s> for %qT",
         operator_name_info[(int)code].name, type);
   return error_mark_node;
 }
@@ -4044,16 +4047,16 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
 bool
 enforce_access (tree basetype_path, tree decl)
 {
-  my_friendly_assert (TREE_CODE (basetype_path) == TREE_VEC, 20030624);
+  gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
   
-  if (!accessible_p (basetype_path, decl))
+  if (!accessible_p (basetype_path, decl, true))
     {
       if (TREE_PRIVATE (decl))
-       cp_error_at ("`%+#D' is private", decl);
+       cp_error_at ("%q+#D is private", decl);
       else if (TREE_PROTECTED (decl))
-       cp_error_at ("`%+#D' is protected", decl);
+       cp_error_at ("%q+#D is protected", decl);
       else
-       cp_error_at ("`%+#D' is inaccessible", decl);
+       cp_error_at ("%q+#D is inaccessible", decl);
       error ("within this context");
       return false;
     }
@@ -4061,6 +4064,21 @@ enforce_access (tree basetype_path, tree decl)
   return true;
 }
 
+/* Check that a callable constructor to initialize a temporary of
+   TYPE from an EXPR exists.  */
+
+static void
+check_constructor_callable (tree type, tree expr)
+{
+  build_special_member_call (NULL_TREE,
+                            complete_ctor_identifier,
+                            build_tree_list (NULL_TREE, expr), 
+                            type,
+                            LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
+                            | LOOKUP_NO_CONVERSION
+                            | LOOKUP_CONSTRUCTOR_CALLABLE);
+}
+
 /* Initialize a temporary of type TYPE with EXPR.  The FLAGS are a
    bitwise or of LOOKUP_* values.  If any errors are warnings are
    generated, set *DIAGNOSTIC_FN to "error" or "warning",
@@ -4072,15 +4090,14 @@ build_temp (tree expr, tree type, int flags,
            void (**diagnostic_fn)(const char *, ...))
 {
   int savew, savee;
-
+  
   savew = warningcount, savee = errorcount;
-  expr = build_special_member_call (NULL_TREE, 
+  expr = build_special_member_call (NULL_TREE,
                                    complete_ctor_identifier,
                                    build_tree_list (NULL_TREE, expr), 
-                                   TYPE_BINFO (type),
-                                   flags);
+                                   type, flags);
   if (warningcount > savew)
-    *diagnostic_fn = warning;
+    *diagnostic_fn = warning0;
   else if (errorcount > savee)
     *diagnostic_fn = error;
   else
@@ -4095,11 +4112,14 @@ build_temp (tree expr, tree type, int flags,
    being called to continue a conversion chain. It is negative when a
    reference binding will be applied, positive otherwise.  If
    ISSUE_CONVERSION_WARNINGS is true, warnings about suspicious
-   conversions will be emitted if appropriate.  */
+   conversions will be emitted if appropriate.  If C_CAST_P is true,
+   this conversion is coming from a C-style cast; in that case,
+   conversions to inaccessible bases are permitted.  */
 
 static tree
 convert_like_real (conversion *convs, tree expr, tree fn, int argnum, 
-                  int inner, bool issue_conversion_warnings)
+                  int inner, bool issue_conversion_warnings,
+                  bool c_cast_p)
 {
   tree totype = convs->type;
   void (*diagnostic_fn)(const char *, ...);
@@ -4115,24 +4135,64 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
          if (t->kind == ck_user || !t->bad_p)
            {
              expr = convert_like_real (t, expr, fn, argnum, 1,
-                                       /*issue_conversion_warnings=*/false);
+                                       /*issue_conversion_warnings=*/false,
+                                       /*c_cast_p=*/false);
              break;
            }
          else if (t->kind == ck_ambig)
            return convert_like_real (t, expr, fn, argnum, 1,
-                                     /*issue_conversion_warnings=*/false);
+                                     /*issue_conversion_warnings=*/false,
+                                     /*c_cast_p=*/false);
          else if (t->kind == ck_identity)
            break;
        }
-      pedwarn ("invalid conversion from `%T' to `%T'", TREE_TYPE (expr), totype);
+      pedwarn ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
       if (fn)
-       pedwarn ("  initializing argument %P of `%D'", argnum, fn);
+       pedwarn ("  initializing argument %P of %qD", argnum, fn);
       return cp_convert (totype, expr);
     }
   
   if (issue_conversion_warnings)
-    expr = dubious_conversion_warnings
-             (totype, expr, "converting", fn, argnum);
+    {
+      tree t = non_reference (totype);
+
+      /* Issue warnings about peculiar, but valid, uses of NULL.  */
+      if (ARITHMETIC_TYPE_P (t) && expr == null_node)
+       {
+         if (fn)
+           warning (0, "passing NULL to non-pointer argument %P of %qD",
+                    argnum, fn);
+         else
+           warning (0, "converting to non-pointer type %qT from NULL", t);
+       }
+
+      /* Warn about assigning a floating-point type to an integer type.  */
+      if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+         && TREE_CODE (t) == INTEGER_TYPE)
+       {
+         if (fn)
+           warning (0, "passing %qT for argument %P to %qD",
+                    TREE_TYPE (expr), argnum, fn);
+         else
+           warning (0, "converting to %qT from %qT", t, TREE_TYPE (expr));
+       }
+      /* And warn about assigning a negative value to an unsigned
+        variable.  */
+      else if (TYPE_UNSIGNED (t) && TREE_CODE (t) != BOOLEAN_TYPE)
+       {
+         if (TREE_CODE (expr) == INTEGER_CST && TREE_NEGATED_INT (expr)) 
+           {
+             if (fn)
+               warning (0, "passing negative value %qE for argument %P to %qD",
+                        expr, argnum, fn);
+             else
+               warning (0, "converting negative value %qE to %qT", expr, t);
+           }
+         
+         overflow_warning (expr);
+       }
+    }
+
   switch (convs->kind)
     {
     case ck_user:
@@ -4143,15 +4203,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 
        if (DECL_CONSTRUCTOR_P (convfn))
          {
-           tree t = build_int_2 (0, 0);
-           TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (convfn));
+           tree t = build_int_cst (build_pointer_type (DECL_CONTEXT (convfn)),
+                                   0);
 
            args = build_tree_list (NULL_TREE, expr);
-           if (DECL_HAS_IN_CHARGE_PARM_P (convfn)
-               || DECL_HAS_VTT_PARM_P (convfn))
-             /* We should never try to call the abstract or base constructor
-                from here.  */
-             abort ();
+           /* We should never try to call the abstract or base constructor
+              from here.  */
+           gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (convfn)
+                       && !DECL_HAS_VTT_PARM_P (convfn));
            args = tree_cons (NULL_TREE, t, args);
          }
        else
@@ -4187,11 +4246,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
              {
                if (fn)
                  diagnostic_fn 
-                   ("  initializing argument %P of `%D' from result of `%D'",
+                   ("  initializing argument %P of %qD from result of %qD",
                     argnum, fn, convfn);
                else
                 diagnostic_fn 
-                  ("  initializing temporary from result of `%D'",  convfn);
+                  ("  initializing temporary from result of %qD",  convfn);
              }
            expr = build_cplus_new (totype, expr);
          }
@@ -4200,20 +4259,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     case ck_identity:
       if (type_unknown_p (expr))
        expr = instantiate_type (totype, expr, tf_error | tf_warning);
-      /* Convert a non-array constant variable to its underlying value, unless we
-        are about to bind it to a reference, in which case we need to
+      /* Convert a constant to its underlying value, unless we are
+        about to bind it to a reference, in which case we need to
         leave it as an lvalue.  */
-      if (inner >= 0
-         && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
-       expr = decl_constant_value (expr);
+      if (inner >= 0)
+       expr = integral_constant_value (expr);
       if (convs->check_copy_constructor_p)
-       /* Generate a temporary copy purely to generate the required
-          diagnostics.  */
-       build_temp
-         (build_dummy_object
-          (build_qualified_type (totype, TYPE_QUAL_CONST)),
-          totype, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, &diagnostic_fn);
-       return expr;
+       check_constructor_callable (totype, expr);
+      return expr;
     case ck_ambig:
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
@@ -4225,7 +4278,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 
   expr = convert_like_real (convs->u.next, expr, fn, argnum,
                            convs->kind == ck_ref_bind ? -1 : 1,
-                           /*issue_conversion_warnings=*/false);
+                           /*issue_conversion_warnings=*/false,
+                           c_cast_p);
   if (expr == error_mark_node)
     return error_mark_node;
 
@@ -4241,16 +4295,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
          /* We are going to bind a reference directly to a base-class
             subobject of EXPR.  */
          if (convs->check_copy_constructor_p)
-           /* Generate a temporary copy purely to generate the required
-              diagnostics.  */
-           build_temp (build_dummy_object (TREE_TYPE (expr)),
-                       TREE_TYPE (expr),
-                       LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
-                       &diagnostic_fn);
+           check_constructor_callable (TREE_TYPE (expr), expr);
          /* Build an expression for `*((base*) &expr)'.  */
          expr = build_unary_op (ADDR_EXPR, expr, 0);
-         expr = perform_implicit_conversion (build_pointer_type (totype), 
-                                             expr);
+         expr = convert_to_base (expr, build_pointer_type (totype),
+                                 !c_cast_p, /*nonnull=*/true);
          expr = build_indirect_ref (expr, "implicit conversion");
          return expr;
        }
@@ -4261,7 +4310,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       expr = build_temp (expr, totype, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
                         &diagnostic_fn);
       if (diagnostic_fn && fn)
-       diagnostic_fn ("  initializing argument %P of `%D'", argnum, fn);
+       diagnostic_fn ("  initializing argument %P of %qD", argnum, fn);
       return build_cplus_new (totype, expr);
 
     case ck_ref_bind:
@@ -4272,21 +4321,34 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        if (convs->need_temporary_p || !lvalue_p (expr))
          {
            tree type = convs->u.next->type;
+           cp_lvalue_kind lvalue = real_lvalue_p (expr);
 
            if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
              {
                /* If the reference is volatile or non-const, we
                   cannot create a temporary.  */
-               cp_lvalue_kind lvalue = real_lvalue_p (expr);
-               
                if (lvalue & clk_bitfield)
-                 error ("cannot bind bitfield `%E' to `%T'",
+                 error ("cannot bind bitfield %qE to %qT",
                         expr, ref_type);
                else if (lvalue & clk_packed)
-                 error ("cannot bind packed field `%E' to `%T'",
+                 error ("cannot bind packed field %qE to %qT",
                         expr, ref_type);
                else
-                 error ("cannot bind rvalue `%E' to `%T'", expr, ref_type);
+                 error ("cannot bind rvalue %qE to %qT", expr, ref_type);
+               return error_mark_node;
+             }
+           /* If the source is a packed field, and we must use a copy
+              constructor, then building the target expr will require
+              binding the field to the reference parameter to the
+              copy constructor, and we'll end up with an infinite
+              loop.  If we can use a bitwise copy, then we'll be
+              OK.  */
+           if ((lvalue & clk_packed) 
+               && CLASS_TYPE_P (type) 
+               && !TYPE_HAS_TRIVIAL_INIT_REF (type))
+             {
+               error ("cannot bind packed field %qE to %qT",
+                      expr, ref_type);
                return error_mark_node;
              }
            expr = build_target_expr_with_type (expr, type);
@@ -4314,7 +4376,17 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       /* Warn about deprecated conversion if appropriate.  */
       string_conv_p (totype, expr, 1);
       break;
-      
+
+    case ck_ptr:
+      if (convs->base_p)
+       expr = convert_to_base (expr, totype, !c_cast_p,
+                               /*nonnull=*/false);
+      return build_nop (totype, expr);
+
+    case ck_pmem:
+      return convert_ptrmem (totype, expr, /*allow_inverse_p=*/false,
+                            c_cast_p);
+
     default:
       break;
     }
@@ -4322,18 +4394,15 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
                      LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
 }
 
-/* Build a call to __builtin_trap which can be used as an expression of
-   type TYPE.  */
+/* Build a call to __builtin_trap.  */
 
 static tree
-call_builtin_trap (tree type)
+call_builtin_trap (void)
 {
-  tree fn = IDENTIFIER_GLOBAL_VALUE (get_identifier ("__builtin_trap"));
+  tree fn = implicit_built_in_decls[BUILT_IN_TRAP];
 
-  my_friendly_assert (fn != NULL, 20030927);
+  gcc_assert (fn != NULL);
   fn = build_call (fn, NULL_TREE);
-  fn = build (COMPOUND_EXPR, type, fn, error_mark_node);
-  fn = force_target_expr (type, fn);
   return fn;
 }
 
@@ -4374,9 +4443,11 @@ convert_arg_to_ellipsis (tree arg)
         there is no need to emit a warning, since the expression won't be 
         evaluated. We keep the builtin_trap just as a safety check.  */
       if (!skip_evaluation)
-       warning ("cannot pass objects of non-POD type `%#T' through `...'; "
+       warning (0, "cannot pass objects of non-POD type %q#T through %<...%>; "
                 "call will abort at runtime", TREE_TYPE (arg));
-      arg = call_builtin_trap (TREE_TYPE (arg));
+      arg = call_builtin_trap ();
+      arg = build2 (COMPOUND_EXPR, integer_type_node, arg,
+                   integer_zero_node);
     }
 
   return arg;
@@ -4398,10 +4469,13 @@ build_x_va_arg (tree expr, tree type)
   if (! pod_type_p (type))
     {
       /* Undefined behavior [expr.call] 5.2.2/7.  */
-      warning ("cannot receive objects of non-POD type `%#T' through `...'; \
-call will abort at runtime",
-              type);
-      return call_builtin_trap (type);
+      warning (0, "cannot receive objects of non-POD type %q#T through %<...%>; "
+               "call will abort at runtime", type);
+      expr = convert (build_pointer_type (type), null_node);
+      expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr),
+                    call_builtin_trap (), expr);
+      expr = build_indirect_ref (expr, NULL);
+      return expr;
     }
   
   return build_va_arg (expr, type);
@@ -4438,7 +4512,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
      conversion cannot be performed.  */
   if (TREE_CODE (arg) == DEFAULT_ARG)
     {
-      error ("the default argument for parameter %d of `%D' has "
+      error ("the default argument for parameter %d of %qD has "
             "not yet been parsed",
             parmnum, fn);
       return error_mark_node;
@@ -4477,7 +4551,11 @@ type_passed_as (tree type)
 {
   /* Pass classes with copy ctors by invisible reference.  */
   if (TREE_ADDRESSABLE (type))
-    type = build_reference_type (type);
+    {
+      type = build_reference_type (type);
+      /* There are no other pointers to this temporary.  */
+      type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
+    }
   else if (targetm.calls.promote_prototypes (type)
           && INTEGRAL_TYPE_P (type)
           && COMPLETE_TYPE_P (type)
@@ -4557,7 +4635,9 @@ build_over_call (struct z_candidate *cand, int flags)
       tree expr;
       tree return_type;
       return_type = TREE_TYPE (TREE_TYPE (fn));
-      expr = build (CALL_EXPR, return_type, fn, args);
+      expr = build3 (CALL_EXPR, return_type, fn, args, NULL_TREE);
+      if (TREE_THIS_VOLATILE (fn) && cfun)
+       current_function_returns_abnormally = 1;
       if (!VOID_TYPE_P (return_type))
        require_complete_type (return_type);
       return convert_from_reference (expr);
@@ -4599,7 +4679,7 @@ build_over_call (struct z_candidate *cand, int flags)
         primary template because `B<T>::g' and `B<int>::g' may have
         different access.  */
       if (DECL_TEMPLATE_INFO (fn)
-         && is_member_template (DECL_TI_TEMPLATE (fn)))
+         && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
        perform_or_defer_access_check (cand->access_path,
                                       DECL_TI_TEMPLATE (fn));
       else
@@ -4617,9 +4697,9 @@ build_over_call (struct z_candidate *cand, int flags)
       converted_args = tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args);
       arg = TREE_CHAIN (arg);
       parm = TREE_CHAIN (parm);
-      if (DECL_HAS_IN_CHARGE_PARM_P (fn))
-       /* We should never try to call the abstract constructor.  */
-       abort ();
+      /* We should never try to call the abstract constructor.  */
+      gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn));
+      
       if (DECL_HAS_VTT_PARM_P (fn))
        {
          converted_args = tree_cons
@@ -4637,8 +4717,8 @@ build_over_call (struct z_candidate *cand, int flags)
       tree base_binfo;
       
       if (convs[i]->bad_p)
-       pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers",
-                   TREE_TYPE (argtype), fn);
+       pedwarn ("passing %qT as %<this%> argument of %q#D discards qualifiers",
+                 TREE_TYPE (argtype), fn);
 
       /* [class.mfct.nonstatic]: If a nonstatic member function of a class
         X is called for an object that is not of type X, or of a type
@@ -4646,24 +4726,24 @@ build_over_call (struct z_candidate *cand, int flags)
 
          So we can assume that anything passed as 'this' is non-null, and
         optimize accordingly.  */
-      my_friendly_assert (TREE_CODE (parmtype) == POINTER_TYPE, 19990811);
+      gcc_assert (TREE_CODE (parmtype) == POINTER_TYPE);
       /* Convert to the base in which the function was declared.  */
-      my_friendly_assert (cand->conversion_path != NULL_TREE, 20020730);
+      gcc_assert (cand->conversion_path != NULL_TREE);
       converted_arg = build_base_path (PLUS_EXPR,
                                       TREE_VALUE (arg),
                                       cand->conversion_path,
                                       1);
       /* Check that the base class is accessible.  */
       if (!accessible_base_p (TREE_TYPE (argtype), 
-                             BINFO_TYPE (cand->conversion_path)))
-       error ("`%T' is not an accessible base of `%T'",
+                             BINFO_TYPE (cand->conversion_path), true))
+       error ("%qT is not an accessible base of %qT",
               BINFO_TYPE (cand->conversion_path),
               TREE_TYPE (argtype));
       /* If fn was found by a using declaration, the conversion path
          will be to the derived class, not the base declaring fn. We
          must convert from derived to base.  */
       base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
-                               TREE_TYPE (parmtype), ba_ignore, NULL);
+                               TREE_TYPE (parmtype), ba_unique, NULL);
       converted_arg = build_base_path (PLUS_EXPR, converted_arg,
                                       base_binfo, 1);
       
@@ -4709,9 +4789,8 @@ build_over_call (struct z_candidate *cand, int flags)
 
   converted_args = nreverse (converted_args);
 
-  if (warn_format)
-    check_function_format (NULL, TYPE_ATTRIBUTES (TREE_TYPE (fn)),
-                          converted_args);
+  check_function_arguments (TYPE_ATTRIBUTES (TREE_TYPE (fn)),
+                           converted_args);
 
   /* Avoid actually calling copy constructors and copy assignment operators,
      if possible.  */
@@ -4765,16 +4844,11 @@ build_over_call (struct z_candidate *cand, int flags)
       else if (TREE_CODE (arg) == TARGET_EXPR
               || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
        {
-         tree address;
          tree to = stabilize_reference
            (build_indirect_ref (TREE_VALUE (args), 0));
 
-         val = build (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
-         address = build_unary_op (ADDR_EXPR, val, 0);
-         /* Avoid a warning about this expression, if the address is
-            never used.  */
-         TREE_USED (address) = 1;
-         return address;
+         val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
+         return val;
        }
     }
   else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
@@ -4786,31 +4860,28 @@ build_over_call (struct z_candidate *cand, int flags)
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
 
-      arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
+      arg = TREE_VALUE (TREE_CHAIN (converted_args));
       if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
-       val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+       {
+         arg = build_indirect_ref (arg, 0);
+         val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+       }
       else
        {
-         /* We must only copy the non-tail padding parts. Use
-            CLASSTYPE_AS_BASE for the bitwise copy.  */
-         tree to_ptr, arg_ptr, to_as_base, arg_as_base, base_ptr_type;
-         tree save_to;
-
-         to_ptr = save_expr (build_unary_op (ADDR_EXPR, to, 0));
-         arg_ptr = build_unary_op (ADDR_EXPR, arg, 0);
-
-         base_ptr_type = build_pointer_type (as_base);
-         to_as_base = build_nop (base_ptr_type, to_ptr);
-         to_as_base = build_indirect_ref (to_as_base, 0);
-         arg_as_base = build_nop (base_ptr_type, arg_ptr);
-         arg_as_base = build_indirect_ref (arg_as_base, 0);
-
-         save_to = build_indirect_ref (to_ptr, 0);
-
-         val = build (MODIFY_EXPR, as_base, to_as_base, arg_as_base);
-         val = convert_to_void (val, NULL);
-         val = build (COMPOUND_EXPR, type, val, save_to);
-         TREE_NO_UNUSED_WARNING (val) = 1;
+         /* We must only copy the non-tail padding parts.
+            Use __builtin_memcpy for the bitwise copy.  */
+
+         tree args, t;
+
+         args = tree_cons (NULL, TYPE_SIZE_UNIT (as_base), NULL);
+         args = tree_cons (NULL, arg, args);
+         t = build_unary_op (ADDR_EXPR, to, 0);
+         args = tree_cons (NULL, t, args);
+         t = implicit_built_in_decls[BUILT_IN_MEMCPY];
+         t = build_call (t, args);
+
+         t = convert (TREE_TYPE (TREE_VALUE (args)), t);
+         val = build_indirect_ref (t, 0);
        }
       
       return val;
@@ -4824,7 +4895,7 @@ build_over_call (struct z_candidate *cand, int flags)
       tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)),
                                DECL_CONTEXT (fn),
                                ba_any, NULL);
-      my_friendly_assert (binfo && binfo != error_mark_node, 20010730);
+      gcc_assert (binfo && binfo != error_mark_node);
       
       *p = build_base_path (PLUS_EXPR, *p, binfo, 1);
       if (TREE_SIDE_EFFECTS (*p))
@@ -4833,7 +4904,7 @@ build_over_call (struct z_candidate *cand, int flags)
       if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
        fn = build_java_interface_fn_ref (fn, *p);
       else
-       fn = build_vfn_ref (build_indirect_ref (*p, 0), DECL_VINDEX (fn));
+       fn = build_vfn_ref (*p, DECL_VINDEX (fn));
       TREE_TYPE (fn) = t;
     }
   else if (DECL_INLINE (fn))
@@ -4841,33 +4912,19 @@ build_over_call (struct z_candidate *cand, int flags)
   else
     fn = build_addr_func (fn);
 
-  return build_cxx_call (fn, args, converted_args);
+  return build_cxx_call (fn, converted_args);
 }
 
-/* Build and return a call to FN, using the the CONVERTED_ARGS.  ARGS
-   gives the original form of the arguments.  This function performs
+/* Build and return a call to FN, using ARGS.  This function performs
    no overload resolution, conversion, or other high-level
    operations.  */
 
 tree
-build_cxx_call(tree fn, tree args, tree converted_args)
+build_cxx_call (tree fn, tree args)
 {
   tree fndecl;
 
-  /* Recognize certain built-in functions so we can make tree-codes
-     other than CALL_EXPR.  We do this when it enables fold-const.c
-     to do something useful.  */
-  if (TREE_CODE (fn) == ADDR_EXPR
-      && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
-      && DECL_BUILT_IN (TREE_OPERAND (fn, 0)))
-    {
-      tree exp;
-      exp = expand_tree_builtin (TREE_OPERAND (fn, 0), args, converted_args);
-      if (exp)
-       return exp;
-    }
-
-  fn = build_call (fn, converted_args);
+  fn = build_call (fn, args);
 
   /* If this call might throw an exception, note that fact.  */
   fndecl = get_callee_fndecl (fn);
@@ -4878,7 +4935,7 @@ build_cxx_call(tree fn, tree args, tree converted_args)
 
   /* Some built-in function calls will be evaluated at compile-time in
      fold ().  */
-  fn = fold (fn);
+  fn = fold_if_not_in_template (fn);
 
   if (VOID_TYPE_P (TREE_TYPE (fn)))
     return fn;
@@ -4929,11 +4986,12 @@ build_java_interface_fn_ref (tree fn, tree instance)
   if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL
       || DECL_CONTEXT (iface_ref) != iface)
     {
-      error ("could not find class$ field in java interface type `%T'", 
+      error ("could not find class$ field in java interface type %qT", 
                iface);
       return error_mark_node;
     }
-  iface_ref = build1 (ADDR_EXPR, build_pointer_type (iface), iface_ref);
+  iface_ref = build_address (iface_ref);
+  iface_ref = convert (build_pointer_type (iface), iface_ref);
   
   /* Determine the itable index of FN.  */
   i = 1;
@@ -4945,7 +5003,7 @@ build_java_interface_fn_ref (tree fn, tree instance)
         break;
       i++;
     }
-  idx = build_int_2 (i, 0);
+  idx = build_int_cst (NULL_TREE, i);
 
   lookup_args = tree_cons (NULL_TREE, klass_ref, 
                           tree_cons (NULL_TREE, iface_ref,
@@ -4953,16 +5011,18 @@ build_java_interface_fn_ref (tree fn, tree instance)
   lookup_fn = build1 (ADDR_EXPR, 
                      build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
                      java_iface_lookup_fn);
-  return build (CALL_EXPR, ptr_type_node, lookup_fn, lookup_args, NULL_TREE);
+  return build3 (CALL_EXPR, ptr_type_node, lookup_fn, lookup_args, NULL_TREE);
 }
 
 /* Returns the value to use for the in-charge parameter when making a
-   call to a function with the indicated NAME.  */
+   call to a function with the indicated NAME.
+   
+   FIXME:Can't we find a neater way to do this mapping?  */
 
 tree
 in_charge_arg_for_name (tree name)
 {
 if (name == base_ctor_identifier
+ if (name == base_ctor_identifier
       || name == base_dtor_identifier)
     return integer_zero_node;
   else if (name == complete_ctor_identifier)
@@ -4974,7 +5034,7 @@ in_charge_arg_for_name (tree name)
 
   /* This function should only be called with one of the names listed
      above.  */
-  abort ();
+  gcc_unreachable ();
   return NULL_TREE;
 }
 
@@ -4998,22 +5058,29 @@ build_special_member_call (tree instance, tree name, tree args,
   /* The type of the subobject to be constructed or destroyed.  */
   tree class_type;
 
-  my_friendly_assert (name == complete_ctor_identifier
-                     || name == base_ctor_identifier
-                     || name == complete_dtor_identifier
-                     || name == base_dtor_identifier
-                     || name == deleting_dtor_identifier
-                     || name == ansi_assopname (NOP_EXPR),
-                     20020712);
-  my_friendly_assert (binfo != NULL_TREE, 20020712);
+  gcc_assert (name == complete_ctor_identifier
+             || name == base_ctor_identifier
+             || name == complete_dtor_identifier
+             || name == base_dtor_identifier
+             || name == deleting_dtor_identifier
+             || name == ansi_assopname (NOP_EXPR));
+  if (TYPE_P (binfo))
+    {
+      /* Resolve the name.  */
+      if (!complete_type_or_else (binfo, NULL_TREE))
+       return error_mark_node;
+
+      binfo = TYPE_BINFO (binfo);
+    }
+  
+  gcc_assert (binfo != NULL_TREE);
 
   class_type = BINFO_TYPE (binfo);
 
   /* Handle the special case where INSTANCE is NULL_TREE.  */
   if (name == complete_ctor_identifier && !instance)
     {
-      instance = build_int_2 (0, 0);
-      TREE_TYPE (instance) = build_pointer_type (class_type);
+      instance = build_int_cst (build_pointer_type (class_type), 0);
       instance = build1 (INDIRECT_REF, class_type, instance);
     }
   else
@@ -5021,7 +5088,7 @@ build_special_member_call (tree instance, tree name, tree args,
       if (name == complete_dtor_identifier 
          || name == base_dtor_identifier
          || name == deleting_dtor_identifier)
-       my_friendly_assert (args == NULL_TREE, 20020712);
+       gcc_assert (args == NULL_TREE);
 
       /* Convert to the base class, if necessary.  */
       if (!same_type_ignoring_top_level_qualifiers_p 
@@ -5042,11 +5109,7 @@ build_special_member_call (tree instance, tree name, tree args,
        }
     }
   
-  my_friendly_assert (instance != NULL_TREE, 20020712);
-
-  /* Resolve the name.  */
-  if (!complete_type_or_else (BINFO_TYPE (binfo), NULL_TREE))
-    return error_mark_node;
+  gcc_assert (instance != NULL_TREE);
 
   fns = lookup_fnfields (binfo, name, 1);
     
@@ -5055,7 +5118,7 @@ build_special_member_call (tree instance, tree name, tree args,
      the subobject.  */
   if ((name == base_ctor_identifier
        || name == base_dtor_identifier)
-      && TYPE_USES_VIRTUAL_BASECLASSES (class_type))
+      && CLASSTYPE_VBASECLASSES (class_type))
     {
       tree vtt;
       tree sub_vtt;
@@ -5065,14 +5128,14 @@ build_special_member_call (tree instance, tree name, tree args,
         Otherwise, we look it up using the VTT we were given.  */
       vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type));
       vtt = decay_conversion (vtt);
-      vtt = build (COND_EXPR, TREE_TYPE (vtt),
-                  build (EQ_EXPR, boolean_type_node,
-                         current_in_charge_parm, integer_zero_node),
-                  current_vtt_parm,
-                  vtt);
-      my_friendly_assert (BINFO_SUBVTT_INDEX (binfo), 20010110);
-      sub_vtt = build (PLUS_EXPR, TREE_TYPE (vtt), vtt,
-                      BINFO_SUBVTT_INDEX (binfo));
+      vtt = build3 (COND_EXPR, TREE_TYPE (vtt),
+                   build2 (EQ_EXPR, boolean_type_node,
+                           current_in_charge_parm, integer_zero_node),
+                   current_vtt_parm,
+                   vtt);
+      gcc_assert (BINFO_SUBVTT_INDEX (binfo));
+      sub_vtt = build2 (PLUS_EXPR, TREE_TYPE (vtt), vtt,
+                       BINFO_SUBVTT_INDEX (binfo));
 
       args = tree_cons (NULL_TREE, sub_vtt, args);
     }
@@ -5151,7 +5214,7 @@ build_new_method_call (tree instance, tree fns, tree args,
   tree orig_args;
   void *p;
 
-  my_friendly_assert (instance != NULL_TREE, 20020729);
+  gcc_assert (instance != NULL_TREE);
 
   if (error_operand_p (instance) 
       || error_operand_p (fns)
@@ -5178,14 +5241,12 @@ build_new_method_call (tree instance, tree fns, tree args,
   if (args == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
-    instance = convert_from_reference (instance);
   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
   instance_ptr = build_this (instance);
 
   if (!BASELINK_P (fns))
     {
-      error ("call to non-function `%D'", fns);
+      error ("call to non-function %qD", fns);
       return error_mark_node;
     }
 
@@ -5202,16 +5263,16 @@ build_new_method_call (tree instance, tree fns, tree args,
       template_only = 1;
     }
 
-  my_friendly_assert (TREE_CODE (fns) == FUNCTION_DECL
-                     || TREE_CODE (fns) == TEMPLATE_DECL
-                     || TREE_CODE (fns) == OVERLOAD,
-                     20020712);
+  gcc_assert (TREE_CODE (fns) == FUNCTION_DECL
+             || TREE_CODE (fns) == TEMPLATE_DECL
+             || TREE_CODE (fns) == OVERLOAD);
 
   /* XXX this should be handled before we get here.  */
   if (! IS_AGGR_TYPE (basetype))
     {
       if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node)
-       error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
+       error ("request for member %qD in %qE, which is of non-aggregate "
+               "type %qT",
               fns, instance, basetype);
 
       return error_mark_node;
@@ -5224,9 +5285,9 @@ build_new_method_call (tree instance, tree fns, tree args,
     {
       /* Callers should explicitly indicate whether they want to construct
         the complete object or just the part without virtual bases.  */
-      my_friendly_assert (name != ctor_identifier, 20000408);
+      gcc_assert (name != ctor_identifier);
       /* Similarly for destructors.  */
-      my_friendly_assert (name != dtor_identifier, 20000408);
+      gcc_assert (name != dtor_identifier);
     }
 
   /* It's OK to call destructors on cv-qualified objects.  Therefore,
@@ -5289,7 +5350,7 @@ build_new_method_call (tree instance, tree fns, tree args,
          bool free_p;
 
          pretty_name = name_as_c_string (name, basetype, &free_p);
-         error ("no matching function for call to `%T::%s(%A)%#V'",
+         error ("no matching function for call to %<%T::%s(%A)%#V%>",
                 basetype, pretty_name, user_args,
                 TREE_TYPE (TREE_TYPE (instance_ptr)));
          if (free_p)
@@ -5307,7 +5368,7 @@ build_new_method_call (tree instance, tree fns, tree args,
          bool free_p;
 
          pretty_name = name_as_c_string (name, basetype, &free_p);
-         error ("call of overloaded `%s(%A)' is ambiguous", pretty_name,
+         error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
                 user_args);
          print_z_candidates (candidates);
          if (free_p)
@@ -5316,20 +5377,22 @@ build_new_method_call (tree instance, tree fns, tree args,
        }
       else
        {
-         if (DECL_PURE_VIRTUAL_P (cand->fn)
+         if (!(flags & LOOKUP_NONVIRTUAL)
+             && DECL_PURE_VIRTUAL_P (cand->fn)
              && instance == current_class_ref
              && (DECL_CONSTRUCTOR_P (current_function_decl)
-                 || DECL_DESTRUCTOR_P (current_function_decl))
-             && ! (flags & LOOKUP_NONVIRTUAL)
-             && value_member (cand->fn, CLASSTYPE_PURE_VIRTUALS (basetype)))
-           error ((DECL_CONSTRUCTOR_P (current_function_decl) ? 
-                   "abstract virtual `%#D' called from constructor"
-                   : "abstract virtual `%#D' called from destructor"),
-                  cand->fn);
+                 || DECL_DESTRUCTOR_P (current_function_decl)))
+           /* This is not an error, it is runtime undefined
+              behavior.  */
+           warning (0, (DECL_CONSTRUCTOR_P (current_function_decl) ? 
+                     "abstract virtual %q#D called from constructor"
+                     : "abstract virtual %q#D called from destructor"),
+                    cand->fn);
+         
          if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
              && is_dummy_object (instance_ptr))
            {
-             error ("cannot call member function `%D' without object", 
+             error ("cannot call member function %qD without object", 
                     cand->fn);
              call = error_mark_node;
            }
@@ -5347,8 +5410,8 @@ build_new_method_call (tree instance, tree fns, tree args,
              if (TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE
                  && !is_dummy_object (instance_ptr) 
                  && TREE_SIDE_EFFECTS (instance))
-               call = build (COMPOUND_EXPR, TREE_TYPE (call), 
-                             instance, call);
+               call = build2 (COMPOUND_EXPR, TREE_TYPE (call), 
+                              instance, call);
            }
        }
     }
@@ -5356,8 +5419,8 @@ build_new_method_call (tree instance, tree fns, tree args,
   if (processing_template_decl && call != error_mark_node)
     call = (build_min_non_dep
            (CALL_EXPR, call,
-            build_min_nt (COMPONENT_REF, orig_instance, orig_fns),
-            orig_args));
+            build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
+            orig_args, NULL_TREE));
 
  /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -5826,7 +5889,7 @@ source_type (conversion *t)
          || t->kind == ck_identity)
        return t->type;
     }
-  abort ();
+  gcc_unreachable ();
 }
 
 /* Note a warning about preferring WINNER to LOSER.  We do this by storing
@@ -5869,7 +5932,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
   /* If we have two pseudo-candidates for conversions to the same type,
      or two candidates for the same function, arbitrarily pick one.  */
   if (cand1->fn == cand2->fn
-      && (TYPE_P (cand1->fn) || DECL_P (cand1->fn)))
+      && (IS_TYPE_OR_DECL_P (cand1->fn)))
     return 1;
 
   /* a viable function F1
@@ -5887,17 +5950,18 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
   len = cand1->num_convs;
   if (len != cand2->num_convs)
     {
-      if (DECL_STATIC_FUNCTION_P (cand1->fn)
-         && ! DECL_STATIC_FUNCTION_P (cand2->fn))
+      int static_1 = DECL_STATIC_FUNCTION_P (cand1->fn);
+      int static_2 = DECL_STATIC_FUNCTION_P (cand2->fn);
+
+      gcc_assert (static_1 != static_2);
+      
+      if (static_1)
        off2 = 1;
-      else if (! DECL_STATIC_FUNCTION_P (cand1->fn)
-              && DECL_STATIC_FUNCTION_P (cand2->fn))
+      else
        {
          off1 = 1;
          --len;
        }
-      else
-       abort ();
     }
 
   for (i = 0; i < len; ++i)
@@ -5917,7 +5981,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
              && TREE_CODE (t2->type) == INTEGER_TYPE
              && (TYPE_PRECISION (t1->type)
                  == TYPE_PRECISION (t2->type))
-             && (TREE_UNSIGNED (t1->u.next->type)
+             && (TYPE_UNSIGNED (t1->u.next->type)
                  || (TREE_CODE (t1->u.next->type)
                      == ENUMERAL_TYPE)))
            {
@@ -5933,9 +5997,9 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
 
              if (warn)
                {
-                 warning ("passing `%T' chooses `%T' over `%T'",
+                 warning (0, "passing %qT chooses %qT over %qT",
                              type, type1, type2);
-                 warning ("  in call to `%D'", w->fn);
+                 warning (0, "  in call to %qD", w->fn);
                }
              else
                add_warning (w, l);
@@ -5992,10 +6056,10 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
          tree source = source_type (w->convs[0]);
          if (! DECL_CONSTRUCTOR_P (w->fn))
            source = TREE_TYPE (source);
-         warning ("choosing `%D' over `%D'", w->fn, l->fn);
-         warning ("  for conversion from `%T' to `%T'",
+         warning (0, "choosing %qD over %qD", w->fn, l->fn);
+         warning (0, "  for conversion from %qT to %qT",
                   source, w->second_conv->type);
-         warning ("  because conversion sequence for the argument is better");
+         warning (0, "  because conversion sequence for the argument is better");
        }
       else
        add_warning (w, l);
@@ -6008,9 +6072,9 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
      F1 is a non-template function and F2 is a template function
      specialization.  */
          
-  if (! cand1->template && cand2->template)
+  if (!cand1->template_decl && cand2->template_decl)
     return 1;
-  else if (cand1->template && ! cand2->template)
+  else if (cand1->template_decl && !cand2->template_decl)
     return -1;
   
   /* or, if not that,
@@ -6018,11 +6082,11 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
      more specialized than the template for F2 according to the partial
      ordering rules.  */
   
-  if (cand1->template && cand2->template)
+  if (cand1->template_decl && cand2->template_decl)
     {
-      winner = more_specialized
-        (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
-         DEDUCE_ORDER,
+      winner = more_specialized_fn
+        (TI_TEMPLATE (cand1->template_decl),
+         TI_TEMPLATE (cand2->template_decl),
          /* Tell the deduction code how many real function arguments
            we saw, not counting the implicit 'this' argument.  But,
            add_function_candidate() suppresses the "this" argument
@@ -6128,7 +6192,7 @@ the worst conversion for the second:");
         }
     }
 
-  my_friendly_assert (!winner, 20010121);
+  gcc_assert (!winner);
   return 0;
 }
 
@@ -6256,7 +6320,7 @@ perform_implicit_conversion (tree type, tree expr)
                              LOOKUP_NORMAL);
   if (!conv)
     {
-      error ("could not convert `%E' to `%T'", expr, type);
+      error ("could not convert %qE to %qT", expr, type);
       expr = error_mark_node;
     }
   else
@@ -6271,10 +6335,15 @@ perform_implicit_conversion (tree type, tree expr)
 /* Convert EXPR to TYPE (as a direct-initialization) if that is
    permitted.  If the conversion is valid, the converted expression is
    returned.  Otherwise, NULL_TREE is returned, except in the case
-   that TYPE is a class type; in that case, an error is issued.  */
+   that TYPE is a class type; in that case, an error is issued.  If
+   C_CAST_P is true, then this direction initialization is taking
+   place as part of a static_cast being attempted as part of a C-style
+   cast.  */
 
 tree
-perform_direct_initialization_if_possible (tree type, tree expr)
+perform_direct_initialization_if_possible (tree type, 
+                                          tree expr,
+                                          bool c_cast_p)
 {
   conversion *conv;
   void *p;
@@ -6293,8 +6362,7 @@ perform_direct_initialization_if_possible (tree type, tree expr)
     {
       expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
                                        build_tree_list (NULL_TREE, expr),
-                                       TYPE_BINFO (type),
-                                       LOOKUP_NORMAL);
+                                       type, LOOKUP_NORMAL);
       return build_cplus_new (type, expr);
     }
 
@@ -6307,7 +6375,8 @@ perform_direct_initialization_if_possible (tree type, tree expr)
     expr = NULL_TREE;
   else
     expr = convert_like_real (conv, expr, NULL_TREE, 0, 0, 
-                             /*issue_conversion_warnings=*/false);
+                             /*issue_conversion_warnings=*/false,
+                             c_cast_p);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -6328,6 +6397,7 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
   /* Create the variable.  */
   var = build_decl (VAR_DECL, NULL_TREE, type);
   DECL_ARTIFICIAL (var) = 1;
+  DECL_IGNORED_P (var) = 1;
   TREE_USED (var) = 1;
 
   /* Register the variable.  */
@@ -6358,9 +6428,9 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
    the VAR_DECL being initialized with the EXPR.  (In that case, the
    type of DECL will be TYPE.)  If DECL is non-NULL, then CLEANUP must
    also be non-NULL, and with *CLEANUP initialized to NULL.  Upon
-   return, if *CLEANUP is no longer NULL, it will be a CLEANUP_STMT
-   that should be inserted after the returned expression is used to
-   initialize DECL.
+   return, if *CLEANUP is no longer NULL, it will be an expression
+   that should be pushed as a cleanup after the returned expression
+   is used to initialize DECL.
 
    Return the converted expression.  */
 
@@ -6382,11 +6452,11 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
       if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
           && !real_lvalue_p (expr))
         error ("invalid initialization of non-const reference of "
-               "type '%T' from a temporary of type '%T'",
+               "type %qT from a temporary of type %qT",
                type, TREE_TYPE (expr));
       else
         error ("invalid initialization of reference of type "
-              "'%T' from expression of type '%T'", type, 
+              "%qT from expression of type %qT", type, 
               TREE_TYPE (expr));
       return error_mark_node;
     }
@@ -6425,7 +6495,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
 
     we can extend the lifetime of the return value of the conversion
     operator.  */
-  my_friendly_assert (conv->kind == ck_ref_bind, 20030302);
+  gcc_assert (conv->kind == ck_ref_bind);
   if (decl)
     {
       tree var;
@@ -6435,16 +6505,10 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
       conv = conv->u.next;
       /* If the next conversion is a BASE_CONV, skip that too -- but
         remember that the conversion was required.  */
-      if (conv->kind == ck_base && conv->need_temporary_p)
+      if (conv->kind == ck_base)
        {
-         void (*diagnostic_fn) (const char *, ...);
          if (conv->check_copy_constructor_p)
-           /* Generate a temporary copy purely to generate the required
-              diagnostics.  */
-           build_temp (build_dummy_object (TREE_TYPE (expr)),
-                       TREE_TYPE (expr),
-                       LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
-                       &diagnostic_fn);
+           check_constructor_callable (TREE_TYPE (expr), expr);
          base_conv_type = conv->type;
          conv = conv->u.next;
        }
@@ -6454,78 +6518,88 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
       expr = convert_like_real (conv, expr,
                                /*fn=*/NULL_TREE, /*argnum=*/0,
                                /*inner=*/-1,
-                               /*issue_conversion_warnings=*/true);
-      if (!real_lvalue_p (expr))
+                               /*issue_conversion_warnings=*/true,
+                               /*c_cast_p=*/false);
+      if (error_operand_p (expr))
+       expr = error_mark_node;
+      else
        {
-         tree init;
-         tree type;
-
-         /* Create the temporary variable.  */
-         type = TREE_TYPE (expr);
-         var = make_temporary_var_for_ref_to_temp (decl, type);
-         layout_decl (var, 0);
-         /* If the rvalue is the result of a function call it will be
-            a TARGET_EXPR.  If it is some other construct (such as a
-            member access expression where the underlying object is
-            itself the result of a function call), turn it into a
-            TARGET_EXPR here.  It is important that EXPR be a
-            TARGET_EXPR below since otherwise the INIT_EXPR will
-            attempt to make a bitwise copy of EXPR to initialize
-            VAR. */
-         if (TREE_CODE (expr) != TARGET_EXPR)
-           expr = get_target_expr (expr);
-         /* Create the INIT_EXPR that will initialize the temporary
-            variable.  */
-         init = build (INIT_EXPR, type, var, expr);
-         if (at_function_scope_p ())
+         if (!real_lvalue_p (expr))
            {
-             add_decl_stmt (var);
-             *cleanup = cxx_maybe_build_cleanup (var);
-             if (*cleanup)
-               /* We must be careful to destroy the temporary only
-                  after its initialization has taken place.  If the
-                  initialization throws an exception, then the
-                  destructor should not be run.  We cannot simply
-                  transform INIT into something like:
-            
-                    (INIT, ({ CLEANUP_STMT; }))
-
-                  because emit_local_var always treats the
-                  initializer as a full-expression.  Thus, the
-                  destructor would run too early; it would run at the
-                  end of initializing the reference variable, rather
-                  than at the end of the block enclosing the
-                  reference variable.
-
-                  The solution is to pass back a CLEANUP_STMT which
-                  the caller is responsible for attaching to the
-                  statement tree.  */
-               *cleanup = build_stmt (CLEANUP_STMT, var, *cleanup);
+             tree init;
+             tree type;
+
+             /* Create the temporary variable.  */
+             type = TREE_TYPE (expr);
+             var = make_temporary_var_for_ref_to_temp (decl, type);
+             layout_decl (var, 0);
+             /* If the rvalue is the result of a function call it will be
+                a TARGET_EXPR.  If it is some other construct (such as a
+                member access expression where the underlying object is
+                itself the result of a function call), turn it into a
+                TARGET_EXPR here.  It is important that EXPR be a
+                TARGET_EXPR below since otherwise the INIT_EXPR will
+                attempt to make a bitwise copy of EXPR to initialize
+                VAR.  */
+             if (TREE_CODE (expr) != TARGET_EXPR)
+               expr = get_target_expr (expr);
+             /* Create the INIT_EXPR that will initialize the temporary
+                variable.  */
+             init = build2 (INIT_EXPR, type, var, expr);
+             if (at_function_scope_p ())
+               {
+                 add_decl_expr (var);
+                 *cleanup = cxx_maybe_build_cleanup (var);
+
+                 /* We must be careful to destroy the temporary only
+                    after its initialization has taken place.  If the
+                    initialization throws an exception, then the
+                    destructor should not be run.  We cannot simply
+                    transform INIT into something like:
+
+                        (INIT, ({ CLEANUP_STMT; }))
+
+                    because emit_local_var always treats the
+                    initializer as a full-expression.  Thus, the
+                    destructor would run too early; it would run at the
+                    end of initializing the reference variable, rather
+                    than at the end of the block enclosing the
+                    reference variable.
+
+                    The solution is to pass back a cleanup expression
+                    which the caller is responsible for attaching to
+                    the statement tree.  */
+               }
+             else
+               {
+                 rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
+                 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+                   static_aggregates = tree_cons (NULL_TREE, var,
+                                                  static_aggregates);
+               }
+             /* Use its address to initialize the reference variable.  */
+             expr = build_address (var);
+             if (base_conv_type)
+               expr = convert_to_base (expr, 
+                                       build_pointer_type (base_conv_type),
+                                       /*check_access=*/true,
+                                       /*nonnull=*/true);
+             expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
            }
          else
-           {
-             rest_of_decl_compilation (var, NULL, /*toplev=*/1, at_eof);
-             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
-               static_aggregates = tree_cons (NULL_TREE, var,
-                                              static_aggregates);
-           }
-         /* Use its address to initialize the reference variable.  */
-         expr = build_address (var);
-         expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
+           /* Take the address of EXPR.  */
+           expr = build_unary_op (ADDR_EXPR, expr, 0);
+         /* If a BASE_CONV was required, perform it now.  */
+         if (base_conv_type)
+           expr = (perform_implicit_conversion 
+                   (build_pointer_type (base_conv_type), expr));
+         expr = build_nop (type, expr);
        }
-      else
-       /* Take the address of EXPR.  */
-       expr = build_unary_op (ADDR_EXPR, expr, 0);
-      /* If a BASE_CONV was required, perform it now.  */
-      if (base_conv_type)
-       expr = (perform_implicit_conversion 
-               (build_pointer_type (base_conv_type), expr));
-      expr = build_nop (type, expr);
     }
   else
     /* Perform the conversion.  */
     expr = convert_like (conv, expr);
-  
+
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);