OSDN Git Service

* Make-lang.in, call.c, class.c, decl2.c, except.c, expr.c,
[pf3gnuchains/gcc-fork.git] / gcc / cp / typeck.c
index 2a21a00..a1403d6 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.
@@ -579,8 +579,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.  */
@@ -857,6 +857,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 +888,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 +920,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);
@@ -977,7 +994,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 +1015,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:
@@ -1170,23 +1187,33 @@ 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;
 }
 
 \f
+/* Process a sizeof or alignof expression where the operand is a
+   type.  */
+
 tree
-cxx_sizeof_or_alignof_type (tree type, enum tree_code op, int complain)
+cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
 {
   enum tree_code type_code;
   tree value;
   const char *op_name;
 
   my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
+  if (type == error_mark_node)
+    return error_mark_node;
+  
   if (processing_template_decl)
-    return build_min (op, size_type_node, type);
+    {
+      value = build_min (op, size_type_node, type);
+      TREE_READONLY (value) = 1;
+      return value;
+    }
   
   op_name = operator_name_info[(int) op].name;
 
@@ -1205,30 +1232,47 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, int complain)
   return value;
 }
 
+/* Process a sizeof or alignof expression where the operand is an
+   expression.  */
+
 tree
-expr_sizeof (tree e)
+cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
 {
+  const char *op_name = operator_name_info[(int) op].name;
+  
+  if (e == error_mark_node)
+    return error_mark_node;
+  
   if (processing_template_decl)
-    return build_min (SIZEOF_EXPR, size_type_node, e);
-
+    {
+      e = build_min (op, size_type_node, e);
+      TREE_SIDE_EFFECTS (e) = 0;
+      TREE_READONLY (e) = 1;
+      
+      return e;
+    }
+  
   if (TREE_CODE (e) == COMPONENT_REF
+      && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
       && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
-    error ("sizeof applied to a bit-field");
-  if (is_overloaded_fn (e))
     {
-      pedwarn ("ISO C++ forbids applying `sizeof' to an expression of function type");
-      return c_sizeof (char_type_node);
+      error ("invalid application of `%s' to a bit-field", op_name);
+      e = char_type_node;
+    }
+  else if (is_overloaded_fn (e))
+    {
+      pedwarn ("ISO C++ forbids applying `%s' to an expression of function type", op_name);
+      e = char_type_node;
     }
   else if (type_unknown_p (e))
     {
       cxx_incomplete_type_error (e, TREE_TYPE (e));
-      return c_sizeof (char_type_node);
+      e = char_type_node;
     }
-
-  if (e == error_mark_node)
-    return e;
-
-  return cxx_sizeof (TREE_TYPE (e));
+  else
+    e = TREE_TYPE (e);
+  
+  return cxx_sizeof_or_alignof_type (e, op, true);
 }
   
 \f
@@ -1241,8 +1285,8 @@ expr_sizeof (tree e)
 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);
@@ -1293,7 +1337,7 @@ decay_conversion (tree 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)
@@ -1526,7 +1570,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))
     {
@@ -1785,6 +1830,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
@@ -1809,7 +1857,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))
     {
@@ -1837,6 +1886,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)
@@ -1865,8 +1919,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
        {
@@ -1910,8 +1969,8 @@ finish_class_member_access_expr (tree object, tree name)
   expr = build_class_member_access_expr (object, member, access_path,
                                         /*preserve_reference=*/false);
   if (processing_template_decl && expr != error_mark_node)
-    return build_min (COMPONENT_REF, TREE_TYPE (expr), orig_object, 
-                     orig_name);
+    return build_min_non_dep (COMPONENT_REF, expr,
+                             orig_object, orig_name);
   return expr;
 }
 
@@ -1968,7 +2027,7 @@ build_x_indirect_ref (tree expr, const char *errorstring)
     rval = build_indirect_ref (expr, errorstring);
 
   if (processing_template_decl && rval != error_mark_node)
-    return build_min (INDIRECT_REF, TREE_TYPE (rval), orig_expr);
+    return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
   else
     return rval;
 }
@@ -1976,7 +2035,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;
@@ -2314,8 +2373,8 @@ 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 fntype, fndecl;
+  tree coerced_params;
   tree result;
   tree name = NULL_TREE, assembler_name = NULL_TREE;
   int is_method;
@@ -2432,8 +2491,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;
 
@@ -2458,8 +2517,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;
@@ -2506,8 +2565,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
            {
@@ -2545,7 +2608,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)
        {
@@ -2611,7 +2674,7 @@ build_x_binary_op (enum tree_code code, tree arg1, tree arg2)
     expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE);
 
   if (processing_template_decl && expr != error_mark_node)
-    return build_min (code, TREE_TYPE (expr), orig_arg1, orig_arg2);
+    return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
   
   return expr;
 }
@@ -2639,17 +2702,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.
@@ -3358,8 +3421,8 @@ 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;
+    tree result = build (resultcode, build_type, op0, op1);
+    tree folded;
 
     folded = fold (result);
     if (folded == result)
@@ -3374,8 +3437,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);
 
@@ -3393,9 +3455,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, folded;
   tree restype = ptrdiff_type_node;
   tree target_type = TREE_TYPE (ptrtype);
 
