OSDN Git Service

* c-common.h (check_function_format): Remove first parameter.
[pf3gnuchains/gcc-fork.git] / gcc / cp / typeck.c
index da07fea..1dfb337 100644 (file)
@@ -1,6 +1,6 @@
 /* Build expressions with type checking for C++ compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -24,11 +24,7 @@ Boston, MA 02111-1307, USA.  */
 /* This file is part of the C++ front end.
    It contains routines to build C++ expressions given their operands,
    including computing the types of the result, C and C++ specific error
-   checks, and some optimization.
-
-   There are also routines to build RETURN_STMT nodes and CASE_STMT nodes,
-   and to process initializations in declarations (since they work
-   like a strange sort of assignment).  */
+   checks, and some optimization.  */
 
 #include "config.h"
 #include "system.h"
@@ -54,7 +50,6 @@ static int comp_ptr_ttypes_const (tree, tree);
 static bool comp_except_types (tree, tree, bool);
 static bool comp_array_types (tree, tree, bool);
 static tree common_base_type (tree, tree);
-static tree lookup_anon_field (tree, tree);
 static tree pointer_diff (tree, tree, tree);
 static tree get_delta_difference (tree, tree, int);
 static void casts_away_constness_r (tree *, tree *);
@@ -96,6 +91,9 @@ require_complete_type (tree value)
   else
     type = TREE_TYPE (value);
 
+  if (type == error_mark_node)
+    return error_mark_node;
+
   /* First, detect a valid value with a complete type.  */
   if (COMPLETE_TYPE_P (type))
     return value;
@@ -124,7 +122,7 @@ complete_type (tree type)
   else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
     {
       tree t = complete_type (TREE_TYPE (type));
-      if (COMPLETE_TYPE_P (t) && ! processing_template_decl)
+      if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
        layout_type (type);
       TYPE_NEEDS_CONSTRUCTING (type)
        = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
@@ -163,8 +161,7 @@ complete_type_or_diagnostic (tree type, tree value, int diag_type)
 int
 type_unknown_p (tree exp)
 {
-  return (TREE_CODE (exp) == OVERLOAD
-          || TREE_CODE (exp) == TREE_LIST
+  return (TREE_CODE (exp) == TREE_LIST
          || TREE_TYPE (exp) == unknown_type_node);
 }
 
@@ -348,7 +345,7 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
          || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_integer_type_node))
        {
-         tree t = ((TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
+         tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
                    ? long_long_unsigned_type_node 
                    : long_long_integer_type_node);
          return build_type_attribute_variant (t, attributes);
@@ -362,12 +359,12 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
          || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
        {
-         tree t = ((TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
+         tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
                    ? long_unsigned_type_node : long_integer_type_node);
          return build_type_attribute_variant (t, attributes);
        }
       /* Otherwise prefer the unsigned one.  */
-      if (TREE_UNSIGNED (t1))
+      if (TYPE_UNSIGNED (t1))
        return build_type_attribute_variant (t1, attributes);
       else
        return build_type_attribute_variant (t2, attributes);
@@ -443,7 +440,6 @@ composite_pointer_type_r (tree t1, tree t2, const char* location)
   result_type = cp_build_qualified_type (result_type,
                                         (cp_type_quals (pointee1)
                                          | cp_type_quals (pointee2)));
-  result_type = build_pointer_type (result_type);
   /* If the original types were pointers to members, so is the
      result.  */
   if (TYPE_PTR_TO_MEMBER_P (t1))
@@ -456,6 +452,8 @@ composite_pointer_type_r (tree t1, tree t2, const char* location)
       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
                                       result_type);
     }
+  else
+    result_type = build_pointer_type (result_type);
 
   /* Merge the attributes.  */
   attributes = (*targetm.merge_type_attributes) (t1, t2);
@@ -579,8 +577,8 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
 tree
 merge_types (tree t1, tree t2)
 {
-  register enum tree_code code1;
-  register enum tree_code code2;
+  enum tree_code code1;
+  enum tree_code code2;
   tree attributes;
 
   /* Save time if the two types are the same.  */
@@ -666,9 +664,9 @@ merge_types (tree t1, tree t2)
 
        /* Save space: see if the result is identical to one of the args.  */
        if (valtype == TREE_TYPE (t1) && ! p2)
-         return build_type_attribute_variant (t1, attributes);
+         return cp_build_type_attribute_variant (t1, attributes);
        if (valtype == TREE_TYPE (t2) && ! p1)
-         return build_type_attribute_variant (t2, attributes);
+         return cp_build_type_attribute_variant (t2, attributes);
 
        /* Simple way if one arg fails to specify argument types.  */
        if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
@@ -676,7 +674,7 @@ merge_types (tree t1, tree t2)
            rval = build_function_type (valtype, p2);
            if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
              rval = build_exception_variant (rval, raises);
-           return build_type_attribute_variant (rval, attributes);
+           return cp_build_type_attribute_variant (rval, attributes);
          }
        raises = TYPE_RAISES_EXCEPTIONS (t1);
        if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
@@ -684,7 +682,7 @@ merge_types (tree t1, tree t2)
            rval = build_function_type (valtype, p1);
            if (raises)
              rval = build_exception_variant (rval, raises);
-           return build_type_attribute_variant (rval, attributes);
+           return cp_build_type_attribute_variant (rval, attributes);
          }
 
        rval = build_function_type (valtype, commonparms (p1, p2));
@@ -714,9 +712,15 @@ merge_types (tree t1, tree t2)
        break;
       }
 
+    case TYPENAME_TYPE:
+      /* There is no need to merge attributes into a TYPENAME_TYPE.
+        When the type is instantiated it will have whatever
+        attributes result from the instantiation.  */
+      return t1;
+
     default:;
     }
-  return build_type_attribute_variant (t1, attributes);
+  return cp_build_type_attribute_variant (t1, attributes);
 }
 
 /* Return the common type of two types.
@@ -857,6 +861,7 @@ comp_array_types (tree t1, tree t2, bool allow_redeclaration)
 {
   tree d1;
   tree d2;
+  tree max1, max2;
 
   if (t1 == t2)
     return true;
@@ -887,8 +892,27 @@ comp_array_types (tree t1, tree t2, bool allow_redeclaration)
     return allow_redeclaration;
 
   /* Check that the dimensions are the same.  */
-  return (cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
-         && cp_tree_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)));
+
+  if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
+    return false;
+  max1 = TYPE_MAX_VALUE (d1);
+  max2 = TYPE_MAX_VALUE (d2);
+  if (processing_template_decl && !abi_version_at_least (2)
+      && !value_dependent_expression_p (max1)
+      && !value_dependent_expression_p (max2))
+    {
+      /* With abi-1 we do not fold non-dependent array bounds, (and
+         consequently mangle them incorrectly).  We must therefore
+         fold them here, to verify the domains have the same
+         value.  */
+      max1 = fold (max1);
+      max2 = fold (max2);
+    }
+
+  if (!cp_tree_equal (max1, max2))
+    return false;
+
+  return true;
 }
 
 /* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
@@ -900,11 +924,8 @@ comptypes (tree t1, tree t2, int strict)
   if (t1 == t2)
     return true;
 
-  /* This should never happen.  */
-  my_friendly_assert (t1 != error_mark_node, 307);
-
-  /* Suppress errors caused by previously reported errors */
-  if (t2 == error_mark_node)
+  /* Suppress errors caused by previously reported errors.  */
+  if (t1 == error_mark_node || t2 == error_mark_node)
     return false;
   
   my_friendly_assert (TYPE_P (t1) && TYPE_P (t2), 20030623);
@@ -930,12 +951,12 @@ comptypes (tree t1, tree t2, int strict)
   /* If either type is the internal version of sizetype, use the
      language version.  */
   if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
-      && TYPE_DOMAIN (t1))
-    t1 = TYPE_DOMAIN (t1);
+      && TYPE_ORIG_SIZE_TYPE (t1))
+    t1 = TYPE_ORIG_SIZE_TYPE (t1);
 
   if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
-      && TYPE_DOMAIN (t2))
-    t2 = TYPE_DOMAIN (t2);
+      && TYPE_ORIG_SIZE_TYPE (t2))
+    t2 = TYPE_ORIG_SIZE_TYPE (t2);
 
   if (TYPE_PTRMEMFUNC_P (t1))
     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
@@ -946,8 +967,10 @@ comptypes (tree t1, tree t2, int strict)
   if (TREE_CODE (t1) != TREE_CODE (t2))
     return false;
 
-  /* Qualifiers must match.  */
-  if (cp_type_quals (t1) != cp_type_quals (t2))
+  /* Qualifiers must match.  For array types, we will check when we
+     recur on the array element types.  */
+  if (TREE_CODE (t1) != ARRAY_TYPE
+      && TYPE_QUALS (t1) != TYPE_QUALS (t2))
     return false;
   if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
     return false;
@@ -956,7 +979,8 @@ comptypes (tree t1, tree t2, int strict)
      definition.  Note that we already checked for equality of the type
      qualifiers (just above).  */
 
-  if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+  if (TREE_CODE (t1) != ARRAY_TYPE
+      && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     return true;
 
   if (!(*targetm.comp_type_attributes) (t1, t2))
@@ -977,7 +1001,7 @@ comptypes (tree t1, tree t2, int strict)
        return true;
       /* Don't check inheritance.  */
       strict = COMPARE_STRICT;
-      /* fall through */
+      /* Fall through.  */
 
     case RECORD_TYPE:
     case UNION_TYPE:
@@ -998,7 +1022,7 @@ comptypes (tree t1, tree t2, int strict)
       if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
                      strict & ~COMPARE_REDECLARATION))
        return false;
-      /* FALLTHROUGH*/
+      /* Fall through.  */
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
@@ -1032,6 +1056,11 @@ comptypes (tree t1, tree t2, int strict)
     case COMPLEX_TYPE:
       return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
 
+    case VECTOR_TYPE:
+      return TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+            && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
+      break;
+
     default:
       break;
     }
@@ -1170,7 +1199,7 @@ compparms (tree parms1, tree parms2)
         they fail to match.  */
       if (!t1 || !t2)
        return false;
-      if (!same_type_p (TREE_VALUE (t2), TREE_VALUE (t1)))
+      if (!same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
        return false;
     }
   return true;
@@ -1236,6 +1265,7 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
     }
   
   if (TREE_CODE (e) == COMPONENT_REF
+      && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
       && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
     {
       error ("invalid application of `%s' to a bit-field", op_name);
@@ -1258,6 +1288,33 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
 }
   
 \f
+/* EXPR is being used in a context that is not a function call.
+   Enforce:
+
+     [expr.ref] 
+
+     The expression can be used only as the left-hand operand of a
+     member function call.  
+
+     [expr.mptr.operator]
+
+     If the result of .* or ->* is a function, then that result can be
+     used only as the operand for the function call operator ().  
+
+   by issuing an error message if appropriate.  Returns true iff EXPR
+   violates these rules.  */
+
+bool
+invalid_nonstatic_memfn_p (tree expr)
+{
+  if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
+    {
+      error ("invalid use of non-static member function");
+      return true;
+    }
+  return false;
+}
+
 /* Perform the conversions in [expr] that apply when an lvalue appears
    in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
    function-to-pointer conversions.
@@ -1267,8 +1324,8 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
 tree
 decay_conversion (tree exp)
 {
-  register tree type;
-  register enum tree_code code;
+  tree type;
+  enum tree_code code;
 
   type = TREE_TYPE (exp);
   code = TREE_CODE (type);
@@ -1310,16 +1367,13 @@ decay_conversion (tree exp)
       error ("void value not ignored as it ought to be");
       return error_mark_node;
     }
-  if (code == METHOD_TYPE)
-    {
-      error ("invalid use of non-static member function");
-      return error_mark_node;
-    }
+  if (invalid_nonstatic_memfn_p (exp))
+    return error_mark_node;
   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
     return build_unary_op (ADDR_EXPR, exp, 0);
   if (code == ARRAY_TYPE)
     {
-      register tree adr;
+      tree adr;
       tree ptrtype;
 
       if (TREE_CODE (exp) == INDIRECT_REF)
@@ -1344,15 +1398,9 @@ decay_conversion (tree exp)
 
       if (TREE_CODE (exp) == VAR_DECL)
        {
-         /* ??? This is not really quite correct
-            in that the type of the operand of ADDR_EXPR
-            is not the target type of the type of the ADDR_EXPR itself.
-            Question is, can this lossage be avoided?  */
-         adr = build1 (ADDR_EXPR, ptrtype, exp);
          if (!cxx_mark_addressable (exp))
            return error_mark_node;
-         TREE_CONSTANT (adr) = staticp (exp);
-         TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
+         adr = build_nop (ptrtype, build_address (exp));
          return adr;
        }
       /* This way is better for a COMPONENT_REF since it can
@@ -1471,7 +1519,8 @@ rationalize_conditional_expr (enum tree_code code, tree t)
        build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR
                                                    ? LE_EXPR : GE_EXPR),
                                                   TREE_OPERAND (t, 0),
-                                                  TREE_OPERAND (t, 1)),
+                                                  TREE_OPERAND (t, 1),
+                                                  /*overloaded_p=*/NULL),
                            build_unary_op (code, TREE_OPERAND (t, 0), 0),
                            build_unary_op (code, TREE_OPERAND (t, 1), 0));
     }
@@ -1487,7 +1536,7 @@ rationalize_conditional_expr (enum tree_code code, tree t)
    anonymous unions can nest, we must also search all anonymous unions
    that are directly reachable.  */
 