@@ -3464,7 +3526,7 @@ build_x_unary_op (enum tree_code code, tree xarg)
       && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
           && !COMPLETE_TYPE_P (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);
   if (!exp && code == ADDR_EXPR)
@@ -3511,7 +3573,8 @@ build_x_unary_op (enum tree_code code, tree xarg)
     }
 
   if (processing_template_decl && exp != error_mark_node)
-    return build_min (code, TREE_TYPE (exp), orig_expr, NULL_TREE);
+    return build_min_non_dep (code, exp, orig_expr,
+                             /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
   return exp;
 }
 
@@ -3554,9 +3617,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);
+  addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
   if (staticp (t))
     TREE_CONSTANT (addr) = 1;
 
@@ -3593,8 +3654,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;
 
@@ -3732,7 +3793,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);
@@ -3871,7 +3932,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
          return arg;
        }
 
-      /* For &x[y], return x+y */
+      /* For &x[y], return x+y */
       if (TREE_CODE (arg) == ARRAY_REF)
        {
          if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
@@ -3976,12 +4037,24 @@ 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)
          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'",
@@ -4165,7 +4238,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))
@@ -4182,10 +4255,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
@@ -4194,7 +4267,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:
@@ -4241,23 +4314,25 @@ 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);
     }
 
   expr = build_conditional_expr (ifexp, op1, op2);
   if (processing_template_decl && expr != error_mark_node)
-    return build_min (COND_EXPR, TREE_TYPE (expr)
-                     orig_ifexp, orig_op1, orig_op2);
+    return build_min_non_dep (COND_EXPR, expr
+                             orig_ifexp, orig_op1, orig_op2);
   return expr;
 }
 \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)
 {
@@ -4298,12 +4373,12 @@ build_x_compound_expr (tree op1, tree op2)
     result = build_compound_expr (op1, op2);
 
   if (processing_template_decl && result != error_mark_node)
-    return build_min (COMPOUND_EXPR, TREE_TYPE (result), 
-                     orig_op1, orig_op2);
+    return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
+  
   return result;
 }
 
-/* Build a compound expression. */
+/* Build a compound expression.  */
 
 tree
 build_compound_expr (tree lhs, tree rhs)
@@ -4318,7 +4393,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);
@@ -4356,8 +4431,10 @@ build_static_cast (tree type, tree expr)
 
   if (processing_template_decl)
     {
-      tree t = build_min (STATIC_CAST_EXPR, type, expr); 
-      return t;
+      expr = build_min (STATIC_CAST_EXPR, type, expr);
+      /* We don't know if it will or will not have side effects.  */
+      TREE_SIDE_EFFECTS (expr) = 1;
+      return expr;
     }
 
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
@@ -4398,12 +4475,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
@@ -4447,9 +4525,10 @@ build_static_cast (tree type, tree expr)
         converted to an enumeration type.  */
       || (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
          && INTEGRAL_OR_ENUMERATION_TYPE_P (intype)))
-      /* Really, build_c_cast should defer to this function rather
-        than the other way around.  */
-      return build_c_cast (type, expr);
+    /* Really, build_c_cast should defer to this function rather
+       than the other way around.  */
+    return build_c_cast (type, expr);
+  
   if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
       && CLASS_TYPE_P (TREE_TYPE (type))
       && CLASS_TYPE_P (TREE_TYPE (intype))
@@ -4461,10 +4540,11 @@ 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);
     }
+  
   if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
       || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
     {
@@ -4541,6 +4621,11 @@ build_reinterpret_cast (tree type, tree expr)
   if (processing_template_decl)
     {
       tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
+      
+      if (!TREE_SIDE_EFFECTS (t)
+         && type_dependent_expression_p (expr))
+       /* There might turn out to be side effects inside expr.  */
+       TREE_SIDE_EFFECTS (t) = 1;
       return t;
     }
 
@@ -4625,6 +4710,11 @@ build_const_cast (tree type, tree expr)
   if (processing_template_decl)
     {
       tree t = build_min (CONST_CAST_EXPR, type, expr);
+      
+      if (!TREE_SIDE_EFFECTS (t)
+         && type_dependent_expression_p (expr))
+       /* There might turn out to be side effects inside expr.  */
+       TREE_SIDE_EFFECTS (t) = 1;
       return t;
     }
 
@@ -4684,7 +4774,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)
@@ -4694,6 +4784,8 @@ 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.  */
+      TREE_SIDE_EFFECTS (t) = 1;
       return t;
     }
 
@@ -4847,11 +4939,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)
@@ -4860,7 +4952,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)))
@@ -4931,14 +5023,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,
@@ -4965,7 +5058,7 @@ 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,
@@ -5080,6 +5173,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;
        }
@@ -5152,10 +5254,7 @@ 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;
@@ -5514,8 +5613,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)
@@ -5613,9 +5712,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.  */
@@ -5695,13 +5794,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++)
@@ -5710,7 +5809,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++)
@@ -5921,8 +6020,9 @@ 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, cxx_expand_function_start, and
+     cp_copy_res_decl_for_inlining for other pieces of this
+     optimization.  */
 
   if (fn_returns_value_p && flag_elide_constructors)
     {
@@ -6111,7 +6211,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)