-static tree
+tree
 lookup_anon_field (tree t, tree type)
 {
   tree field;
@@ -1552,7 +1601,8 @@ build_class_member_access_expr (tree object, tree member,
      The type of the first expression shall be "class object" (of a
      complete type).  */
   object_type = TREE_TYPE (object);
-  if (!complete_type_or_else (object_type, object))
+  if (!currently_open_class (object_type) 
+      && !complete_type_or_else (object_type, object))
     return error_mark_node;
   if (!CLASS_TYPE_P (object_type))
     {
@@ -1702,7 +1752,8 @@ build_class_member_access_expr (tree object, tree member,
          member_type = cp_build_qualified_type (member_type, type_quals);
        }
 
-      result = fold (build (COMPONENT_REF, member_type, object, member));
+      result = fold (build (COMPONENT_REF, member_type, object, member,
+                           NULL_TREE));
 
       /* Mark the expression const or volatile, as appropriate.  Even
         though we've dealt with the type above, we still have to mark the
@@ -1729,7 +1780,7 @@ build_class_member_access_expr (tree object, tree member,
        type = unknown_type_node;
       /* Note that we do not convert OBJECT to the BASELINK_BINFO
         base.  That will happen when the function is called.  */
-      result = build (COMPONENT_REF, type, object, member);
+      result = build (COMPONENT_REF, type, object, member, NULL_TREE);
     }
   else if (TREE_CODE (member) == CONST_DECL)
     {
@@ -1764,6 +1815,7 @@ lookup_destructor (tree object, tree scope, tree dtor_name)
 {
   tree object_type = TREE_TYPE (object);
   tree dtor_type = TREE_OPERAND (dtor_name, 0);
+  tree expr;
 
   if (scope && !check_dtor_name (scope, dtor_name))
     {
@@ -1771,17 +1823,20 @@ lookup_destructor (tree object, tree scope, tree dtor_name)
             scope, dtor_type);
       return error_mark_node;
     }
-  if (!same_type_p (dtor_type, TYPE_MAIN_VARIANT (object_type)))
+  if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
     {
-      error ("destructor name `%T' does not match type `%T' of expression",
-            dtor_type, object_type);
+      error ("the type being destroyed is `%T', but the destructor refers to `%T'",
+            TYPE_MAIN_VARIANT (object_type), dtor_type);
       return error_mark_node;
     }
-  if (!TYPE_HAS_DESTRUCTOR (object_type))
+  if (!TYPE_HAS_DESTRUCTOR (dtor_type))
     return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope,
                  dtor_type);
-  return lookup_member (object_type, complete_dtor_identifier,
+  expr = lookup_member (dtor_type, complete_dtor_identifier,
                        /*protect=*/1, /*want_type=*/false);
+  expr = (adjust_result_of_qualified_name_lookup
+         (expr, dtor_type, object_type));
+  return expr;
 }
 
 /* This function is called by the parser to process a class member
@@ -1811,6 +1866,9 @@ finish_class_member_access_expr (tree object, tree name)
     {
       if (/* If OBJECT_TYPE is dependent, so is OBJECT.NAME.  */
          dependent_type_p (object_type)
+         /* If NAME is just an IDENTIFIER_NODE, then the expression
+            is dependent.  */
+         || TREE_CODE (object) == IDENTIFIER_NODE
          /* If NAME is "f<args>", where either 'f' or 'args' is
             dependent, then the expression is dependent.  */
          || (TREE_CODE (name) == TEMPLATE_ID_EXPR
@@ -1821,7 +1879,7 @@ finish_class_member_access_expr (tree object, tree name)
          || (TREE_CODE (name) == SCOPE_REF
              && TYPE_P (TREE_OPERAND (name, 0))
              && dependent_type_p (TREE_OPERAND (name, 0))))
-       return build_min_nt (COMPONENT_REF, object, name);
+       return build_min_nt (COMPONENT_REF, object, name, NULL_TREE);
       object = build_non_dependent_expr (object);
     }
   
@@ -1835,7 +1893,8 @@ finish_class_member_access_expr (tree object, tree name)
 
      The type of the first expression shall be "class object" (of a
      complete type).  */
-  if (!complete_type_or_else (object_type, object))
+  if (!currently_open_class (object_type) 
+      && !complete_type_or_else (object_type, object))
     return error_mark_node;
   if (!CLASS_TYPE_P (object_type))
     {
@@ -1863,6 +1922,11 @@ finish_class_member_access_expr (tree object, tree name)
          is_template_id = true;
          template_args = TREE_OPERAND (name, 1);
          name = TREE_OPERAND (name, 0);
+
+         if (TREE_CODE (name) == OVERLOAD)
+           name = DECL_NAME (get_first_fn (name));
+         else if (DECL_P (name))
+           name = DECL_NAME (name);
        }
 
       if (TREE_CODE (name) == SCOPE_REF)
@@ -1891,8 +1955,13 @@ finish_class_member_access_expr (tree object, tree name)
 
          /* Find the base of OBJECT_TYPE corresponding to SCOPE.  */
          access_path = lookup_base (object_type, scope, ba_check, NULL);
-         if (!access_path || access_path == error_mark_node)
+         if (access_path == error_mark_node)
            return error_mark_node;
+         if (!access_path)
+           {
+             error ("`%T' is not a base of `%T'", scope, object_type);
+             return error_mark_node;
+           }
        }
       else
        {
@@ -1937,7 +2006,7 @@ finish_class_member_access_expr (tree object, tree name)
                                         /*preserve_reference=*/false);
   if (processing_template_decl && expr != error_mark_node)
     return build_min_non_dep (COMPONENT_REF, expr,
-                             orig_object, orig_name);
+                             orig_object, orig_name, NULL_TREE);
   return expr;
 }
 
@@ -1965,7 +2034,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
                          /*want_type=*/false);
   member_type = cp_build_qualified_type (TREE_TYPE (member),
                                         cp_type_quals (ptrmem_type));
-  return fold (build (COMPONENT_REF, member_type, ptrmem, member));
+  return fold (build (COMPONENT_REF, member_type, ptrmem, member, NULL_TREE));
 }
 
 /* Given an expression PTR for a pointer, return an expression
@@ -1989,7 +2058,7 @@ build_x_indirect_ref (tree expr, const char *errorstring)
     }
 
   rval = build_new_op (INDIRECT_REF, LOOKUP_NORMAL, expr, NULL_TREE,
-                      NULL_TREE);
+                      NULL_TREE, /*overloaded_p=*/NULL);
   if (!rval)
     rval = build_indirect_ref (expr, errorstring);
 
@@ -2002,7 +2071,7 @@ build_x_indirect_ref (tree expr, const char *errorstring)
 tree
 build_indirect_ref (tree ptr, const char *errorstring)
 {
-  register tree pointer, type;
+  tree pointer, type;
 
   if (ptr == error_mark_node)
     return error_mark_node;
@@ -2113,8 +2182,7 @@ build_array_ref (tree array, tree idx)
       break;
     }
 
-  if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
-      && TREE_CODE (array) != INDIRECT_REF)
+  if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
     {
       tree rval, type;
 
@@ -2159,8 +2227,8 @@ build_array_ref (tree array, tree idx)
         would get a crash in store_bit_field/extract_bit_field when trying
         to access a non-existent part of the register.  */
       if (TREE_CODE (idx) == INTEGER_CST
-         && TYPE_VALUES (TREE_TYPE (array))
-         && ! int_fits_type_p (idx, TYPE_VALUES (TREE_TYPE (array))))
+         && TYPE_DOMAIN (TREE_TYPE (array))
+         && ! int_fits_type_p (idx, TYPE_DOMAIN (TREE_TYPE (array))))
        {
          if (!cxx_mark_addressable (array))
            return error_mark_node;
@@ -2182,7 +2250,7 @@ build_array_ref (tree array, tree idx)
        }
 
       type = TREE_TYPE (TREE_TYPE (array));
-      rval = build (ARRAY_REF, type, array, idx);
+      rval = build (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
       /* Array ref is const/volatile if the array elements are
         or if the array is..  */
       TREE_READONLY (rval)
@@ -2316,6 +2384,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
       e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
       e2 = build_indirect_ref (e2, NULL);
       TREE_CONSTANT (e2) = 1;
+      TREE_INVARIANT (e2) = 1;
 
       /* When using function descriptors, the address of the
         vtable entry is treated as a function pointer.  */
@@ -2340,10 +2409,9 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
 tree
 build_function_call (tree function, tree params)
 {
-  register tree fntype, fndecl;
-  register tree coerced_params;
-  tree result;
-  tree name = NULL_TREE, assembler_name = NULL_TREE;
+  tree fntype, fndecl;
+  tree coerced_params;
+  tree name = NULL_TREE;
   int is_method;
   tree original = function;
 
@@ -2356,7 +2424,6 @@ build_function_call (tree function, tree params)
   if (TREE_CODE (function) == FUNCTION_DECL)
     {
       name = DECL_NAME (function);
-      assembler_name = DECL_ASSEMBLER_NAME (function);
 
       mark_used (function);
       fndecl = function;
@@ -2419,23 +2486,9 @@ build_function_call (tree function, tree params)
   /* Check for errors in format strings.  */
 
   if (warn_format)
-    check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params);
-
-  /* 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 (function) == ADDR_EXPR
-      && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
-      && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
-    {
-      result = expand_tree_builtin (TREE_OPERAND (function, 0),
-                                   params, coerced_params);
-      if (result)
-       return result;
-    }
+    check_function_format (TYPE_ATTRIBUTES (fntype), coerced_params);
 
-  return build_cxx_call (function, params, coerced_params);
+  return build_cxx_call (function, coerced_params);
 }
 \f
 /* Convert the actual parameter expressions in the list VALUES
@@ -2458,8 +2511,8 @@ build_function_call (tree function, tree params)
 tree
 convert_arguments (tree typelist, tree values, tree fndecl, int flags)
 {
-  register tree typetail, valtail;
-  register tree result = NULL_TREE;
+  tree typetail, valtail;
+  tree result = NULL_TREE;
   const char *called_thing = 0;
   int i = 0;
 
@@ -2484,8 +2537,8 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
        valtail;
        valtail = TREE_CHAIN (valtail), i++)
     {
-      register tree type = typetail ? TREE_VALUE (typetail) : 0;
-      register tree val = TREE_VALUE (valtail);
+      tree type = typetail ? TREE_VALUE (typetail) : 0;
+      tree val = TREE_VALUE (valtail);
 
       if (val == error_mark_node)
        return error_mark_node;
@@ -2532,8 +2585,12 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
 
          if (!COMPLETE_TYPE_P (complete_type (type)))
            {
-             error ("parameter type of called function is incomplete");
-             parmval = val;
+             if (fndecl)
+               error ("parameter %P of `%D' has incomplete type `%T'",
+                      i, fndecl, type);
+             else
+               error ("parameter %P has incomplete type `%T'", i, type);
+             parmval = error_mark_node;
            }
          else
            {
@@ -2571,7 +2628,7 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
 
   if (typetail != 0 && typetail != void_list_node)
     {
-      /* See if there are default arguments that can be used */
+      /* See if there are default arguments that can be used */
       if (TREE_PURPOSE (typetail) 
          && TREE_CODE (TREE_PURPOSE (typetail)) != DEFAULT_ARG)
        {
@@ -2613,7 +2670,8 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
    conversions on the operands.  CODE is the kind of expression to build.  */
 
 tree
-build_x_binary_op (enum tree_code code, tree arg1, tree arg2)
+build_x_binary_op (enum tree_code code, tree arg1, tree arg2, 
+                  bool *overloaded_p)
 {
   tree orig_arg1;
   tree orig_arg2;
@@ -2634,7 +2692,8 @@ build_x_binary_op (enum tree_code code, tree arg1, tree arg2)
   if (code == DOTSTAR_EXPR)
     expr = build_m_component_ref (arg1, arg2);
   else
-    expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE);
+    expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE, 
+                        overloaded_p);
 
   if (processing_template_decl && expr != error_mark_node)
     return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
@@ -2665,17 +2724,17 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
                 int convert_p ATTRIBUTE_UNUSED)
 {
   tree op0, op1;
-  register enum tree_code code0, code1;
+  enum tree_code code0, code1;
   tree type0, type1;
 
   /* Expression code to give to the expression when it is built.
      Normally this is CODE, which is what the caller asked for,
      but in some special cases we change it.  */
-  register enum tree_code resultcode = code;
+  enum tree_code resultcode = code;
 
   /* Data type in which the computation is to be performed.
      In the simplest cases this is the common type of the arguments.  */
-  register tree result_type = NULL;
+  tree result_type = NULL;
 
   /* Nonzero means operands have already been type-converted
      in whatever way is necessary.
@@ -2825,7 +2884,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
               point, so we have to dig out the original type to find out if
               it was unsigned.  */
            shorten = ((TREE_CODE (op0) == NOP_EXPR
-                       && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
+                       && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
                       || (TREE_CODE (op1) == INTEGER_CST
                           && ! integer_all_onesp (op1)));
 
@@ -2854,7 +2913,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
             quotient can't be represented in the computation mode.  We shorten
             only if unsigned or if dividing by something we know != -1.  */
          shorten = ((TREE_CODE (op0) == NOP_EXPR
-                     && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
+                     && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
                     || (TREE_CODE (op1) == INTEGER_CST
                         && ! integer_all_onesp (op1)));
          common = 1;
@@ -3113,7 +3172,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
          tree arg0 = get_narrower (op0, &unsigned0);
          tree arg1 = get_narrower (op1, &unsigned1);
          /* UNS is 1 if the operation to be done is an unsigned one.  */
-         int uns = TREE_UNSIGNED (result_type);
+         int uns = TYPE_UNSIGNED (result_type);
          tree type;
 
          final_type = result_type;
@@ -3122,9 +3181,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
             but it *requires* conversion to FINAL_TYPE.  */
 
          if (op0 == arg0 && TREE_TYPE (op0) != final_type)
-           unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0));
+           unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0));
          if (op1 == arg1 && TREE_TYPE (op1) != final_type)
-           unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1));
+           unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1));
 
          /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE.  */
 
@@ -3176,7 +3235,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
          final_type = result_type;
 
          if (arg0 == op0 && final_type == TREE_TYPE (op0))
-           unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
+           unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0));
 
          if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
              /* We can shorten only if the shift count is less than the
@@ -3189,7 +3248,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
                 ones made by sign-extension and bring in zeros.
                 We can't optimize that case at all, but in most machines
                 it never happens because available widths are 2**N.  */
-             && (!TREE_UNSIGNED (final_type)
+             && (!TYPE_UNSIGNED (final_type)
                  || unsigned_arg
                  || (((unsigned) 2 * TYPE_PRECISION (TREE_TYPE (arg0)))
                      <= TYPE_PRECISION (result_type))))
@@ -3231,8 +3290,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
             bound the ranges of the arguments until that point.  */
          && !processing_template_decl)
        {
-         int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
-         int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
+         int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0));
+         int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1));
 
          int unsignedp0, unsignedp1;
          tree primop0 = get_narrower (op0, &unsignedp0);
@@ -3256,7 +3315,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
          /* Do not warn if the comparison is being done in a signed type,
             since the signed type will only be chosen if it can represent
             all the values of the unsigned type.  */
-         if (! TREE_UNSIGNED (result_type))
+         if (!TYPE_UNSIGNED (result_type))
            /* OK */;
          /* Do not warn if both operands are unsigned.  */
          else if (op0_signed == op1_signed)
@@ -3384,15 +3443,10 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
     build_type = result_type;
 
   {
-    register tree result = build (resultcode, build_type, op0, op1);
-    register tree folded;
-
-    folded = fold (result);
-    if (folded == result)
-      TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
+    tree result = fold (build (resultcode, build_type, op0, op1));
     if (final_type != 0)
-      return cp_convert (final_type, folded);
-    return folded;
+      result = cp_convert (final_type, result);
+    return result;
   }
 }
 \f
@@ -3400,8 +3454,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
    of pointer PTROP and integer INTOP.  */
 
 static tree
-cp_pointer_int_sum (enum tree_code resultcode, register tree ptrop,
-                   register tree intop)
+cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
 {
   tree res_type = TREE_TYPE (ptrop);
 
@@ -3419,9 +3472,9 @@ cp_pointer_int_sum (enum tree_code resultcode, register tree ptrop,
    The resulting tree has type int.  */
 
 static tree
-pointer_diff (register tree op0, register tree op1, register tree ptrtype)
+pointer_diff (tree op0, tree op1, tree ptrtype)
 {
-  register tree result, folded;
+  tree result;
   tree restype = ptrdiff_type_node;
   tree target_type = TREE_TYPE (ptrtype);
 
@@ -3456,11 +3509,7 @@ pointer_diff (register tree op0, register tree op1, register tree ptrtype)
   /* Do the division.  */
 
   result = build (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
-
-  folded = fold (result);
-  if (folded == result)
-    TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
-  return folded;
+  return fold (result);
 }
 \f
 /* Construct and perhaps optimize a tree representation
@@ -3483,16 +3532,23 @@ build_x_unary_op (enum tree_code code, tree xarg)
 
   exp = NULL_TREE;
 
-  /* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an
-     error message.  */
+  /* [expr.unary.op] says:
+
+       The address of an object of incomplete type can be taken.
+
+     (And is just the ordinary address operator, not an overloaded
+     "operator &".)  However, if the type is a template
+     specialization, we must complete the type at this point so that
+     an overloaded "operator &" will be available if required.  */
   if (code == ADDR_EXPR
       && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
-      && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
-          && !COMPLETE_TYPE_P (TREE_TYPE (xarg)))
+      && ((CLASS_TYPE_P (TREE_TYPE (xarg))
+          && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
          || (TREE_CODE (xarg) == OFFSET_REF)))
-    /* don't look for a function */;
+    /* Don't look for a function.  */;
   else
-    exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE);
+    exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE,
+                       /*overloaded_p=*/NULL);
   if (!exp && code == ADDR_EXPR)
     {
       /*  A pointer to member-function can be formed only by saying
@@ -3581,11 +3637,7 @@ build_address (tree t)
   if (error_operand_p (t) || !cxx_mark_addressable (t))
     return error_mark_node;
 
-  addr = build1 (ADDR_EXPR, 
-                build_pointer_type (TREE_TYPE (t)),
-                t);
-  if (staticp (t))
-    TREE_CONSTANT (addr) = 1;
+  addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
 
   return addr;
 }
@@ -3595,16 +3647,9 @@ build_address (tree t)
 tree
 build_nop (tree type, tree expr)
 {
-  tree nop;
-
   if (type == error_mark_node || error_operand_p (expr))
     return expr;
-    
-  nop = build1 (NOP_EXPR, type, expr);
-  if (TREE_CONSTANT (expr))
-    TREE_CONSTANT (nop) = 1;
-  
-  return nop;
+  return build1 (NOP_EXPR, type, expr);
 }
 
 /* C++: Must handle pointers to members.
@@ -3620,8 +3665,8 @@ tree
 build_unary_op (enum tree_code code, tree xarg, int noconvert)
 {
   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
-  register tree arg = xarg;
-  register tree argtype = 0;
+  tree arg = xarg;
+  tree argtype = 0;
   const char *errstring = NULL;
   tree val;
 
@@ -3640,9 +3685,8 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
       else
        {
          if (!noconvert)
-          arg = default_conversion (arg);
+           arg = default_conversion (arg);
          arg = build1 (NON_LVALUE_EXPR, TREE_TYPE (arg), arg);
-         TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
        }
       break;
 
@@ -3759,7 +3803,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
                        0);
 
       {
-       register tree inc;
+       tree inc;
        tree result_type = TREE_TYPE (arg);
 
        arg = get_unwidened (arg, 0);
@@ -3824,7 +3868,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
              compound = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
 
              /* Eliminate warning about unused result of + or -.  */
-             TREE_NO_UNUSED_WARNING (compound) = 1;
+             TREE_NO_WARNING (compound) = 1;
              return compound;
            }
 
@@ -3866,10 +3910,8 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
 
       if (TREE_CODE (argtype) == REFERENCE_TYPE)
        {
-         arg = build1
-           (CONVERT_EXPR,
-            build_pointer_type (TREE_TYPE (argtype)), arg);
-         TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
+         tree type = build_pointer_type (TREE_TYPE (argtype));
+         arg = build1 (CONVERT_EXPR, type, arg);
          return arg;
        }
       else if (pedantic && DECL_MAIN_P (arg))
@@ -3887,10 +3929,8 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
          arg = TREE_OPERAND (arg, 0);
          if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
            {
-             arg = build1
-               (CONVERT_EXPR,
-                build_pointer_type (TREE_TYPE (TREE_TYPE (arg))), arg);
-             TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
+             tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
+             arg = build1 (CONVERT_EXPR, type, arg);
            }
          else if (lvalue_p (arg))
            /* Don't let this be an lvalue.  */
@@ -3898,8 +3938,12 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
          return arg;
        }
 
-      /* For &x[y], return x+y */
-      if (TREE_CODE (arg) == ARRAY_REF)
+      /* For &x[y], return x+y.  But, in a template, ARG may be an
+        ARRAY_REF representing a non-dependent expression.  In that
+        case, there may be an overloaded "operator []" that will be
+        chosen at instantiation time; we must not try to optimize
+        here.  */
+      if (TREE_CODE (arg) == ARRAY_REF && !processing_template_decl)
        {
          if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
            return error_mark_node;
@@ -3980,7 +4024,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
          if (! lvalue_p (arg) && pedantic)
            pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
          break;
-         
+
+       case OVERLOAD:
+         arg = OVL_CURRENT (arg);
+         break;
+
        default:
          break;
        }
@@ -4003,12 +4051,28 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
       {
        tree addr;
 
-       if (TREE_CODE (arg) == COMPONENT_REF
-           && TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
-         arg = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
-
-       if (TREE_CODE (arg) != COMPONENT_REF)
+       if (TREE_CODE (arg) != COMPONENT_REF
+           /* Inside a template, we are processing a non-dependent
+              expression so we can just form an ADDR_EXPR with the
+              correct type.  */
+           || processing_template_decl)
          addr = build_address (arg);
+       else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
+         {
+           tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
+
+           /* We can only get here with a single static member
+              function.  */
+           my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL
+                               && DECL_STATIC_FUNCTION_P (fn),
+                               20030906);
+           mark_used (fn);
+           addr = build_address (fn);
+           if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
+             /* Do not lose object's side effects.  */
+             addr = build (COMPOUND_EXPR, TREE_TYPE (addr),
+                           TREE_OPERAND (arg, 0), addr);
+         }
        else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
          {
            error ("attempt to take address of bit-field structure member `%D'",
@@ -4104,7 +4168,7 @@ unary_complex_lvalue (enum tree_code code, tree arg)
     {
       tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0);
       arg = build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result);
-      TREE_NO_UNUSED_WARNING (arg) = 1;
+      TREE_NO_WARNING (arg) = 1;
       return arg;
     }
 
@@ -4150,7 +4214,8 @@ unary_complex_lvalue (enum tree_code code, tree arg)
              return error_mark_node;
            }
 
-         type = build_ptrmem_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t));
+         type = build_ptrmem_type (context_for_name_lookup (t), 
+                                   TREE_TYPE (t));
          t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
          return t;
        }
@@ -4192,7 +4257,7 @@ unary_complex_lvalue (enum tree_code code, tree arg)
 bool
 cxx_mark_addressable (tree exp)
 {
-  register tree x = exp;
+  tree x = exp;
 
   while (1)
     switch (TREE_CODE (x))
@@ -4209,10 +4274,10 @@ cxx_mark_addressable (tree exp)
        if (x == current_class_ptr)
          {
             error ("cannot take the address of `this', which is an rvalue expression");
-           TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later */
+           TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later */
            return true;
          }
-       /* FALLTHRU */
+       /* Fall through.  */
 
       case VAR_DECL:
        /* Caller should not be trying to mark initialized
@@ -4221,7 +4286,7 @@ cxx_mark_addressable (tree exp)
                            || DECL_IN_AGGR_P (x) == 0
                            || TREE_STATIC (x)
                            || DECL_EXTERNAL (x), 314);
-       /* FALLTHRU */
+       /* Fall through.  */
 
       case CONST_DECL:
       case RESULT_DECL:
@@ -4235,7 +4300,6 @@ cxx_mark_addressable (tree exp)
 
       case FUNCTION_DECL:
        TREE_ADDRESSABLE (x) = 1;
-       TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
        return true;
 
       case CONSTRUCTOR:
@@ -4268,11 +4332,13 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2)
         IFEXP is type-dependent, even though the eventual type of the
         expression doesn't dependent on IFEXP.  */
       if (type_dependent_expression_p (ifexp)
-         || type_dependent_expression_p (op1)
+         /* As a GNU extension, the middle operand may be omitted.  */
+         || (op1 && type_dependent_expression_p (op1))
          || type_dependent_expression_p (op2))
        return build_min_nt (COND_EXPR, ifexp, op1, op2);
       ifexp = build_non_dependent_expr (ifexp);
-      op1 = build_non_dependent_expr (op1);
+      if (op1)
+       op1 = build_non_dependent_expr (op1);
       op2 = build_non_dependent_expr (op2);
     }
 
@@ -4284,7 +4350,7 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2)
 }
 \f
 /* Given a list of expressions, return a compound expression
-   that performs them all and returns the value of the last of them. */
+   that performs them all and returns the value of the last of them.  */
 
 tree build_x_compound_expr_from_list (tree list, const char *msg)
 {
@@ -4320,7 +4386,8 @@ build_x_compound_expr (tree op1, tree op2)
       op2 = build_non_dependent_expr (op2);
     }
 
-  result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE);
+  result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE,
+                        /*overloaded_p=*/NULL);
   if (!result)
     result = build_compound_expr (op1, op2);
 
@@ -4330,7 +4397,7 @@ build_x_compound_expr (tree op1, tree op2)
   return result;
 }
 
-/* Build a compound expression. */
+/* Build a compound expression.  */
 
 tree
 build_compound_expr (tree lhs, tree rhs)
@@ -4345,7 +4412,7 @@ build_compound_expr (tree lhs, tree rhs)
     {
       /* If the rhs is a TARGET_EXPR, then build the compound
          expression inside the target_expr's initializer. This
-        helps the compiler to eliminate unncessary temporaries.  */
+        helps the compiler to eliminate unnecessary temporaries.  */
       tree init = TREE_OPERAND (rhs, 1);
       
       init = build (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
@@ -4427,12 +4494,13 @@ build_static_cast (tree type, tree expr)
                                          (TREE_TYPE (type))))
       && at_least_as_qualified_p (TREE_TYPE (type), intype))
     {
-      /* At this point we have checked all of the conditions except
-        that B is not a virtual base class of D.  That will be
-        checked by build_base_path.  */
-      tree base = lookup_base (TREE_TYPE (type), intype, ba_any, NULL);
+      /* There is a standard conversion from "D*" to "B*" even if "B"
+        is ambiguous or inaccessible.  Therefore, we ask lookup_base
+        to check these conditions.  */
+      tree base = lookup_base (TREE_TYPE (type), intype, ba_check, NULL);
 
-      /* Convert from B* to D*.  */
+      /* Convert from "B*" to "D*".  This function will check that "B"
+        is not a virtual base of "D".  */
       expr = build_base_path (MINUS_EXPR, build_address (expr), 
                              base, /*nonnull=*/false);
       /* Convert the pointer to a reference -- but then remember that
@@ -4448,7 +4516,17 @@ build_static_cast (tree type, tree expr)
      t.  */
   result = perform_direct_initialization_if_possible (type, expr);
   if (result)
-    return convert_from_reference (result);
+    {
+      result = convert_from_reference (result);
+      /* [expr.static.cast]
+
+         If T is a reference type, the result is an lvalue; otherwise,
+        the result is an rvalue.  */
+      if (TREE_CODE (type) != REFERENCE_TYPE
+         && real_lvalue_p (result))
+       result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
+      return result;
+    }
   
   /* [expr.static.cast]
 
@@ -4491,8 +4569,8 @@ build_static_cast (tree type, tree expr)
       tree base;
 
       check_for_casting_away_constness (intype, type, "static_cast");
-      base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), 
-                         ba_check | ba_quiet, NULL);
+      base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), ba_check, 
+                         NULL);
       return build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false);
     }
   
@@ -4669,7 +4747,7 @@ build_const_cast (tree type, tree expr)
       return t;
     }
 
-  if (!POINTER_TYPE_P (type))
+  if (!POINTER_TYPE_P (type) && !TYPE_PTRMEM_P (type))
     error ("invalid use of const_cast with type `%T', which is not a pointer, reference, nor a pointer-to-data-member type", type);
   else if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
     {
@@ -4725,7 +4803,7 @@ build_const_cast (tree type, tree expr)
 tree
 build_c_cast (tree type, tree expr)
 {
-  register tree value = expr;
+  tree value = expr;
   tree otype;
 
   if (type == error_mark_node || expr == error_mark_node)
@@ -4735,7 +4813,7 @@ build_c_cast (tree type, tree expr)
     {
       tree t = build_min (CAST_EXPR, type,
                          tree_cons (NULL_TREE, value, NULL_TREE));
-      /* We don't know if it will or will not have side effects. */
+      /* We don't know if it will or will not have side effects.  */
       TREE_SIDE_EFFECTS (t) = 1;
       return t;
     }
@@ -4854,7 +4932,9 @@ build_c_cast (tree type, tree expr)
       if (TREE_CODE (value) == INTEGER_CST)
        {
          TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
-         TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
+
+         if (TREE_CODE_CLASS (TREE_CODE (ovalue)) == 'c')
+           TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
        }
     }
 
@@ -4890,11 +4970,11 @@ build_c_cast (tree type, tree expr)
 tree
 build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
 {
-  register tree result;
+  tree result;
   tree newrhs = rhs;
   tree lhstype = TREE_TYPE (lhs);
   tree olhstype = lhstype;
-  tree olhs = lhs;
+  tree olhs = NULL_TREE;
 
   /* Avoid duplicate error messages from operands that had errors.  */
   if (lhs == error_mark_node || rhs == error_mark_node)
@@ -4903,7 +4983,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
   /* Handle control structure constructs used as "lvalues".  */
   switch (TREE_CODE (lhs))
     {
-      /* Handle --foo = 5; as these are valid constructs in C++ */
+      /* Handle --foo = 5; as these are valid constructs in C++ */
     case PREDECREMENT_EXPR:
     case PREINCREMENT_EXPR:
       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
@@ -4963,7 +5043,9 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
          return cond;
        /* Make sure the code to compute the rhs comes out
           before the split.  */
-       return build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+       if (preeval)
+         cond = build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+       return cond;
       }
       
     default:
@@ -4974,14 +5056,15 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
     {
       if (TREE_CODE (rhs) == CONSTRUCTOR)
        {
-         my_friendly_assert (same_type_p (TREE_TYPE (rhs), lhstype),
-                             20011220);
+         if (! same_type_p (TREE_TYPE (rhs), lhstype))
+           /* Call convert to generate an error; see PR 11063.  */
+           rhs = convert (lhstype, rhs);
          result = build (INIT_EXPR, lhstype, lhs, rhs);
          TREE_SIDE_EFFECTS (result) = 1;
          return result;
        }
       else if (! IS_AGGR_TYPE (lhstype))
-       /* Do the default thing */;
+       /* Do the default thing */;
       else
        {
          result = build_special_member_call (lhs, complete_ctor_identifier,
@@ -5008,11 +5091,12 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
        {
          /* `operator=' is not an inheritable operator.  */
          if (! IS_AGGR_TYPE (lhstype))
-           /* Do the default thing */;
+           /* Do the default thing */;
          else
            {
              result = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL,
-                                    lhs, rhs, make_node (NOP_EXPR));
+                                    lhs, rhs, make_node (NOP_EXPR),
+                                    /*overloaded_p=*/NULL);
              if (result == NULL_TREE)
                return error_mark_node;
              return result;
@@ -5044,52 +5128,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
                          20011220);
     }
 
-  /* Handle a cast used as an "lvalue".
-     We have already performed any binary operator using the value as cast.
-     Now convert the result to the cast type of the lhs,
-     and then true type of the lhs and store it there;
-     then convert result back to the cast type to be the value
-     of the assignment.  */
-
-  switch (TREE_CODE (lhs))
-    {
-    case NOP_EXPR:
-    case CONVERT_EXPR:
-    case FLOAT_EXPR:
-    case FIX_TRUNC_EXPR:
-    case FIX_FLOOR_EXPR:
-    case FIX_ROUND_EXPR:
-    case FIX_CEIL_EXPR:
-      {
-       tree inner_lhs = TREE_OPERAND (lhs, 0);
-       tree result;
-
-       if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
-           || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE
-           || TREE_CODE (TREE_TYPE (newrhs)) == METHOD_TYPE
-           || TREE_CODE (TREE_TYPE (newrhs)) == OFFSET_TYPE)
-         newrhs = decay_conversion (newrhs);
-       
-       /* ISO C++ 5.4/1: The result is an lvalue if T is a reference
-          type, otherwise the result is an rvalue.  */
-       if (! lvalue_p (lhs))
-         pedwarn ("ISO C++ forbids cast to non-reference type used as lvalue");
-
-       result = build_modify_expr (inner_lhs, NOP_EXPR,
-                                   cp_convert (TREE_TYPE (inner_lhs),
-                                               cp_convert (lhstype, newrhs)));
-       if (result == error_mark_node)
-         return result;
-       return cp_convert (TREE_TYPE (lhs), result);
-      }
-
-    default:
-      break;
-    }
-
-  /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
-     Reject anything strange now.  */
-
+  /* The left-hand side must be an lvalue.  */
   if (!lvalue_or_else (lhs, "assignment"))
     return error_mark_node;
 
@@ -5123,6 +5162,15 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
 
       if (lhstype != TREE_TYPE (lhs))
        {
+         /* Avoid warnings converting integral types back into enums for
+            enum bit fields.  */
+         if (TREE_CODE (lhstype) == INTEGER_TYPE
+             && TREE_CODE (olhstype) == ENUMERAL_TYPE)
+           {
+             if (TREE_SIDE_EFFECTS (lhs))
+               lhs = stabilize_reference (lhs);
+             olhs = lhs;
+           }
          lhs = copy_node (lhs);
          TREE_TYPE (lhs) = lhstype;
        }
@@ -5195,13 +5243,10 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
 
   if (olhstype == TREE_TYPE (result))
     return result;
-  /* Avoid warnings converting integral types back into enums
-     for enum bit fields.  */
-  if (TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
-      && TREE_CODE (olhstype) == ENUMERAL_TYPE)
+  if (olhs)
     {
       result = build (COMPOUND_EXPR, olhstype, result, olhs);
-      TREE_NO_UNUSED_WARNING (result) = 1;
+      TREE_NO_WARNING (result) = 1;
       return result;
     }
   return convert_for_assignment (olhstype, result, "assignment",
@@ -5218,7 +5263,8 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
   if (modifycode != NOP_EXPR)
     {
       tree rval = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs,
-                               make_node (modifycode));
+                               make_node (modifycode),
+                               /*overloaded_p=*/NULL);
       if (rval)
        return rval;
     }
@@ -5242,51 +5288,53 @@ get_delta_difference (tree from, tree to, int force)
   tree binfo;
   tree virt_binfo;
   base_kind kind;
-  
+  tree result;
+
+  /* Assume no conversion is required.  */
+  result = integer_zero_node;
   binfo = lookup_base (to, from, ba_check, &kind);
   if (kind == bk_inaccessible || kind == bk_ambig)
-    {
-      error ("   in pointer to member function conversion");
-      goto error;
-    }
-  if (!binfo)
+    error ("   in pointer to member function conversion");
+  else if (!binfo)
     {
       if (!force)
        {
          error_not_base_type (from, to);
          error ("   in pointer to member conversion");
-         goto error;
        }
-      binfo = lookup_base (from, to, ba_check, &kind);
-      if (!binfo)
-       goto error;
+      else
+       {
+         binfo = lookup_base (from, to, ba_check, &kind);
+         if (binfo)
+           {
+             virt_binfo = binfo_from_vbase (binfo);
+             if (virt_binfo)
+               /* This is a reinterpret cast, we choose to do nothing.  */
+               warning ("pointer to member cast via virtual base `%T'",
+                        BINFO_TYPE (virt_binfo));
+             else
+               result = size_diffop (size_zero_node, BINFO_OFFSET (binfo));
+           }
+       }
+    }
+  else
+    {
       virt_binfo = binfo_from_vbase (binfo);
-      if (virt_binfo)
-        {
-          /* This is a reinterpret cast, we choose to do nothing.  */
-          warning ("pointer to member cast via virtual base `%T'",
+      if (!virt_binfo)
+       result = BINFO_OFFSET (binfo);
+      else
+       {
+         /* This is a reinterpret cast, we choose to do nothing.  */
+         if (force)
+           warning ("pointer to member cast via virtual base `%T'",
+                    BINFO_TYPE (virt_binfo));
+         else
+           error ("pointer to member conversion via virtual base `%T'",
                   BINFO_TYPE (virt_binfo));
-         goto error;
-        }
-      return convert_to_integer (ptrdiff_type_node, 
-                                size_diffop (size_zero_node,
-                                             BINFO_OFFSET (binfo)));
+       }
     }
 
-  virt_binfo = binfo_from_vbase (binfo);
-  if (!virt_binfo)
-    return convert_to_integer (ptrdiff_type_node, BINFO_OFFSET (binfo));
-
-  /* This is a reinterpret cast, we choose to do nothing.  */
-  if (force)
-    warning ("pointer to member cast via virtual base `%T'",
-            BINFO_TYPE (virt_binfo));
-  else
-    error ("pointer to member conversion via virtual base `%T'",
-          BINFO_TYPE (virt_binfo));
-
- error:
-  return convert_to_integer(ptrdiff_type_node, integer_zero_node);
+  return fold (convert_to_integer (ptrdiff_type_node, result));
 }
 
 /* Return a constructor for the pointer-to-member-function TYPE using
@@ -5310,7 +5358,8 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn)
   u = tree_cons (pfn_field, pfn,
                 build_tree_list (delta_field, delta));
   u = build_constructor (type, u);
-  TREE_CONSTANT (u) = TREE_CONSTANT (pfn) && TREE_CONSTANT (delta);
+  TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
+  TREE_INVARIANT (u) = TREE_INVARIANT (pfn) & TREE_INVARIANT (delta);
   TREE_STATIC (u) = (TREE_CONSTANT (u)
                     && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
                         != NULL_TREE)
@@ -5412,7 +5461,7 @@ build_ptrmemfunc (tree type, tree pfn, int force)
    given by CST.
 
    ??? There is no consistency as to the types returned for the above
-   values.  Some code acts as if its a sizetype and some as if its
+   values.  Some code acts as if it were a sizetype and some as if it were
    integer_type_node.  */
 
 void
@@ -5526,10 +5575,9 @@ dubious_conversion_warnings (tree type, tree expr,
     }
   /* And warn about assigning a negative value to an unsigned
      variable.  */
-  else if (TREE_UNSIGNED (type) && TREE_CODE (type) != BOOLEAN_TYPE)
+  else if (TYPE_UNSIGNED (type) && TREE_CODE (type) != BOOLEAN_TYPE)
     {
-      if (TREE_CODE (expr) == INTEGER_CST
-         && TREE_NEGATED_INT (expr))
+      if (TREE_CODE (expr) == INTEGER_CST && TREE_NEGATED_INT (expr))
        {
          if (fndecl)
            warning ("passing negative value `%E' for %s %P of `%D'",
@@ -5557,8 +5605,8 @@ static tree
 convert_for_assignment (tree type, tree rhs,
                        const char *errtype, tree fndecl, int parmnum)
 {
-  register tree rhstype;
-  register enum tree_code coder;
+  tree rhstype;
+  enum tree_code coder;
 
   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
   if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
@@ -5568,8 +5616,7 @@ convert_for_assignment (tree type, tree rhs,
   coder = TREE_CODE (rhstype);
 
   if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (type)
-         || (*targetm.vector_opaque_p) (rhstype)))
+      && vector_types_convertible_p (type, rhstype))
     return convert (type, rhs);
 
   if (rhs == error_mark_node || rhstype == error_mark_node)
@@ -5577,8 +5624,6 @@ convert_for_assignment (tree type, tree rhs,
   if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
     return error_mark_node;
 
-  rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum);
-
   /* The RHS of an assignment cannot have void type.  */
   if (coder == VOID_TYPE)
     {
@@ -5656,9 +5701,9 @@ tree
 convert_for_initialization (tree exp, tree type, tree rhs, int flags,
                            const char *errtype, tree fndecl, int parmnum)
 {
-  register enum tree_code codel = TREE_CODE (type);
-  register tree rhstype;
-  register enum tree_code coder;
+  enum tree_code codel = TREE_CODE (type);
+  tree rhstype;
+  enum tree_code coder;
 
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
      Strip such NOP_EXPRs, since RHS is used in non-lvalue context.  */
@@ -5738,13 +5783,13 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
 
 void
 c_expand_asm_operands (tree string, tree outputs, tree inputs, tree clobbers,
-                      int vol, const char *filename, int line)
+                      int vol, location_t locus)
 {
   int noutputs = list_length (outputs);
-  register int i;
+  int i;
   /* o[I] is the place that output number I should be written.  */
-  register tree *o = alloca (noutputs * sizeof (tree));
-  register tree tail;
+  tree *o = alloca (noutputs * sizeof (tree));
+  tree tail;
 
   /* Record the contents of OUTPUTS before it is modified.  */
   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
@@ -5753,7 +5798,7 @@ c_expand_asm_operands (tree string, tree outputs, tree inputs, tree clobbers,
   /* Generate the ASM_OPERANDS insn;
      store into the TREE_VALUEs of OUTPUTS some trees for
      where the values were actually stored.  */
-  expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
+  expand_asm_operands (string, outputs, inputs, clobbers, vol, locus);
 
   /* Copy all the intermediate outputs into the specified outputs.  */
   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
@@ -5826,7 +5871,7 @@ maybe_warn_about_returning_address_of_local (tree retval)
        }
     }
 
-  if (TREE_CODE (whats_returned) == VAR_DECL
+  if (DECL_P (whats_returned)
       && DECL_NAME (whats_returned)
       && DECL_FUNCTION_SCOPE_P (whats_returned)
       && !(TREE_STATIC (whats_returned)
@@ -5964,8 +6009,7 @@ check_return_expr (tree retval)
      returned expression uses the chosen variable somehow.  And people expect
      this restriction, anyway.  (jason 2000-11-19)
 
-     See finish_function, genrtl_start_function, and declare_return_variable
-     for other pieces of this optimization.  */
+     See finish_function and finalize_nrv for the rest of this optimization.  */
 
   if (fn_returns_value_p && flag_elide_constructors)
     {
@@ -6154,7 +6198,7 @@ cp_type_quals (tree type)
   return TYPE_QUALS (type);
 }
 
-/* Returns nonzero if the TYPE contains a mutable member */
+/* Returns nonzero if the TYPE contains a mutable member */
 
 bool
 cp_has_mutable_p (tree type)