OSDN Git Service

* reorg.c (fill_slots_from_thread): Check side_effects_p when
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index 0a1f490..62a3b25 100644 (file)
@@ -1,5 +1,6 @@
 /* Build expressions with type checking for C compiler.
-   Copyright (C) 1987, 88, 91-97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -32,47 +33,49 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "tree.h"
 #include "c-tree.h"
+#include "tm_p.h"
 #include "flags.h"
 #include "output.h"
 #include "rtl.h"
 #include "expr.h"
 #include "toplev.h"
+#include "intl.h"
+#include "defaults.h"
+#include "ggc.h"
 
 /* Nonzero if we've already printed a "missing braces around initializer"
    message within this initializer.  */
 static int missing_braces_mentioned;
 
-static tree qualify_type               PROTO((tree, tree));
-static int comp_target_types           PROTO((tree, tree));
-static int function_types_compatible_p PROTO((tree, tree));
-static int type_lists_compatible_p     PROTO((tree, tree));
-static int self_promoting_type_p       PROTO((tree));
-static tree decl_constant_value                PROTO((tree));
-static tree lookup_field               PROTO((tree, tree, tree *));
-static tree convert_arguments          PROTO((tree, tree, tree, tree));
-static tree pointer_int_sum            PROTO((enum tree_code, tree, tree));
-static tree pointer_diff               PROTO((tree, tree));
-static tree unary_complex_lvalue       PROTO((enum tree_code, tree));
-static void pedantic_lvalue_warning    PROTO((enum tree_code));
-static tree internal_build_compound_expr PROTO((tree, int));
-static tree convert_for_assignment     PROTO((tree, tree, char *, tree,
-                                              tree, int));
-static void warn_for_assignment                PROTO((char *, char *, tree, int));
-static tree valid_compound_expr_initializer PROTO((tree, tree));
-static void push_string                        PROTO((char *));
-static void push_member_name           PROTO((tree));
-static void push_array_bounds          PROTO((int));
-static int spelling_length             PROTO((void));
-static char *print_spelling            PROTO((char *));
-static char *get_spelling              PROTO((char *));
-static void warning_init               PROTO((char *, char *,
-                                              char *));
-static tree digest_init                        PROTO((tree, tree, int, int));
-static void check_init_type_bitfields  PROTO((tree));
-static void output_init_element                PROTO((tree, tree, tree, int));
-static void output_pending_init_elements PROTO((int));
-static void add_pending_init           PROTO((tree, tree));
-static int pending_init_member         PROTO((tree));
+static tree qualify_type               PARAMS ((tree, tree));
+static int comp_target_types           PARAMS ((tree, tree));
+static int function_types_compatible_p PARAMS ((tree, tree));
+static int type_lists_compatible_p     PARAMS ((tree, tree));
+static tree decl_constant_value                PARAMS ((tree));
+static tree lookup_field               PARAMS ((tree, tree, tree *));
+static tree convert_arguments          PARAMS ((tree, tree, tree, tree));
+static tree pointer_int_sum            PARAMS ((enum tree_code, tree, tree));
+static tree pointer_diff               PARAMS ((tree, tree));
+static tree unary_complex_lvalue       PARAMS ((enum tree_code, tree));
+static void pedantic_lvalue_warning    PARAMS ((enum tree_code));
+static tree internal_build_compound_expr PARAMS ((tree, int));
+static tree convert_for_assignment     PARAMS ((tree, tree, const char *,
+                                                tree, tree, int));
+static void warn_for_assignment                PARAMS ((const char *, const char *,
+                                                tree, int));
+static tree valid_compound_expr_initializer PARAMS ((tree, tree));
+static void push_string                        PARAMS ((const char *));
+static void push_member_name           PARAMS ((tree));
+static void push_array_bounds          PARAMS ((int));
+static int spelling_length             PARAMS ((void));
+static char *print_spelling            PARAMS ((char *));
+static void warning_init               PARAMS ((const char *));
+static tree digest_init                        PARAMS ((tree, tree, int, int));
+static void check_init_type_bitfields  PARAMS ((tree));
+static void output_init_element                PARAMS ((tree, tree, tree, int));
+static void output_pending_init_elements PARAMS ((int));
+static void add_pending_init           PARAMS ((tree, tree));
+static int pending_init_member         PARAMS ((tree));
 \f
 /* Do `exp = require_complete_type (exp);' to make sure exp
    does not have an incomplete type.  (That includes void types.)  */
@@ -83,9 +86,11 @@ require_complete_type (value)
 {
   tree type = TREE_TYPE (value);
 
+  if (TREE_CODE (value) == ERROR_MARK)
+    return error_mark_node;
+
   /* First, detect a valid value with a complete type.  */
-  if (TYPE_SIZE (type) != 0
-      && type != void_type_node)
+  if (COMPLETE_TYPE_P (type))
     return value;
 
   incomplete_type_error (value, type);
@@ -101,7 +106,7 @@ incomplete_type_error (value, type)
      tree value;
      tree type;
 {
-  char *errmsg;
+  const char *type_code_string;
 
   /* Avoid duplicate error message.  */
   if (TREE_CODE (type) == ERROR_MARK)
@@ -119,15 +124,15 @@ incomplete_type_error (value, type)
       switch (TREE_CODE (type))
        {
        case RECORD_TYPE:
-         errmsg = "invalid use of undefined type `struct %s'";
+         type_code_string = "struct";
          break;
 
        case UNION_TYPE:
-         errmsg = "invalid use of undefined type `union %s'";
+         type_code_string = "union";
          break;
 
        case ENUMERAL_TYPE:
-         errmsg = "invalid use of undefined type `enum %s'";
+         type_code_string = "enum";
          break;
 
        case VOID_TYPE:
@@ -148,7 +153,8 @@ incomplete_type_error (value, type)
        }
 
       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
-       error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type)));
+       error ("invalid use of undefined type `%s %s'",
+              type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type)));
       else
        /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL.  */
        error ("invalid use of incomplete typedef `%s'",
@@ -163,9 +169,8 @@ static tree
 qualify_type (type, like)
      tree type, like;
 {
-  int constflag = TYPE_READONLY (type) || TYPE_READONLY (like);
-  int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like);
-  return c_build_type_variant (type, constflag, volflag);
+  return c_build_qualified_type (type, 
+                                TYPE_QUALS (type) | TYPE_QUALS (like));
 }
 \f
 /* Return the common type of two types.
@@ -283,14 +288,14 @@ common_type (t1, t2)
         But ANSI C specifies doing this with the qualifiers.
         So I turned it on again.  */
       {
-       tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
-                                  TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
-       int constp
-         = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2));
-       int volatilep
-         = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
-       t1 = build_pointer_type (c_build_type_variant (target, constp,
-                                volatilep));
+       tree pointed_to_1 = TREE_TYPE (t1);
+       tree pointed_to_2 = TREE_TYPE (t2);
+       tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
+                                  TYPE_MAIN_VARIANT (pointed_to_2));
+       t1 = build_pointer_type (c_build_qualified_type 
+                                (target, 
+                                 TYPE_QUALS (pointed_to_1) | 
+                                 TYPE_QUALS (pointed_to_2)));
        return build_type_attribute_variant (t1, attributes);
       }
 #if 0
@@ -430,6 +435,16 @@ comptypes (type1, type2)
       || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
     return 1;
 
+  /* If either type is the internal version of sizetype, return the
+     language version.  */
+  if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
+      && TYPE_DOMAIN (t1) != 0)
+    t1 = TYPE_DOMAIN (t1);
+
+  if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
+      && TYPE_DOMAIN (t2) != 0)
+    t2 = TYPE_DOMAIN (t2);
+
   /* Treat an enum type as the integer type of the same width and 
      signedness.  */
 
@@ -447,9 +462,7 @@ comptypes (type1, type2)
 
   /* Qualifiers must match.  */
 
-  if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
-    return 0;
-  if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
+  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
     return 0;
 
   /* Allow for two different type nodes which have essentially the same
@@ -500,15 +513,10 @@ comptypes (type1, type2)
            || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)
          break;
 
-       if (! ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1))
-                 == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2)))
-                && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1))
-                    == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2)))
-                && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1))
-                    == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2)))
-                && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1))
-                    == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2)))))
-          val = 0;
+       if (! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
+           || ! tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
+         val = 0;
+
         break;
       }
 
@@ -625,12 +633,12 @@ type_lists_compatible_p (args1, args2)
         So match anything that self-promotes.  */
       if (TREE_VALUE (args1) == 0)
        {
-         if (! self_promoting_type_p (TREE_VALUE (args2)))
+         if (simple_type_promotes_to (TREE_VALUE (args2)) != NULL_TREE)
            return 0;
        }
       else if (TREE_VALUE (args2) == 0)
        {
-         if (! self_promoting_type_p (TREE_VALUE (args1)))
+         if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE)
            return 0;
        }
       else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2))))
@@ -679,132 +687,7 @@ type_lists_compatible_p (args1, args2)
       args2 = TREE_CHAIN (args2);
     }
 }
-
-/* Return 1 if PARMS specifies a fixed number of parameters
-   and none of their types is affected by default promotions.  */
-
-int
-self_promoting_args_p (parms)
-     tree parms;
-{
-  register tree t;
-  for (t = parms; t; t = TREE_CHAIN (t))
-    {
-      register tree type = TREE_VALUE (t);
-
-      if (TREE_CHAIN (t) == 0 && type != void_type_node)
-       return 0;
-
-      if (type == 0)
-       return 0;
-
-      if (TYPE_MAIN_VARIANT (type) == float_type_node)
-       return 0;
-
-      if (C_PROMOTING_INTEGER_TYPE_P (type))
-       return 0;
-    }
-  return 1;
-}
-
-/* Return 1 if TYPE is not affected by default promotions.  */
-
-static int
-self_promoting_type_p (type)
-     tree type;
-{
-  if (TYPE_MAIN_VARIANT (type) == float_type_node)
-    return 0;
-
-  if (C_PROMOTING_INTEGER_TYPE_P (type))
-    return 0;
-
-  return 1;
-}
 \f
-/* Return an unsigned type the same as TYPE in other respects.  */
-
-tree
-unsigned_type (type)
-     tree type;
-{
-  tree type1 = TYPE_MAIN_VARIANT (type);
-  if (type1 == signed_char_type_node || type1 == char_type_node)
-    return unsigned_char_type_node;
-  if (type1 == integer_type_node)
-    return unsigned_type_node;
-  if (type1 == short_integer_type_node)
-    return short_unsigned_type_node;
-  if (type1 == long_integer_type_node)
-    return long_unsigned_type_node;
-  if (type1 == long_long_integer_type_node)
-    return long_long_unsigned_type_node;
-  if (type1 == intDI_type_node)
-    return unsigned_intDI_type_node;
-  if (type1 == intSI_type_node)
-    return unsigned_intSI_type_node;
-  if (type1 == intHI_type_node)
-    return unsigned_intHI_type_node;
-  if (type1 == intQI_type_node)
-    return unsigned_intQI_type_node;
-
-  return signed_or_unsigned_type (1, type);
-}
-
-/* Return a signed type the same as TYPE in other respects.  */
-
-tree
-signed_type (type)
-     tree type;
-{
-  tree type1 = TYPE_MAIN_VARIANT (type);
-  if (type1 == unsigned_char_type_node || type1 == char_type_node)
-    return signed_char_type_node;
-  if (type1 == unsigned_type_node)
-    return integer_type_node;
-  if (type1 == short_unsigned_type_node)
-    return short_integer_type_node;
-  if (type1 == long_unsigned_type_node)
-    return long_integer_type_node;
-  if (type1 == long_long_unsigned_type_node)
-    return long_long_integer_type_node;
-  if (type1 == unsigned_intDI_type_node)
-    return intDI_type_node;
-  if (type1 == unsigned_intSI_type_node)
-    return intSI_type_node;
-  if (type1 == unsigned_intHI_type_node)
-    return intHI_type_node;
-  if (type1 == unsigned_intQI_type_node)
-    return intQI_type_node;
-
-  return signed_or_unsigned_type (0, type);
-}
-
-/* Return a type the same as TYPE except unsigned or
-   signed according to UNSIGNEDP.  */
-
-tree
-signed_or_unsigned_type (unsignedp, type)
-     int unsignedp;
-     tree type;
-{
-  if ((! INTEGRAL_TYPE_P (type) && ! POINTER_TYPE_P (type))
-      || TREE_UNSIGNED (type) == unsignedp)
-    return type;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
-    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) 
-    return unsignedp ? unsigned_type_node : integer_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) 
-    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) 
-    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
-  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) 
-    return (unsignedp ? long_long_unsigned_type_node
-           : long_long_integer_type_node);
-  return type;
-}
-
 /* Compute the value of the `sizeof' operator.  */
 
 tree
@@ -812,36 +695,33 @@ c_sizeof (type)
      tree type;
 {
   enum tree_code code = TREE_CODE (type);
-  tree t;
 
   if (code == FUNCTION_TYPE)
     {
       if (pedantic || warn_pointer_arith)
        pedwarn ("sizeof applied to a function type");
-      return size_int (1);
+      return size_one_node;
     }
   if (code == VOID_TYPE)
     {
       if (pedantic || warn_pointer_arith)
        pedwarn ("sizeof applied to a void type");
-      return size_int (1);
+      return size_one_node;
     }
+
   if (code == ERROR_MARK)
-    return size_int (1);
-  if (TYPE_SIZE (type) == 0)
+    return size_one_node;
+
+  if (!COMPLETE_TYPE_P (type))
     {
       error ("sizeof applied to an incomplete type");
-      return size_int (0);
+      return size_zero_node;
     }
 
   /* Convert in case a char is more than one unit.  */
-  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 
-                 size_int (TYPE_PRECISION (char_type_node)));
-  t = convert (sizetype, t);
-  /* size_binop does not put the constant in range, so do it now.  */
-  if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0))
-    TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1;
-  return t;
+  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+                    size_int (TYPE_PRECISION (char_type_node)
+                              / BITS_PER_UNIT));
 }
 
 tree
@@ -849,21 +729,17 @@ c_sizeof_nowarn (type)
      tree type;
 {
   enum tree_code code = TREE_CODE (type);
-  tree t;
 
-  if (code == FUNCTION_TYPE
-      || code == VOID_TYPE
-      || code == ERROR_MARK)
-    return size_int (1);
-  if (TYPE_SIZE (type) == 0)
-    return size_int (0);
+  if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
+    return size_one_node;
+
+  if (!COMPLETE_TYPE_P (type))
+    return size_zero_node;
 
   /* Convert in case a char is more than one unit.  */
-  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 
-                 size_int (TYPE_PRECISION (char_type_node)));
-  t = convert (sizetype, t);
-  force_fit_type (t, 0);
-  return t;
+  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+                    size_int (TYPE_PRECISION (char_type_node)
+                              / BITS_PER_UNIT));
 }
 
 /* Compute the size to increment a pointer by.  */
@@ -873,26 +749,20 @@ c_size_in_bytes (type)
      tree type;
 {
   enum tree_code code = TREE_CODE (type);
-  tree t;
 
-  if (code == FUNCTION_TYPE)
-    return size_int (1);
-  if (code == VOID_TYPE)
-    return size_int (1);
-  if (code == ERROR_MARK)
-    return size_int (1);
-  if (TYPE_SIZE (type) == 0)
+  if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
+    return size_one_node;
+
+  if (!COMPLETE_OR_VOID_TYPE_P (type))
     {
       error ("arithmetic on pointer to an incomplete type");
-      return size_int (1);
+      return size_one_node;
     }
 
   /* Convert in case a char is more than one unit.  */
-  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 
-                    size_int (BITS_PER_UNIT));
-  t = convert (sizetype, t);
-  force_fit_type (t, 0);
-  return t;
+  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+                    size_int (TYPE_PRECISION (char_type_node)
+                              / BITS_PER_UNIT));
 }
 
 /* Implement the __alignof keyword: Return the minimum required
@@ -908,7 +778,13 @@ c_alignof (type)
     return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
 
   if (code == VOID_TYPE || code == ERROR_MARK)
-    return size_int (1);
+    return size_one_node;
+
+  if (!COMPLETE_TYPE_P (type))
+    {
+      error ("__alignof__ applied to an incomplete type");
+      return size_zero_node;
+    }
 
   return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
 }
@@ -929,7 +805,7 @@ c_alignof_expr (expr)
       && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
     {
       error ("`__alignof' applied to a bit-field");
-      return size_int (1);
+      return size_one_node;
     }
   else if (TREE_CODE (expr) == COMPONENT_REF
       && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
@@ -1008,8 +884,9 @@ default_conversion (exp)
     }
 
   /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
-     an lvalue.  */
-  /* Do not use STRIP_NOPS here!  It will remove conversions from pointer
+     an lvalue. 
+
+     Do not use STRIP_NOPS here!  It will remove conversions from pointer
      to integer and cause infinite recursion.  */
   while (TREE_CODE (exp) == NON_LVALUE_EXPR
         || (TREE_CODE (exp) == NOP_EXPR
@@ -1026,26 +903,19 @@ default_conversion (exp)
                              || (TYPE_PRECISION (type)
                                  >= TYPE_PRECISION (integer_type_node)))
                             && TREE_UNSIGNED (type)));
+
       return convert (type, exp);
     }
 
   if (TREE_CODE (exp) == COMPONENT_REF
-      && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)))
-    {
-      tree width = DECL_SIZE (TREE_OPERAND (exp, 1));
-      HOST_WIDE_INT low = TREE_INT_CST_LOW (width);
-
+      && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))
       /* If it's thinner than an int, promote it like a
         C_PROMOTING_INTEGER_TYPE_P, otherwise leave it alone.  */
-
-      if (low < TYPE_PRECISION (integer_type_node))
-       {
-         if (flag_traditional && TREE_UNSIGNED (type))
-           return convert (unsigned_type_node, exp);
-         else
-           return convert (integer_type_node, exp);
-       }
-    }
+      && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
+                              TYPE_PRECISION (integer_type_node)))
+    return convert (flag_traditional && TREE_UNSIGNED (type)
+                   ? unsigned_type_node : integer_type_node,
+                   exp);
 
   if (C_PROMOTING_INTEGER_TYPE_P (type))
     {
@@ -1055,11 +925,14 @@ default_conversion (exp)
          && (flag_traditional
              || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
        return convert (unsigned_type_node, exp);
+
       return convert (integer_type_node, exp);
     }
+
   if (flag_traditional && !flag_allow_single_precision
       && TYPE_MAIN_VARIANT (type) == float_type_node)
     return convert (double_type_node, exp);
+
   if (code == VOID_TYPE)
     {
       error ("void value not ignored as it ought to be");
@@ -1077,18 +950,18 @@ default_conversion (exp)
       int constp = 0;
       int volatilep = 0;
 
-      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r'
-         || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
+      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r' || DECL_P (exp))
        {
          constp = TREE_READONLY (exp);
          volatilep = TREE_THIS_VOLATILE (exp);
        }
 
-      if (TYPE_READONLY (type) || TYPE_VOLATILE (type)
-         || constp || volatilep)
-       restype = c_build_type_variant (restype,
-                                       TYPE_READONLY (type) || constp,
-                                       TYPE_VOLATILE (type) || volatilep);
+      if (TYPE_QUALS (type) || constp || volatilep)
+       restype 
+         = c_build_qualified_type (restype,
+                                   TYPE_QUALS (type) 
+                                   | (constp * TYPE_QUAL_CONST)
+                                   | (volatilep * TYPE_QUAL_VOLATILE));
 
       if (TREE_CODE (exp) == INDIRECT_REF)
        return convert (TYPE_POINTER_TO (restype),
@@ -1269,7 +1142,7 @@ build_component_ref (datum, component)
     {
       tree indirect = 0;
 
-      if (TYPE_SIZE (type) == 0)
+      if (!COMPLETE_TYPE_P (type))
        {
          incomplete_type_error (NULL_TREE, type);
          return error_mark_node;
@@ -1279,9 +1152,8 @@ build_component_ref (datum, component)
 
       if (!field)
        {
-         error (code == RECORD_TYPE
-                ? "structure has no member named `%s'"
-                : "union has no member named `%s'",
+         error ("%s has no member named `%s'",
+                code == RECORD_TYPE ? "structure" : "union",
                 IDENTIFIER_POINTER (component));
          return error_mark_node;
        }
@@ -1324,7 +1196,7 @@ build_component_ref (datum, component)
 tree
 build_indirect_ref (ptr, errorstring)
      tree ptr;
-     char *errorstring;
+     const char *errorstring;
 {
   register tree pointer = default_conversion (ptr);
   register tree type = TREE_TYPE (pointer);
@@ -1342,7 +1214,7 @@ build_indirect_ref (ptr, errorstring)
          register tree ref = build1 (INDIRECT_REF,
                                      TYPE_MAIN_VARIANT (t), pointer);
 
-         if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE)
+         if (!COMPLETE_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
            {
              error ("dereferencing pointer to incomplete type");
              return error_mark_node;
@@ -1422,7 +1294,7 @@ build_array_ref (array, index)
         address arithmetic on its address.
         Likewise an array of elements of variable size.  */
       if (TREE_CODE (index) != INTEGER_CST
-         || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0
+         || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
              && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
        {
          if (mark_addressable (array) == 0)
@@ -1528,7 +1400,7 @@ build_function_call (function, params)
 {
   register tree fntype, fundecl = 0;
   register tree coerced_params;
-  tree name = NULL_TREE, assembler_name = NULL_TREE;
+  tree name = NULL_TREE, assembler_name = NULL_TREE, result;
 
   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
   STRIP_TYPE_NOPS (function);
@@ -1584,28 +1456,20 @@ build_function_call (function, params)
   if (TREE_CODE (function) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
       && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
-    switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0)))
-      {
-      case BUILT_IN_ABS:
-      case BUILT_IN_LABS:
-      case BUILT_IN_FABS:
-       if (coerced_params == 0)
-         return integer_zero_node;
-       return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
-      default:
-       break;
-      }
+    {
+      result = expand_tree_builtin (TREE_OPERAND (function, 0),
+                                   params, coerced_params);
+      if (result)
+       return result;
+    }
 
-  {
-    register tree result
-      = build (CALL_EXPR, TREE_TYPE (fntype),
-              function, coerced_params, NULL_TREE);
-
-    TREE_SIDE_EFFECTS (result) = 1;
-    if (TREE_TYPE (result) == void_type_node)
-      return result;
-    return require_complete_type (result);
-  }
+  result = build (CALL_EXPR, TREE_TYPE (fntype),
+                 function, coerced_params, NULL_TREE);
+
+  TREE_SIDE_EFFECTS (result) = 1;
+  if (TREE_TYPE (result) == void_type_node)
+    return result;
+  return require_complete_type (result);
 }
 \f
 /* Convert the argument expressions in the list VALUES
@@ -1671,7 +1535,7 @@ convert_arguments (typelist, values, name, fundecl)
          /* Formal parm type is specified by a function prototype.  */
          tree parmval;
 
-         if (TYPE_SIZE (type) == 0)
+         if (!COMPLETE_TYPE_P (type))
            {
              error ("type of formal parameter %d is incomplete", parmnum + 1);
              parmval = val;
@@ -1764,12 +1628,11 @@ convert_arguments (typelist, values, name, fundecl)
                                                (char *) 0, /* arg passing  */
                                                fundecl, name, parmnum + 1);
              
-#ifdef PROMOTE_PROTOTYPES
-             if ((TREE_CODE (type) == INTEGER_TYPE
-                  || TREE_CODE (type) == ENUMERAL_TYPE)
+             if (PROMOTE_PROTOTYPES
+                 && (TREE_CODE (type) == INTEGER_TYPE
+                     || TREE_CODE (type) == ENUMERAL_TYPE)
                  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
                parmval = default_conversion (parmval);
-#endif
            }
          result = tree_cons (NULL_TREE, parmval, result);
        }
@@ -2047,17 +1910,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
          if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
            resultcode = RDIV_EXPR;
          else
-           {
-             /* Although it would be tempting to shorten always here, that
-                loses on some targets, since the modulo instruction is
-                undefined if the quotient can't be represented in the
-                computation mode.  We shorten only if unsigned or if
-                dividing by something we know != -1.  */
-             shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
-                        || (TREE_CODE (op1) == INTEGER_CST
-                            && (TREE_INT_CST_LOW (op1) != -1
-                                || TREE_INT_CST_HIGH (op1) != -1)));
-           }
+           /* Although it would be tempting to shorten always here, that
+              loses on some targets, since the modulo instruction is
+              undefined if the quotient can't be represented in the
+              computation mode.  We shorten only if unsigned or if
+              dividing by something we know != -1.  */
+           shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
+                      || (TREE_CODE (op1) == INTEGER_CST
+                          && ! integer_all_onesp (op1)));
          common = 1;
        }
       break;
@@ -2103,8 +1963,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
             only if unsigned or if dividing by something we know != -1.  */
          shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
                     || (TREE_CODE (op1) == INTEGER_CST
-                        && (TREE_INT_CST_LOW (op1) != -1
-                            || TREE_INT_CST_HIGH (op1) != -1)));
+                        && ! integer_all_onesp (op1)));
          common = 1;
        }
       break;
@@ -2142,14 +2001,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
                warning ("right shift count is negative");
              else
                {
-                 if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1))
+                 if (! integer_zerop (op1))
                    short_shift = 1;
-                 if (TREE_INT_CST_HIGH (op1) != 0
-                     || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
-                         >= TYPE_PRECISION (type0)))
+
+                 if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
                    warning ("right shift count >= width of type");
                }
            }
+
          /* Use the type of the value to be shifted.
             This is what most traditional C compilers do.  */
          result_type = type0;
@@ -2172,11 +2031,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
            {
              if (tree_int_cst_sgn (op1) < 0)
                warning ("left shift count is negative");
-             else if (TREE_INT_CST_HIGH (op1) != 0
-                      || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
-                          >= TYPE_PRECISION (type0)))
+
+             else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
                warning ("left shift count >= width of type");
            }
+
          /* Use the type of the value to be shifted.
             This is what most traditional C compilers do.  */
          result_type = type0;
@@ -2200,11 +2059,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
            {
              if (tree_int_cst_sgn (op1) < 0)
                warning ("shift count is negative");
-             else if (TREE_INT_CST_HIGH (op1) != 0
-                      || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
-                          >= TYPE_PRECISION (type0)))
+             else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
                warning ("shift count >= width of type");
            }
+
          /* Use the type of the value to be shifted.
             This is what most traditional C compilers do.  */
          result_type = type0;
@@ -2222,6 +2080,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
 
     case EQ_EXPR:
     case NE_EXPR:
+      if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE))
+       warning ("comparing floating point with == or != is unsafe");
       /* Result of comparison is always int,
         but don't convert the args to int!  */
       build_type = integer_type_node;
@@ -2314,8 +2174,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
          if (comp_target_types (type0, type1))
            {
              result_type = common_type (type0, type1);
-             if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
-                 != (TYPE_SIZE (TREE_TYPE (type1)) != 0))
+             if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
+                 != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
                pedwarn ("comparison of complete and incomplete pointers");
              else if (pedantic 
                       && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
@@ -2354,7 +2214,23 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
            pedwarn ("comparison between pointer and integer");
        }
       break;
-      
+
+    case UNORDERED_EXPR:
+    case ORDERED_EXPR:
+    case UNLT_EXPR:
+    case UNLE_EXPR:
+    case UNGT_EXPR:
+    case UNGE_EXPR:
+    case UNEQ_EXPR:
+      build_type = integer_type_node;
+      if (code0 != REAL_TYPE || code1 != REAL_TYPE)
+       {
+         error ("unordered comparison on non-floating point argument");
+         return error_mark_node;
+       }
+      common = 1;
+      break;
+
     default:
       break;
     }
@@ -2458,8 +2334,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
          if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
              /* We can shorten only if the shift count is less than the
                 number of bits in the smaller type size.  */
-             && TREE_INT_CST_HIGH (op1) == 0
-             && TYPE_PRECISION (TREE_TYPE (arg0)) > TREE_INT_CST_LOW (op1)
+             && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
              /* If arg is sign-extended and then unsigned-shifted,
                 we can simulate this with a signed shift in arg's type
                 only if the extended result is at least twice as wide
@@ -2469,7 +2344,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
                 it never happens because available widths are 2**N.  */
              && (!TREE_UNSIGNED (final_type)
                  || unsigned_arg
-                 || 2 * TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (result_type)))
+                 || (2 * TYPE_PRECISION (TREE_TYPE (arg0))
+                     <= TYPE_PRECISION (result_type))))
            {
              /* Do an unsigned shift if the operand was zero-extended.  */
              result_type
@@ -2495,8 +2371,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
          enum tree_code xresultcode = resultcode;
          tree val 
            = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
+
          if (val != 0)
            return val;
+
          op0 = xop0, op1 = xop1;
          converted = 1;
          resultcode = xresultcode;
@@ -2506,50 +2384,63 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
            {
              int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
              int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
-
              int unsignedp0, unsignedp1;
              tree primop0 = get_narrower (op0, &unsignedp0);
              tree primop1 = get_narrower (op1, &unsignedp1);
 
-             /* Avoid spurious warnings for comparison with enumerators.  */
              xop0 = orig_op0;
              xop1 = orig_op1;
              STRIP_TYPE_NOPS (xop0);
              STRIP_TYPE_NOPS (xop1);
 
              /* Give warnings for comparisons between signed and unsigned
-                quantities that may fail.  */
-             /* Do the checking based on the original operand trees, so that
-                casts will be considered, but default promotions won't be.  */
+                quantities that may fail. 
 
-             /* Do not warn if the comparison is being done in a signed type,
+                Do the checking based on the original operand trees, so that
+                casts will be considered, but default promotions won't be.
+
+                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))
                /* OK */;
-              /* Do not warn if both operands are unsigned.  */
+              /* Do not warn if both operands are the same signedness.  */
               else if (op0_signed == op1_signed)
                 /* OK */;
-             /* Do not warn if the signed quantity is an unsuffixed
-                integer literal (or some static constant expression
-                involving such literals) and it is non-negative.  */
-             else if ((op0_signed && TREE_CODE (xop0) == INTEGER_CST
-                       && tree_int_cst_sgn (xop0) >= 0)
-                      || (op1_signed && TREE_CODE (xop1) == INTEGER_CST
-                          && tree_int_cst_sgn (xop1) >= 0))
-               /* OK */;
-             /* Do not warn if the comparison is an equality operation,
-                 the unsigned quantity is an integral constant and it does
-                 not use the most significant bit of result_type.  */
-             else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR)
-                      && ((op0_signed && TREE_CODE (xop1) == INTEGER_CST
-                           && int_fits_type_p (xop1, signed_type (result_type)))
-                          || (op1_signed && TREE_CODE (xop0) == INTEGER_CST
-                              && int_fits_type_p (xop0, signed_type (result_type)))))
-               /* OK */;
              else
-               warning ("comparison between signed and unsigned");
+               {
+                 tree sop, uop;
+
+                 if (op0_signed)
+                   sop = xop0, uop = xop1;
+                 else
+                   sop = xop1, uop = xop0;
+
+                 /* Do not warn if the signed quantity is an
+                    unsuffixed integer literal (or some static
+                    constant expression involving such literals or a
+                    conditional expression involving such literals)
+                    and it is non-negative.  */
+                 if (tree_expr_nonnegative_p (sop))
+                   /* OK */;
+                 /* Do not warn if the comparison is an equality operation,
+                    the unsigned quantity is an integral constant, and it
+                    would fit in the result if the result were signed.  */
+                 else if (TREE_CODE (uop) == INTEGER_CST
+                          && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
+                          && int_fits_type_p (uop, signed_type (result_type)))
+                   /* OK */;
+                 /* Do not warn if the unsigned quantity is an enumeration
+                    constant and its maximum value would fit in the result
+                    if the result were signed.  */
+                 else if (TREE_CODE (uop) == INTEGER_CST
+                          && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
+                          && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE(uop)),
+                                              signed_type (result_type)))
+                   /* OK */;
+                 else
+                   warning ("comparison between signed and unsigned");
+               }
 
              /* Warn if two unsigned values are being compared in a size
                 larger than their original size, and one (and only one) is the
@@ -2569,31 +2460,30 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
                    primop1 = get_narrower (TREE_OPERAND (primop1, 0),
                                            &unsignedp1);
              
-                 if (TREE_CODE (primop0) == INTEGER_CST
-                     || TREE_CODE (primop1) == INTEGER_CST)
+                 if (host_integerp (primop0, 0) || host_integerp (primop1, 0))
                    {
                      tree primop;
-                     long constant, mask;
+                     HOST_WIDE_INT constant, mask;
                      int unsignedp, bits;
 
-                     if (TREE_CODE (primop0) == INTEGER_CST)
+                     if (host_integerp (primop0, 0))
                        {
                          primop = primop1;
                          unsignedp = unsignedp1;
-                         constant = TREE_INT_CST_LOW (primop0);
+                         constant = tree_low_cst (primop0, 0);
                        }
                      else
                        {
                          primop = primop0;
                          unsignedp = unsignedp0;
-                         constant = TREE_INT_CST_LOW (primop1);
+                         constant = tree_low_cst (primop1, 0);
                        }
 
                      bits = TYPE_PRECISION (TREE_TYPE (primop));
                      if (bits < TYPE_PRECISION (result_type)
-                         && bits < HOST_BITS_PER_LONG && unsignedp)
+                         && bits < HOST_BITS_PER_WIDE_INT && unsignedp)
                        {
-                         mask = (~0L) << bits;
+                         mask = (~ (HOST_WIDE_INT) 0) << bits;
                          if ((mask & constant) != mask)
                            warning ("comparison of promoted ~unsigned with constant");
                        }
@@ -2762,7 +2652,7 @@ pointer_diff (op0, op1)
   op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
                         convert (restype, op1), 0);
   /* This generates an error if op1 is pointer to incomplete type.  */
-  if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
+  if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
     error ("arithmetic on pointer to an incomplete type");
 
   /* This generates an error if op0 is pointer to incomplete type.  */
@@ -2793,7 +2683,6 @@ build_unary_op (code, xarg, noconvert)
   register tree arg = xarg;
   register tree argtype = 0;
   register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));
-  char *errstring = NULL;
   tree val;
 
   if (typecode == ERROR_MARK)
@@ -2809,7 +2698,10 @@ build_unary_op (code, xarg, noconvert)
         associativity, but won't generate any code.  */
       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
            || typecode == COMPLEX_TYPE))
-        errstring = "wrong type argument to unary plus";
+       {
+         error ("wrong type argument to unary plus");
+         return error_mark_node;
+       }
       else if (!noconvert)
        arg = default_conversion (arg);
       break;
@@ -2817,7 +2709,10 @@ build_unary_op (code, xarg, noconvert)
     case NEGATE_EXPR:
       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
            || typecode == COMPLEX_TYPE))
-        errstring = "wrong type argument to unary minus";
+       {
+         error ("wrong type argument to unary minus");
+         return error_mark_node;
+       }
       else if (!noconvert)
        arg = default_conversion (arg);
       break;
@@ -2830,7 +2725,10 @@ build_unary_op (code, xarg, noconvert)
            arg = default_conversion (arg);
        }
       else if (typecode != INTEGER_TYPE)
-        errstring = "wrong type argument to bit-complement";
+       {
+         error ("wrong type argument to bit-complement");
+         return error_mark_node;
+       }
       else if (!noconvert)
        arg = default_conversion (arg);
       break;
@@ -2838,7 +2736,10 @@ build_unary_op (code, xarg, noconvert)
     case ABS_EXPR:
       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
            || typecode == COMPLEX_TYPE))
-        errstring = "wrong type argument to abs";
+       {
+         error ("wrong type argument to abs");
+         return error_mark_node;
+       }
       else if (!noconvert)
        arg = default_conversion (arg);
       break;
@@ -2847,7 +2748,10 @@ build_unary_op (code, xarg, noconvert)
       /* Conjugating a real value is a no-op, but allow it anyway.  */
       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
            || typecode == COMPLEX_TYPE))
-       errstring = "wrong type argument to conjugation";
+       {
+         error ("wrong type argument to conjugation");
+         return error_mark_node;
+       }
       else if (!noconvert)
        arg = default_conversion (arg);
       break;
@@ -2859,8 +2763,8 @@ build_unary_op (code, xarg, noconvert)
          /* These will convert to a pointer.  */
          && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
        {
-         errstring = "wrong type argument to unary exclamation mark";
-         break;
+         error ("wrong type argument to unary exclamation mark");
+         return error_mark_node;
        }
       arg = truthvalue_conversion (arg);
       return invert_truthvalue (arg);
@@ -2913,11 +2817,10 @@ build_unary_op (code, xarg, noconvert)
       if (typecode != POINTER_TYPE
          && typecode != INTEGER_TYPE && typecode != REAL_TYPE)
        {
-         if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
-           errstring ="wrong type argument to increment";
-         else
-           errstring ="wrong type argument to decrement";
-         break;
+         error ("wrong type argument to %s",
+                code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+                ? "increment" : "decrement");
+         return error_mark_node;
        }
 
       {
@@ -2933,18 +2836,16 @@ build_unary_op (code, xarg, noconvert)
          {
            /* If pointer target is an undefined struct,
               we just cannot know how to do the arithmetic.  */
-           if (TYPE_SIZE (TREE_TYPE (result_type)) == 0)
+           if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type)))
              error ("%s of pointer to unknown structure",
-                      ((code == PREINCREMENT_EXPR
-                        || code == POSTINCREMENT_EXPR)
-                       ? "increment" : "decrement"));
+                    code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+                    ? "increment" : "decrement");
            else if ((pedantic || warn_pointer_arith)
                     && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
                         || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
              pedwarn ("wrong type argument to %s",
-                      ((code == PREINCREMENT_EXPR
-                        || code == POSTINCREMENT_EXPR)
-                       ? "increment" : "decrement"));
+                      code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+                      ? "increment" : "decrement");
            inc = c_size_in_bytes (TREE_TYPE (result_type));
          }
        else
@@ -3001,7 +2902,8 @@ build_unary_op (code, xarg, noconvert)
        /* Complain about anything else that is not a true lvalue.  */
        if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
                                    || code == POSTINCREMENT_EXPR)
-                                  ? "increment" : "decrement")))
+                                  ? "invalid lvalue in increment"
+                                  : "invalid lvalue in decrement")))
          return error_mark_node;
 
        /* Report a read-only lvalue.  */
@@ -3075,21 +2977,22 @@ build_unary_op (code, xarg, noconvert)
        ;
       /* Anything not already handled and not a true memory reference
         is an error.  */
-      else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "unary `&'"))
+      else if (typecode != FUNCTION_TYPE
+              && !lvalue_or_else (arg, "invalid lvalue in unary `&'"))
        return error_mark_node;
 
       /* Ordinary case; arg is a COMPONENT_REF or a decl.  */
       argtype = TREE_TYPE (arg);
-      /* If the lvalue is const or volatile,
-        merge that into the type that the address will point to.  */
-      if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
-         || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
-       {
-         if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
-           argtype = c_build_type_variant (argtype,
-                                           TREE_READONLY (arg),
-                                           TREE_THIS_VOLATILE (arg));
-       }
+
+      /* If the lvalue is const or volatile, merge that into the type
+         to which the address will point.  Note that you can't get a
+        restricted pointer by taking the address of something, so we
+        only have to deal with `const' and `volatile' here.  */
+      if ((DECL_P (arg) || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
+         && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)))
+         argtype = c_build_type_variant (argtype,
+                                         TREE_READONLY (arg),
+                                         TREE_THIS_VOLATILE (arg));
 
       argtype = build_pointer_type (argtype);
 
@@ -3112,18 +3015,9 @@ build_unary_op (code, xarg, noconvert)
                return error_mark_node;
              }
 
-           addr = convert (argtype, addr);
-
-           if (! integer_zerop (DECL_FIELD_BITPOS (field)))
-             {
-               tree offset
-                 = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field),
-                               size_int (BITS_PER_UNIT));
-               int flag = TREE_CONSTANT (addr);
-               addr = fold (build (PLUS_EXPR, argtype,
-                                   addr, convert (argtype, offset)));
-               TREE_CONSTANT (addr) = flag;
-             }
+           addr = fold (build (PLUS_EXPR, argtype,
+                               convert (argtype, addr),
+                               convert (argtype, byte_position (field))));
          }
        else
          addr = build1 (code, argtype, arg);
@@ -3141,15 +3035,9 @@ build_unary_op (code, xarg, noconvert)
       break;
     }
 
-  if (!errstring)
-    {
-      if (argtype == 0)
-       argtype = TREE_TYPE (arg);
-      return fold (build1 (code, argtype, arg));
-    }
-
-  error (errstring);
-  return error_mark_node;
+  if (argtype == 0)
+    argtype = TREE_TYPE (arg);
+  return fold (build1 (code, argtype, arg));
 }
 
 #if 0
@@ -3223,13 +3111,15 @@ lvalue_p (ref)
    otherwise, print an error message and return zero.  */
 
 int
-lvalue_or_else (ref, string)
+lvalue_or_else (ref, msgid)
      tree ref;
-     char *string;
+     const char *msgid;
 {
   int win = lvalue_p (ref);
+
   if (! win)
-    error ("invalid lvalue in %s", string);
+    error ("%s", msgid);
+
   return win;
 }
 
@@ -3282,47 +3172,45 @@ pedantic_lvalue_warning (code)
      enum tree_code code;
 {
   if (pedantic)
-    pedwarn ("ANSI C forbids use of %s expressions as lvalues",
-            code == COND_EXPR ? "conditional"
-            : code == COMPOUND_EXPR ? "compound" : "cast");
+    switch (code)
+      {
+      case COND_EXPR:
+       pedwarn ("ANSI C forbids use of conditional expressions as lvalues");
+       break;
+      case COMPOUND_EXPR:
+       pedwarn ("ANSI C forbids use of compound expressions as lvalues");
+       break;
+      default:
+       pedwarn ("ANSI C forbids use of cast expressions as lvalues");
+       break;
+      }
 }
 \f
 /* Warn about storing in something that is `const'.  */
 
 void
-readonly_warning (arg, string)
+readonly_warning (arg, msgid)
      tree arg;
-     char *string;
+     const char *msgid;
 {
-  char buf[80];
-  strcpy (buf, string);
-
   /* Forbid assignments to iterators.  */
   if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg))
-    {
-      strcat (buf, " of iterator `%s'");
-      pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg)));
-    }
+    pedwarn ("%s of iterator `%s'",  _(msgid), 
+            IDENTIFIER_POINTER (DECL_NAME (arg)));
 
   if (TREE_CODE (arg) == COMPONENT_REF)
     {
       if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
-       readonly_warning (TREE_OPERAND (arg, 0), string);
+       readonly_warning (TREE_OPERAND (arg, 0), msgid);
       else
-       {
-         strcat (buf, " of read-only member `%s'");
-         pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
-       }
+       pedwarn ("%s of read-only member `%s'", _(msgid),
+                IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
     }
   else if (TREE_CODE (arg) == VAR_DECL)
-    {
-      strcat (buf, " of read-only variable `%s'");
-      pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg)));
-    }
+    pedwarn ("%s of read-only variable `%s'", _(msgid),
+            IDENTIFIER_POINTER (DECL_NAME (arg)));
   else
-    {
-      pedwarn ("%s of read-only location", buf);
-    }
+    pedwarn ("%s of read-only location", _(msgid));
 }
 \f
 /* Mark EXP saying that we need to be able to take the
@@ -3474,6 +3362,35 @@ build_conditional_expr (ifexp, op1, op2)
            && (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
     {
       result_type = common_type (type1, type2);
+
+      /* If -Wsign-compare, warn here if type1 and type2 have
+        different signedness.  We'll promote the signed to unsigned
+        and later code won't know it used to be different.
+        Do this check on the original types, so that explicit casts
+        will be considered, but default promotions won't.  */
+      if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare)
+         && !skip_evaluation)
+       {
+         int unsigned_op1 = TREE_UNSIGNED (TREE_TYPE (orig_op1));
+         int unsigned_op2 = TREE_UNSIGNED (TREE_TYPE (orig_op2));
+
+         if (unsigned_op1 ^ unsigned_op2)
+           {
+             /* Do not warn if the result type is signed, since the
+                signed type will only be chosen if it can represent
+                all the values of the unsigned type.  */
+             if (! TREE_UNSIGNED (result_type))
+               /* OK */;
+             /* Do not warn if the signed quantity is an unsuffixed
+                integer literal (or some static constant expression
+                involving such literals) and it is non-negative.  */
+             else if ((unsigned_op2 && tree_expr_nonnegative_p (op1))
+                      || (unsigned_op1 && tree_expr_nonnegative_p (op2)))
+               /* OK */;
+             else
+               warning ("signed and unsigned type in conditional expression");
+           }
+       }
     }
   else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
     {
@@ -3560,43 +3477,6 @@ build_conditional_expr (ifexp, op1, op2)
   if (result_type != TREE_TYPE (op2))
     op2 = convert_and_check (result_type, op2);
     
-#if 0
-  if (code1 == RECORD_TYPE || code1 == UNION_TYPE)
-    {
-      result_type = TREE_TYPE (op1);
-      if (TREE_CONSTANT (ifexp))
-       return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
-
-      if (TYPE_MODE (result_type) == BLKmode)
-       {
-         register tree tempvar
-           = build_decl (VAR_DECL, NULL_TREE, result_type);
-         register tree xop1 = build_modify_expr (tempvar, op1);
-         register tree xop2 = build_modify_expr (tempvar, op2);
-         register tree result = fold (build (COND_EXPR, result_type,
-                                             ifexp, xop1, xop2));
-
-         layout_decl (tempvar, TYPE_ALIGN (result_type));
-         /* No way to handle variable-sized objects here.
-            I fear that the entire handling of BLKmode conditional exprs
-            needs to be redone.  */
-         if (TREE_CODE (DECL_SIZE (tempvar)) != INTEGER_CST)
-           abort ();
-         DECL_RTL (tempvar)
-           = assign_stack_local (DECL_MODE (tempvar),
-                                 (TREE_INT_CST_LOW (DECL_SIZE (tempvar))
-                                  + BITS_PER_UNIT - 1)
-                                 / BITS_PER_UNIT,
-                                 0);
-
-         TREE_SIDE_EFFECTS (result)
-           = TREE_SIDE_EFFECTS (ifexp) | TREE_SIDE_EFFECTS (op1)
-             | TREE_SIDE_EFFECTS (op2);
-         return build (COMPOUND_EXPR, result_type, result, tempvar);
-       }
-    }
-#endif /* 0 */
-    
   if (TREE_CODE (ifexp) == INTEGER_CST)
     return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
 
@@ -3726,7 +3606,7 @@ build_c_cast (type, expr)
 
       if (field)
        {
-         char *name;
+         const char *name;
          tree t;
 
          if (pedantic)
@@ -3771,19 +3651,27 @@ build_c_cast (type, expr)
          && TREE_CODE (type) == POINTER_TYPE
          && TREE_CODE (otype) == POINTER_TYPE)
        {
-         /* Go to the innermost object being pointed to.  */
          tree in_type = type;
          tree in_otype = otype;
+         int warn = 0;
+
+         /* Check that the qualifiers on IN_TYPE are a superset of
+            the qualifiers of IN_OTYPE.  The outermost level of
+            POINTER_TYPE nodes is uninteresting and we stop as soon
+            as we hit a non-POINTER_TYPE node on either type.  */
+         do
+           {
+             in_otype = TREE_TYPE (in_otype);
+             in_type = TREE_TYPE (in_type);
+             warn |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
+           }
+         while (TREE_CODE (in_type) == POINTER_TYPE
+                && TREE_CODE (in_otype) == POINTER_TYPE);
 
-         while (TREE_CODE (in_type) == POINTER_TYPE)
-           in_type = TREE_TYPE (in_type);
-         while (TREE_CODE (in_otype) == POINTER_TYPE)
-           in_otype = TREE_TYPE (in_otype);
-           
-         if (TYPE_VOLATILE (in_otype) && ! TYPE_VOLATILE (in_type))
-           pedwarn ("cast discards `volatile' from pointer target type");
-         if (TYPE_READONLY (in_otype) && ! TYPE_READONLY (in_type))
-           pedwarn ("cast discards `const' from pointer target type");
+         if (warn)
+           /* There are qualifiers present in IN_OTYPE that are not
+              present in IN_TYPE.  */
+           pedwarn ("cast discards qualifiers from pointer target type");
        }
 
       /* Warn about possible alignment problems.  */
@@ -3884,8 +3772,7 @@ build_modify_expr (lhs, modifycode, rhs)
       /* Handle (a, b) used as an "lvalue".  */
     case COMPOUND_EXPR:
       pedantic_lvalue_warning (COMPOUND_EXPR);
-      newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
-                                 modifycode, rhs);
+      newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), modifycode, rhs);
       if (TREE_CODE (newrhs) == ERROR_MARK)
        return error_mark_node;
       return build (COMPOUND_EXPR, lhstype,
@@ -3964,7 +3851,7 @@ build_modify_expr (lhs, modifycode, rhs)
   /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
      Reject anything strange now.  */
 
-  if (!lvalue_or_else (lhs, "assignment"))
+  if (!lvalue_or_else (lhs, "invalid lvalue in assignment"))
     return error_mark_node;
 
   /* Warn about storing in something that is `const'.  */
@@ -3997,7 +3884,7 @@ build_modify_expr (lhs, modifycode, rhs)
 
   /* Convert new value to destination type.  */
 
-  newrhs = convert_for_assignment (lhstype, newrhs, "assignment",
+  newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"),
                                   NULL_TREE, NULL_TREE, 0);
   if (TREE_CODE (newrhs) == ERROR_MARK)
     return error_mark_node;
@@ -4012,7 +3899,7 @@ build_modify_expr (lhs, modifycode, rhs)
 
   if (olhstype == TREE_TYPE (result))
     return result;
-  return convert_for_assignment (olhstype, result, "assignment",
+  return convert_for_assignment (olhstype, result, _("assignment"),
                                 NULL_TREE, NULL_TREE, 0);
 }
 \f
@@ -4023,9 +3910,7 @@ build_modify_expr (lhs, modifycode, rhs)
    for assignments that are not allowed in C.
    ERRTYPE is a string to use in error messages:
    "assignment", "return", etc.  If it is null, this is parameter passing
-   for a function call (and different error messages are output).  Otherwise,
-   it may be a name stored in the spelling stack and interpreted by
-   get_spelling.
+   for a function call (and different error messages are output).
 
    FUNNAME is the name of the function being called,
    as an IDENTIFIER_NODE, or null.
@@ -4034,7 +3919,7 @@ build_modify_expr (lhs, modifycode, rhs)
 static tree
 convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
      tree type, rhs;
-     char *errtype;
+     const char *errtype;
      tree fundecl, funname;
      int parmnum;
 {
@@ -4074,11 +3959,32 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
       error ("void value not ignored as it ought to be");
       return error_mark_node;
     }
+  /* A type converts to a reference to it.  
+     This code doesn't fully support references, it's just for the
+     special case of va_start and va_copy.  */
+  if (codel == REFERENCE_TYPE
+      && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
+    {
+      if (mark_addressable (rhs) == 0)
+       return error_mark_node;
+      rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
+
+      /* We already know that these two types are compatible, but they
+        may not be exactly identical.  In fact, `TREE_TYPE (type)' is
+        likely to be __builtin_va_list and `TREE_TYPE (rhs)' is
+        likely to be va_list, a typedef to __builtin_va_list, which
+        is different enough that it will cause problems later.  */
+      if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type))
+       rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
+
+      rhs = build1 (NOP_EXPR, type, rhs);
+      return rhs;
+    }
   /* Arithmetic types all interconvert, and enum is treated like int.  */
-  if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE
-       || codel == COMPLEX_TYPE)
-      && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
-         || coder == COMPLEX_TYPE))
+  else if ((codel == INTEGER_TYPE || codel == REAL_TYPE 
+           || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE)
+          && (coder == INTEGER_TYPE || coder == REAL_TYPE 
+              || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE))
     return convert_and_check (type, rhs);
 
   /* Conversion to a transparent union from its member types.
@@ -4114,12 +4020,13 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
                  || comp_target_types (memb_type, rhstype))
                {
                  /* If this type won't generate any warnings, use it.  */
-                 if ((TREE_CODE (ttr) == FUNCTION_TYPE
-                      && TREE_CODE (ttl) == FUNCTION_TYPE)
-                     ? ((! TYPE_READONLY (ttl) | TYPE_READONLY (ttr))
-                        & (! TYPE_VOLATILE (ttl) | TYPE_VOLATILE (ttr)))
-                     : ((TYPE_READONLY (ttl) | ! TYPE_READONLY (ttr))
-                        & (TYPE_VOLATILE (ttl) | ! TYPE_VOLATILE (ttr))))
+                 if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
+                     || ((TREE_CODE (ttr) == FUNCTION_TYPE
+                          && TREE_CODE (ttl) == FUNCTION_TYPE)
+                         ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
+                            == TYPE_QUALS (ttr))
+                         : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
+                            == TYPE_QUALS (ttl))))
                    break;
 
                  /* Keep looking for a better type, but remember this one.  */
@@ -4157,26 +4064,14 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
                     certain things, it is okay to use a const or volatile
                     function where an ordinary one is wanted, but not
                     vice-versa.  */
-                 if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
-                   warn_for_assignment ("%s makes `const *' function pointer from non-const",
-                                        get_spelling (errtype), funname,
-                                        parmnum);
-                 if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr))
-                   warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile",
-                                        get_spelling (errtype), funname,
-                                        parmnum);
-               }
-             else
-               {
-                 if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
-                   warn_for_assignment ("%s discards `const' from pointer target type",
-                                        get_spelling (errtype), funname,
-                                        parmnum);
-                 if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
-                   warn_for_assignment ("%s discards `volatile' from pointer target type",
-                                        get_spelling (errtype), funname,
-                                        parmnum);
+                 if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
+                   warn_for_assignment ("%s makes qualified function pointer from unqualified",
+                                        errtype, funname, parmnum);
                }
+             else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
+               warn_for_assignment ("%s discards qualifiers from pointer target type",
+                                    errtype, funname,
+                                    parmnum);
            }
          
          if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
@@ -4187,7 +4082,8 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
     }
 
   /* Conversions among pointers */
-  else if (codel == POINTER_TYPE && coder == POINTER_TYPE)
+  else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
+          && (coder == POINTER_TYPE || coder == REFERENCE_TYPE))
     {
       register tree ttl = TREE_TYPE (type);
       register tree ttr = TREE_TYPE (rhstype);
@@ -4211,18 +4107,15 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
                   && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR)
                   && TREE_CODE (ttl) == FUNCTION_TYPE)))
            warn_for_assignment ("ANSI forbids %s between function pointer and `void *'",
-                                get_spelling (errtype), funname, parmnum);
+                                errtype, funname, parmnum);
          /* Const and volatile mean something different for function types,
             so the usual warnings are not appropriate.  */
          else if (TREE_CODE (ttr) != FUNCTION_TYPE
                   && TREE_CODE (ttl) != FUNCTION_TYPE)
            {
-             if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
-               warn_for_assignment ("%s discards `const' from pointer target type",
-                                    get_spelling (errtype), funname, parmnum);
-             else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
-               warn_for_assignment ("%s discards `volatile' from pointer target type",
-                                    get_spelling (errtype), funname, parmnum);
+             if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
+               warn_for_assignment ("%s discards qualifiers from pointer target type",
+                                    errtype, funname, parmnum);
              /* If this is not a case of ignoring a mismatch in signedness,
                 no warning.  */
              else if (TYPE_MAIN_VARIANT (ttl) == void_type_node
@@ -4232,7 +4125,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
              /* If there is a mismatch, do warn.  */
              else if (pedantic)
                warn_for_assignment ("pointer targets in %s differ in signedness",
-                                    get_spelling (errtype), funname, parmnum);
+                                    errtype, funname, parmnum);
            }
          else if (TREE_CODE (ttl) == FUNCTION_TYPE
                   && TREE_CODE (ttr) == FUNCTION_TYPE)
@@ -4241,17 +4134,14 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
                 that say the function will not do certain things,
                 it is okay to use a const or volatile function
                 where an ordinary one is wanted, but not vice-versa.  */
-             if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
-               warn_for_assignment ("%s makes `const *' function pointer from non-const",
-                                    get_spelling (errtype), funname, parmnum);
-             if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr))
-               warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile",
-                                    get_spelling (errtype), funname, parmnum);
+             if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
+               warn_for_assignment ("%s makes qualified function pointer from unqualified",
+                                    errtype, funname, parmnum);
            }
        }
       else
        warn_for_assignment ("%s from incompatible pointer type",
-                            get_spelling (errtype), funname, parmnum);
+                            errtype, funname, parmnum);
       return convert (type, rhs);
     }
   else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
@@ -4267,7 +4157,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
             && integer_zerop (TREE_OPERAND (rhs, 0))))
        {
          warn_for_assignment ("%s makes pointer from integer without a cast",
-                              get_spelling (errtype), funname, parmnum);
+                              errtype, funname, parmnum);
          return convert (type, rhs);
        }
       return null_pointer_node;
@@ -4275,7 +4165,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
   else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
     {
       warn_for_assignment ("%s makes integer from pointer without a cast",
-                          get_spelling (errtype), funname, parmnum);
+                          errtype, funname, parmnum);
       return convert (type, rhs);
     }
 
@@ -4297,30 +4187,28 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
               parmnum);
     }
   else
-    error ("incompatible types in %s", get_spelling (errtype));
+    error ("incompatible types in %s", errtype);
 
   return error_mark_node;
 }
 
-/* Print a warning using MSG.
+/* Print a warning using MSGID.
    It gets OPNAME as its one parameter.
    If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
    FUNCTION and ARGNUM are handled specially if we are building an
    Objective-C selector.  */
 
 static void
-warn_for_assignment (msg, opname, function, argnum)
-     char *msg;
-     char *opname;
+warn_for_assignment (msgid, opname, function, argnum)
+     const char *msgid;
+     const char *opname;
      tree function;
      int argnum;
 {
-  static char argstring[] = "passing arg %d of `%s'";
-  static char argnofun[] =  "passing arg %d";
-
   if (opname == 0)
     {
       tree selector = maybe_building_objc_message_expr ();
+      char * new_opname;
       
       if (selector && argnum > 2)
        {
@@ -4330,159 +4218,25 @@ warn_for_assignment (msg, opname, function, argnum)
       if (function)
        {
          /* Function name is known; supply it.  */
-         opname = (char *) alloca (IDENTIFIER_LENGTH (function)
-                                   + sizeof (argstring) + 25 /*%d*/ + 1);
-         sprintf (opname, argstring, argnum, IDENTIFIER_POINTER (function));
+         const char *argstring = _("passing arg %d of `%s'");
+         new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
+                                       + strlen (argstring) + 1 + 25
+                                       /*%d*/ + 1);
+         sprintf (new_opname, argstring, argnum,
+                  IDENTIFIER_POINTER (function));
        }
       else
        {
-         /* Function name unknown (call through ptr); just give arg number.  */
-         opname = (char *) alloca (sizeof (argnofun) + 25 /*%d*/ + 1);
-         sprintf (opname, argnofun, argnum);
+         /* Function name unknown (call through ptr); just give arg number.*/
+         const char *argnofun = _("passing arg %d of pointer to function");
+         new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
+         sprintf (new_opname, argnofun, argnum);
        }
+      opname = new_opname;
     }
-  pedwarn (msg, opname);
+  pedwarn (msgid, opname);
 }
 \f
-/* Return nonzero if VALUE is a valid constant-valued expression
-   for use in initializing a static variable; one that can be an
-   element of a "constant" initializer.
-
-   Return null_pointer_node if the value is absolute;
-   if it is relocatable, return the variable that determines the relocation.
-   We assume that VALUE has been folded as much as possible;
-   therefore, we do not need to check for such things as
-   arithmetic-combinations of integers.  */
-
-tree
-initializer_constant_valid_p (value, endtype)
-     tree value;
-     tree endtype;
-{
-  switch (TREE_CODE (value))
-    {
-    case CONSTRUCTOR:
-      if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
-          || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
-         && TREE_CONSTANT (value)
-         && CONSTRUCTOR_ELTS (value))
-       return
-         initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
-                                       endtype);
-       
-      return TREE_STATIC (value) ? null_pointer_node : 0;
-
-    case INTEGER_CST:
-    case REAL_CST:
-    case STRING_CST:
-    case COMPLEX_CST:
-      return null_pointer_node;
-
-    case ADDR_EXPR:
-      return TREE_OPERAND (value, 0);
-
-    case NON_LVALUE_EXPR:
-      return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-    case CONVERT_EXPR:
-    case NOP_EXPR:
-      /* Allow conversions between pointer types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between real types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow length-preserving conversions between integer types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between other integer types only if
-        explicit value.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
-       {
-         tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                    endtype);
-         if (inner == null_pointer_node)
-           return null_pointer_node;
-         return 0;
-       }
-
-      /* Allow (int) &foo provided int is as wide as a pointer.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-
-      /* Likewise conversions from int to pointers, but also allow
-        conversions from 0.  */
-      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
-       {
-         if (integer_zerop (TREE_OPERAND (value, 0)))
-           return null_pointer_node;
-         else if (TYPE_PRECISION (TREE_TYPE (value))
-                  <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))
-           return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                endtype);
-       }
-
-      /* Allow conversions to union types if the value inside is okay.  */
-      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-      return 0;
-
-    case PLUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
-       return 0;
-      {
-       tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                   endtype);
-       tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
-                                                   endtype);
-       /* If either term is absolute, use the other terms relocation.  */
-       if (valid0 == null_pointer_node)
-         return valid1;
-       if (valid1 == null_pointer_node)
-         return valid0;
-       return 0;
-      }
-
-    case MINUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
-       return 0;
-      {
-       tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                   endtype);
-       tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
-                                                   endtype);
-       /* Win if second argument is absolute.  */
-       if (valid1 == null_pointer_node)
-         return valid0;
-       /* Win if both arguments have the same relocation.
-          Then the value is absolute.  */
-       if (valid0 == valid1)
-         return null_pointer_node;
-       return 0;
-      }
-
-    default:
-      return 0;
-    }
-}
-
 /* If VALUE is a compound expr all of whose expressions are constant, then
    return its value.  Otherwise, return error_mark_node.
 
@@ -4580,7 +4334,7 @@ struct spelling
   union
     {
       int i;
-      char *s;
+      const char *s;
     } u;
 };
 
@@ -4636,7 +4390,7 @@ static int spelling_size;         /* Size of the spelling stack.  */
 
 static void
 push_string (string)
-     char *string;
+     const char *string;
 {
   PUSH_SPELLING (SPELLING_STRING, string, u.s);
 }
@@ -4648,7 +4402,7 @@ push_member_name (decl)
      tree decl;
      
 {
-  char *string
+  const char *string
     = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>";
   PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
 }
@@ -4688,7 +4442,6 @@ print_spelling (buffer)
      register char *buffer;
 {
   register char *d = buffer;
-  register char *s;
   register struct spelling *p;
 
   for (p = spelling_base; p < spelling; p++)
@@ -4699,6 +4452,7 @@ print_spelling (buffer)
       }
     else
       {
+       register const char *s;
        if (p->kind == SPELLING_MEMBER)
          *d++ = '.';
        for (s = p->u.s; (*d = *s++); d++)
@@ -4708,115 +4462,52 @@ print_spelling (buffer)
   return buffer;
 }
 
-/* Provide a means to pass component names derived from the spelling stack.  */
-
-char initialization_message;
-
-/* Interpret the spelling of the given ERRTYPE message.  */
-
-static char *
-get_spelling (errtype)
-     char *errtype;
-{
-  static char *buffer;
-  static int size = -1;
-
-  if (errtype == &initialization_message)
-    {
-      /* Avoid counting chars */
-      static char message[] = "initialization of `%s'";
-      register int needed = sizeof (message) + spelling_length () + 1;
-      char *temp;
-
-      if (size < 0)
-       buffer = (char *) xmalloc (size = needed);
-      if (needed > size)
-       buffer = (char *) xrealloc (buffer, size = needed);
-
-      temp = (char *) alloca (needed);
-      sprintf (buffer, message, print_spelling (temp));
-      return buffer;
-    }
-
-  return errtype;
-}
-
 /* Issue an error message for a bad initializer component.
-   FORMAT describes the message.  OFWHAT is the name for the component.
-   LOCAL is a format string for formatting the insertion of the name
-   into the message.
-
-   If OFWHAT is null, the component name is stored on the spelling stack.
-   If the component name is a null string, then LOCAL is omitted entirely.  */
+   MSGID identifies the message.
+   The component name is taken from the spelling stack.  */
 
 void
-error_init (format, local, ofwhat)
-     char *format, *local, *ofwhat;
+error_init (msgid)
+     const char *msgid;
 {
-  char *buffer;
-
-  if (ofwhat == 0)
-    ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
-  buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+  char *ofwhat;
 
+  error ("%s", msgid);
+  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
-    sprintf (buffer, local, ofwhat);
-  else
-    buffer[0] = 0;
-
-  error (format, buffer);
+    error ("(near initialization for `%s')", ofwhat);
 }
 
 /* Issue a pedantic warning for a bad initializer component.
-   FORMAT describes the message.  OFWHAT is the name for the component.
-   LOCAL is a format string for formatting the insertion of the name
-   into the message.
-
-   If OFWHAT is null, the component name is stored on the spelling stack.
-   If the component name is a null string, then LOCAL is omitted entirely.  */
+   MSGID identifies the message.
+   The component name is taken from the spelling stack.  */
 
 void
-pedwarn_init (format, local, ofwhat)
-     char *format, *local, *ofwhat;
+pedwarn_init (msgid)
+     const char *msgid;
 {
-  char *buffer;
-
-  if (ofwhat == 0)
-    ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
-  buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+  char *ofwhat;
 
+  pedwarn ("%s", msgid);
+  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
-    sprintf (buffer, local, ofwhat);
-  else
-    buffer[0] = 0;
-
-  pedwarn (format, buffer);
+    pedwarn ("(near initialization for `%s')", ofwhat);
 }
 
 /* Issue a warning for a bad initializer component.
-   FORMAT describes the message.  OFWHAT is the name for the component.
-   LOCAL is a format string for formatting the insertion of the name
-   into the message.
-
-   If OFWHAT is null, the component name is stored on the spelling stack.
-   If the component name is a null string, then LOCAL is omitted entirely.  */
+   MSGID identifies the message.
+   The component name is taken from the spelling stack.  */
 
 static void
-warning_init (format, local, ofwhat)
-     char *format, *local, *ofwhat;
+warning_init (msgid)
+     const char *msgid;
 {
-  char *buffer;
-
-  if (ofwhat == 0)
-    ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
-  buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+  char *ofwhat;
 
+  warning ("%s", msgid);
+  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
-    sprintf (buffer, local, ofwhat);
-  else
-    buffer[0] = 0;
-
-  warning (format, buffer);
+    warning ("(near initialization for `%s')", ofwhat);
 }
 \f
 /* Digest the parser output INIT as an initializer for type TYPE.
@@ -4834,8 +4525,8 @@ digest_init (type, init, require_constant, constructor_constant)
   enum tree_code code = TREE_CODE (type);
   tree inside_init = init;
 
-  if (init == error_mark_node)
-    return init;
+  if (type == error_mark_node || init == error_mark_node)
+    return error_mark_node;
 
   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
   /* Do not use STRIP_NOPS here.  We do not want an enumerator
@@ -4864,36 +4555,32 @@ digest_init (type, init, require_constant, constructor_constant)
               != char_type_node)
              && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node))
            {
-             error_init ("char-array%s initialized from wide string",
-                         " `%s'", NULL);
+             error_init ("char-array initialized from wide string");
              return error_mark_node;
            }
          if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
               == char_type_node)
              && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node))
            {
-             error_init ("int-array%s initialized from non-wide string",
-                         " `%s'", NULL);
+             error_init ("int-array initialized from non-wide string");
              return error_mark_node;
            }
 
          TREE_TYPE (inside_init) = type;
          if (TYPE_DOMAIN (type) != 0
-             && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
-           {
-             register int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
-             size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+             && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
              /* Subtract 1 (or sizeof (wchar_t))
                 because it's ok to ignore the terminating null char
                 that is counted in the length of the constant.  */
-             if (size < TREE_STRING_LENGTH (inside_init)
-                 - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)
-                    ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT
-                    : 1))
-               pedwarn_init (
-                 "initializer-string for array of chars%s is too long",
-                 " `%s'", NULL);
-           }
+             && 0 > compare_tree_int (TYPE_SIZE_UNIT (type),
+                                      TREE_STRING_LENGTH (inside_init)
+                                      - ((TYPE_PRECISION (typ1)
+                                          != TYPE_PRECISION (char_type_node))
+                                         ? (TYPE_PRECISION (wchar_type_node)
+                                            / BITS_PER_UNIT)
+                                         : 1)))
+           pedwarn_init ("initializer-string for array of chars is too long");
+
          return inside_init;
        }
     }
@@ -4919,8 +4606,7 @@ digest_init (type, init, require_constant, constructor_constant)
       else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
               && TREE_CODE (inside_init) != CONSTRUCTOR)
        {
-         error_init ("array%s initialized from non-constant array expression",
-                     " `%s'", NULL);
+         error_init ("array initialized from non-constant array expression");
          return error_mark_node;
        }
 
@@ -4937,25 +4623,21 @@ digest_init (type, init, require_constant, constructor_constant)
            = valid_compound_expr_initializer (inside_init,
                                               TREE_TYPE (inside_init));
          if (inside_init == error_mark_node)
-           error_init ("initializer element%s is not constant",
-                       " for `%s'", NULL);
+           error_init ("initializer element is not constant");
          else
-           pedwarn_init ("initializer element%s is not constant",
-                         " for `%s'", NULL);
+           pedwarn_init ("initializer element is not constant");
          if (flag_pedantic_errors)
            inside_init = error_mark_node;
        }
       else if (require_constant && ! TREE_CONSTANT (inside_init))
        {
-         error_init ("initializer element%s is not constant",
-                     " for `%s'", NULL);
+         error_init ("initializer element is not constant");
          inside_init = error_mark_node;
        }
       else if (require_constant
               && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
        {
-         error_init ("initializer element%s is not computable at load time",
-                     " for `%s'", NULL);
+         error_init ("initializer element is not computable at load time");
          inside_init = error_mark_node;
        }
 
@@ -4971,20 +4653,18 @@ digest_init (type, init, require_constant, constructor_constant)
         for arrays and functions.  We must not call it in the
         case where inside_init is a null pointer constant.  */
       inside_init
-       = convert_for_assignment (type, init, "initialization",
+       = convert_for_assignment (type, init, _("initialization"),
                                  NULL_TREE, NULL_TREE, 0);
 
       if (require_constant && ! TREE_CONSTANT (inside_init))
        {
-         error_init ("initializer element%s is not constant",
-                     " for `%s'", NULL);
+         error_init ("initializer element is not constant");
          inside_init = error_mark_node;
        }
       else if (require_constant
               && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
        {
-         error_init ("initializer element%s is not computable at load time",
-                     " for `%s'", NULL);
+         error_init ("initializer element is not computable at load time");
          inside_init = error_mark_node;
        }
 
@@ -4993,10 +4673,9 @@ digest_init (type, init, require_constant, constructor_constant)
 
   /* Come here only for records and arrays.  */
 
-  if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+  if (COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
     {
-      error_init ("variable-sized object%s may not be initialized",
-                 " `%s'", NULL);
+      error_init ("variable-sized object may not be initialized");
       return error_mark_node;
     }
 
@@ -5022,7 +4701,7 @@ digest_init (type, init, require_constant, constructor_constant)
            type = TREE_TYPE (TYPE_FIELDS (type));
          else
            {
-             error_init ("invalid initializer%s", " for `%s'", NULL);
+             error_init ("invalid initializer");
              return error_mark_node;
            }
        }
@@ -5038,7 +4717,7 @@ digest_init (type, init, require_constant, constructor_constant)
       else
        return error_mark_node;
     }
-  error_init ("invalid initializer%s", " for `%s'", NULL);
+  error_init ("invalid initializer");
   return error_mark_node;
 }
 \f
@@ -5053,8 +4732,7 @@ static tree constructor_type;
 static tree constructor_fields;
 
 /* For an ARRAY_TYPE, this is the specified index
-   at which to store the next element we get.
-   This is a special INTEGER_CST node that we modify in place.  */
+   at which to store the next element we get.  */
 static tree constructor_index;
 
 /* For an ARRAY_TYPE, this is the end index of the range
@@ -5069,13 +4747,11 @@ static tree constructor_max_index;
 static tree constructor_unfilled_fields;
 
 /* For an ARRAY_TYPE, this is the index of the first element
-   not yet written out.
-   This is a special INTEGER_CST node that we modify in place.  */
+   not yet written out.  */
 static tree constructor_unfilled_index;
 
 /* In a RECORD_TYPE, the byte index of the next consecutive field.
-   This is so we can generate gaps between fields, when appropriate.
-   This is a special INTEGER_CST node that we modify in place.  */
+   This is so we can generate gaps between fields, when appropriate.  */
 static tree constructor_bit_index;
 
 /* If we are saving up the elements rather than allocating them,
@@ -5110,7 +4786,8 @@ struct init_node
 /* Tree of pending elements at this constructor level.
    These are elements encountered out of order
    which belong at places we haven't reached yet in actually
-   writing the output.  */
+   writing the output.
+   Will never hold tree nodes across GC runs.  */
 static struct init_node *constructor_pending_elts;
 
 /* The SPELLING_DEPTH of this constructor.  */
@@ -5201,7 +4878,7 @@ start_init (decl, asmspec_tree, top_level)
      tree asmspec_tree;
      int top_level;
 {
-  char *locus;
+  const char *locus;
   struct initializer_stack *p
     = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack));
   char *asmspec = 0;
@@ -5357,9 +5034,9 @@ really_start_incremental_init (type)
       while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
             && DECL_NAME (constructor_fields) == 0)
        constructor_fields = TREE_CHAIN (constructor_fields);
+
       constructor_unfilled_fields = constructor_fields;
-      constructor_bit_index = copy_node (integer_zero_node);
-      TREE_TYPE (constructor_bit_index) = sbitsizetype;
+      constructor_bit_index = bitsize_zero_node;
     }
   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
     {
@@ -5369,11 +5046,13 @@ really_start_incremental_init (type)
          constructor_max_index
            = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
          constructor_index
-           = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
+           = convert (bitsizetype,
+                      TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
        }
       else
-       constructor_index = copy_node (integer_zero_node);
-      constructor_unfilled_index = copy_node (constructor_index);
+       constructor_index = bitsize_zero_node;
+
+      constructor_unfilled_index = constructor_index;
     }
   else
     {
@@ -5384,19 +5063,10 @@ really_start_incremental_init (type)
 
   if (constructor_incremental)
     {
-      int momentary = suspend_momentary ();
-      push_obstacks_nochange ();
-      if (TREE_PERMANENT (constructor_decl))
-       end_temporary_allocation ();
       make_decl_rtl (constructor_decl, constructor_asmspec,
                     constructor_top_level);
       assemble_variable (constructor_decl, constructor_top_level, 0, 1);
-      pop_obstacks ();
-      resume_momentary (momentary);
-    }
 
-  if (constructor_incremental)
-    {
       defer_addressed_constants ();
       constructor_subconstants_deferred = 1;
     }
@@ -5437,20 +5107,16 @@ push_init_level (implicit)
     {
       /* Advance to offset of this element.  */
       if (! tree_int_cst_equal (constructor_bit_index,
-                               DECL_FIELD_BITPOS (constructor_fields)))
-       {
-         /* By using unsigned arithmetic, the result will be correct even
-            in case of overflows, if BITS_PER_UNIT is a power of two.  */
-         unsigned next = (TREE_INT_CST_LOW
-                          (DECL_FIELD_BITPOS (constructor_fields))
-                          / (unsigned)BITS_PER_UNIT);
-         unsigned here = (TREE_INT_CST_LOW (constructor_bit_index)
-                          / (unsigned)BITS_PER_UNIT);
-
-         assemble_zeros ((next - here)
-                         * (unsigned)BITS_PER_UNIT
-                         / (unsigned)BITS_PER_UNIT);
-       }
+                               bit_position (constructor_fields)))
+       assemble_zeros
+         (tree_low_cst
+          (size_binop (TRUNC_DIV_EXPR,
+                       size_binop (MINUS_EXPR,
+                                   bit_position (constructor_fields),
+                                   constructor_bit_index),
+                       bitsize_unit_node),
+           1));
+
       /* Indicate that we have now filled the structure up to the current
         field.  */
       constructor_unfilled_fields = constructor_fields;
@@ -5506,7 +5172,7 @@ push_init_level (implicit)
   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
     {
       constructor_type = TREE_TYPE (constructor_type);
-      push_array_bounds (TREE_INT_CST_LOW (constructor_index));
+      push_array_bounds (tree_low_cst (constructor_index, 0));
       constructor_depth++;
       if (! tree_int_cst_equal (constructor_index, constructor_unfilled_index)
          || constructor_range_end != 0)
@@ -5515,8 +5181,7 @@ push_init_level (implicit)
 
   if (constructor_type == 0)
     {
-      error_init ("extra brace group at end of initializer%s",
-                 " for `%s'", NULL);
+      error_init ("extra brace group at end of initializer");
       constructor_fields = 0;
       constructor_unfilled_fields = 0;
       return;
@@ -5528,7 +5193,7 @@ push_init_level (implicit)
   if (implicit && warn_missing_braces && !missing_braces_mentioned)
     {
       missing_braces_mentioned = 1;
-      warning_init ("missing braces around initializer%s", " for `%s'", NULL);
+      warning_init ("missing braces around initializer");
     }
 
   if (TREE_CODE (constructor_type) == RECORD_TYPE
@@ -5539,9 +5204,9 @@ push_init_level (implicit)
       while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
             && DECL_NAME (constructor_fields) == 0)
        constructor_fields = TREE_CHAIN (constructor_fields);
+
       constructor_unfilled_fields = constructor_fields;
-      constructor_bit_index = copy_node (integer_zero_node);
-      TREE_TYPE (constructor_bit_index) = sbitsizetype;
+      constructor_bit_index = bitsize_zero_node;
     }
   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
     {
@@ -5551,15 +5216,18 @@ push_init_level (implicit)
          constructor_max_index
            = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
          constructor_index
-           = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
+           = convert (bitsizetype, 
+                                 TYPE_MIN_VALUE
+                                 (TYPE_DOMAIN (constructor_type)));
        }
       else
-       constructor_index = copy_node (integer_zero_node);
-      constructor_unfilled_index = copy_node (constructor_index);
+       constructor_index = bitsize_zero_node;
+
+      constructor_unfilled_index = constructor_index;
     }
   else
     {
-      warning_init ("braces around scalar initializer%s", " for `%s'", NULL);
+      warning_init ("braces around scalar initializer");
       constructor_fields = constructor_type;
       constructor_unfilled_fields = constructor_type;
     }
@@ -5579,9 +5247,7 @@ check_init_type_bitfields (type)
       for (tail = TYPE_FIELDS (type); tail;
           tail = TREE_CHAIN (tail))
        {
-         if (DECL_C_BIT_FIELD (tail)
-             /* This catches cases like `int foo : 8;'.  */
-             || DECL_MODE (tail) != TYPE_MODE (TREE_TYPE (tail)))
+         if (DECL_C_BIT_FIELD (tail))
            {
              constructor_incremental = 0;
              break;
@@ -5591,6 +5257,17 @@ check_init_type_bitfields (type)
        }
     }
 
+  else if (TREE_CODE (type) == UNION_TYPE)
+    {
+      tree tail = TYPE_FIELDS (type);
+      if (tail && DECL_C_BIT_FIELD (tail))
+       /* We also use the nonincremental algorithm for initiliazation
+          of unions whose first member is a bitfield, becuase the
+          incremental algorithm has no code for dealing with
+          bitfields. */
+       constructor_incremental = 0;
+    }
+
   else if (TREE_CODE (type) == ARRAY_TYPE)
     check_init_type_bitfields (TREE_TYPE (type));
 }
@@ -5608,7 +5285,7 @@ pop_init_level (implicit)
      int implicit;
 {
   struct constructor_stack *p;
-  int size = 0;
+  HOST_WIDE_INT size = 0;
   tree constructor = 0;
 
   if (implicit == 0)
@@ -5631,7 +5308,7 @@ pop_init_level (implicit)
       && constructor_unfilled_fields)
     {
       push_member_name (constructor_unfilled_fields);
-      warning_init ("missing initializer%s", " for `%s'", NULL);
+      warning_init ("missing initializer");
       RESTORE_SPELLING_DEPTH (constructor_depth);
     }
 
@@ -5644,7 +5321,7 @@ pop_init_level (implicit)
       && (TREE_CODE (constructor_type) == ARRAY_TYPE
          ? integer_zerop (constructor_unfilled_index)
          : constructor_unfilled_fields == TYPE_FIELDS (constructor_type)))
-    pedwarn_init ("empty braces in initializer%s", " for `%s'", NULL);
+    pedwarn_init ("empty braces in initializer");
 #endif
 
   /* Pad out the end of the structure.  */
@@ -5669,29 +5346,15 @@ pop_init_level (implicit)
          if (TREE_CODE (constructor_type) == ARRAY_TYPE
              && TYPE_DOMAIN (constructor_type) == 0)
            {
-             int failure;
-             int momentary_p;
-
-             push_obstacks_nochange ();
-             if (TREE_PERMANENT (constructor_type))
-               end_temporary_allocation ();
-
-             momentary_p = suspend_momentary ();
-
              /* We shouldn't have an incomplete array type within
                 some other type.  */
              if (constructor_stack->next)
                abort ();
 
-             failure
-               = complete_array_type (constructor_type,
-                                      constructor, 0);
-             if (failure)
+             if (complete_array_type (constructor_type, constructor, 0))
                abort ();
 
              size = int_size_in_bytes (constructor_type);
-             resume_momentary (momentary_p);
-             pop_obstacks ();
            }
 
          output_constant (constructor, size);
@@ -5708,14 +5371,12 @@ pop_init_level (implicit)
         the element, after verifying there is just one.  */
       if (constructor_elements == 0)
        {
-         error_init ("empty scalar initializer%s",
-                     " for `%s'", NULL);
+         error_init ("empty scalar initializer");
          constructor = error_mark_node;
        }
       else if (TREE_CHAIN (constructor_elements) != 0)
        {
-         error_init ("extra elements in scalar initializer%s",
-                     " for `%s'", NULL);
+         error_init ("extra elements in scalar initializer");
          constructor = TREE_VALUE (constructor_elements);
        }
       else
@@ -5727,31 +5388,24 @@ pop_init_level (implicit)
        constructor = error_mark_node;
       else
        {
-         int momentary = suspend_momentary ();
-
          constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE,
                               nreverse (constructor_elements));
          if (constructor_constant)
            TREE_CONSTANT (constructor) = 1;
          if (constructor_constant && constructor_simple)
            TREE_STATIC (constructor) = 1;
-
-         resume_momentary (momentary);
        }
     }
   else
     {
       tree filled;
-      int momentary = suspend_momentary ();
 
       if (TREE_CODE (constructor_type) == RECORD_TYPE
          || TREE_CODE (constructor_type) == UNION_TYPE)
-       {
-         /* Find the offset of the end of that field.  */
-         filled = size_binop (CEIL_DIV_EXPR,
-                              constructor_bit_index,
-                              size_int (BITS_PER_UNIT));
-       }
+       /* Find the offset of the end of that field.  */
+       filled = size_binop (CEIL_DIV_EXPR, constructor_bit_index,
+                            bitsize_unit_node);
+
       else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
        {
          /* If initializing an array of unknown size,
@@ -5760,14 +5414,9 @@ pop_init_level (implicit)
              && TYPE_DOMAIN (constructor_type) == 0)
            {
              tree maxindex
-               = size_binop (MINUS_EXPR,
-                             constructor_unfilled_index,
-                             integer_one_node);
-
-             push_obstacks_nochange ();
-             if (TREE_PERMANENT (constructor_type))
-               end_temporary_allocation ();
-             maxindex = copy_node (maxindex);
+               = copy_node (size_diffop (constructor_unfilled_index,
+                                         bitsize_one_node));
+
              TYPE_DOMAIN (constructor_type) = build_index_type (maxindex);
              TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type);
 
@@ -5775,25 +5424,27 @@ pop_init_level (implicit)
                 in the array, because we start counting at zero.  Therefore,
                 warn only if the value is less than zero.  */
              if (pedantic
-                 && (tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
+                 && (tree_int_cst_sgn
+                     (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
                      < 0))
                error_with_decl (constructor_decl,
                                 "zero or negative array size `%s'");
+
              layout_type (constructor_type);
              size = int_size_in_bytes (constructor_type);
-             pop_obstacks ();
            }
 
-         filled = size_binop (MULT_EXPR, constructor_unfilled_index,
-                              size_in_bytes (TREE_TYPE (constructor_type)));
+         filled
+           = size_binop (MULT_EXPR, constructor_unfilled_index,
+                         convert (bitsizetype,
+                                  TYPE_SIZE_UNIT
+                                  (TREE_TYPE (constructor_type))));
        }
       else
        filled = 0;
 
       if (filled != 0)
-       assemble_zeros (size - TREE_INT_CST_LOW (filled));
-
-      resume_momentary (momentary);
+       assemble_zeros (size - tree_low_cst (filled, 1));
     }
 
          
@@ -5839,35 +5490,36 @@ set_init_index (first, last)
          || TREE_CODE (first) == NON_LVALUE_EXPR)
         && (TYPE_MODE (TREE_TYPE (first))
             == TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0)))))
-    (first) = TREE_OPERAND (first, 0);
+    first = TREE_OPERAND (first, 0);
+
   if (last)
     while ((TREE_CODE (last) == NOP_EXPR
            || TREE_CODE (last) == CONVERT_EXPR
            || TREE_CODE (last) == NON_LVALUE_EXPR)
           && (TYPE_MODE (TREE_TYPE (last))
               == TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0)))))
-      (last) = TREE_OPERAND (last, 0);
+      last = TREE_OPERAND (last, 0);
 
   if (TREE_CODE (first) != INTEGER_CST)
-    error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+    error_init ("nonconstant array index in initializer");
   else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
-    error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+    error_init ("nonconstant array index in initializer");
   else if (! constructor_unfilled_index)
-    error_init ("array index in non-array initializer%s", " for `%s'", NULL);
+    error_init ("array index in non-array initializer");
   else if (tree_int_cst_lt (first, constructor_unfilled_index))
-    error_init ("duplicate array index in initializer%s", " for `%s'", NULL);
+    error_init ("duplicate array index in initializer");
   else
     {
-      TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (first);
-      TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (first);
+      constructor_index = convert (bitsizetype, first);
 
       if (last != 0 && tree_int_cst_lt (last, first))
-       error_init ("empty index range in initializer%s", " for `%s'", NULL);
+       error_init ("empty index range in initializer");
       else
        {
          if (pedantic)
            pedwarn ("ANSI C forbids specifying element to initialize");
-         constructor_range_end = last;
+
+         constructor_range_end = last ? convert (bitsizetype, last) : 0;
        }
     }
 }
@@ -5929,7 +5581,7 @@ add_pending_init (purpose, value)
          p = *q;
          if (tree_int_cst_lt (purpose, p->purpose))
            q = &p->left;
-         else if (tree_int_cst_lt (p->purpose, purpose))
+         else if (p->purpose != purpose)
            q = &p->right;
          else
            abort ();
@@ -5940,18 +5592,17 @@ add_pending_init (purpose, value)
       while (*q != NULL)
        {
          p = *q;
-         if (tree_int_cst_lt (DECL_FIELD_BITPOS (purpose),
-                              DECL_FIELD_BITPOS (p->purpose)))
+         if (tree_int_cst_lt (bit_position (purpose),
+                              bit_position (p->purpose)))
            q = &p->left;
-         else if (tree_int_cst_lt (DECL_FIELD_BITPOS (p->purpose),
-                                   DECL_FIELD_BITPOS (purpose)))
+         else if (p->purpose != purpose)
            q = &p->right;
          else
            abort ();
        }
     }
 
-  r = (struct init_node *) oballoc (sizeof (struct init_node));
+  r = (struct init_node *) ggc_alloc_obj (sizeof (struct init_node), 0);
   r->purpose = purpose;
   r->value = value;
 
@@ -6129,7 +5780,7 @@ pending_init_member (field)
     {
       while (p)
        {
-         if (tree_int_cst_equal (field, p->purpose))
+         if (field == p->purpose)
            return 1;
          else if (tree_int_cst_lt (field, p->purpose))
            p = p->left;
@@ -6143,8 +5794,8 @@ pending_init_member (field)
        {
          if (field == p->purpose)
            return 1;
-         else if (tree_int_cst_lt (DECL_FIELD_BITPOS (field),
-                                   DECL_FIELD_BITPOS (p->purpose)))
+         else if (tree_int_cst_lt (bit_position (field),
+                                   bit_position (p->purpose)))
            p = p->left;
          else
            p = p->right;
@@ -6193,15 +5844,13 @@ output_init_element (value, type, field, pending)
 
   if (require_constant_value && ! TREE_CONSTANT (value))
     {
-      error_init ("initializer element%s is not constant",
-                 " for `%s'", NULL);
+      error_init ("initializer element is not constant");
       value = error_mark_node;
     }
   else if (require_constant_elements
           && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
     {
-      error_init ("initializer element%s is not computable at load time",
-                 " for `%s'", NULL);
+      error_init ("initializer element is not computable at load time");
       value = error_mark_node;
     }
 
@@ -6217,7 +5866,7 @@ output_init_element (value, type, field, pending)
        {
          if (pending_init_member (field))
            {
-             error_init ("duplicate initializer%s", " for `%s'", NULL);
+             error_init ("duplicate initializer");
              duplicate = 1;
            }
        }
@@ -6226,12 +5875,10 @@ output_init_element (value, type, field, pending)
   /* If this element doesn't come next in sequence,
      put it on constructor_pending_elts.  */
   if (TREE_CODE (constructor_type) == ARRAY_TYPE
-      && !tree_int_cst_equal (field, constructor_unfilled_index))
+      && ! tree_int_cst_equal (field, constructor_unfilled_index))
     {
       if (! duplicate)
-       /* The copy_node is needed in case field is actually
-          constructor_index, which is modified in place.  */
-       add_pending_init (copy_node (field),
+       add_pending_init (field,
                          digest_init (type, value, require_constant_value, 
                                       require_constant_elements));
     }
@@ -6267,27 +5914,18 @@ output_init_element (value, type, field, pending)
            {
              /* Structure elements may require alignment.
                 Do this, if necessary.  */
-             if (TREE_CODE (constructor_type) == RECORD_TYPE)
-               {
-                 /* Advance to offset of this element.  */
-                 if (! tree_int_cst_equal (constructor_bit_index,
-                                           DECL_FIELD_BITPOS (field)))
-                   {
-                     /* By using unsigned arithmetic, the result will be
-                        correct even in case of overflows, if BITS_PER_UNIT
-                        is a power of two.  */
-                     unsigned next = (TREE_INT_CST_LOW
-                                      (DECL_FIELD_BITPOS (field))
-                                      / (unsigned)BITS_PER_UNIT);
-                     unsigned here = (TREE_INT_CST_LOW
-                                      (constructor_bit_index)
-                                      / (unsigned)BITS_PER_UNIT);
-
-                     assemble_zeros ((next - here)
-                                     * (unsigned)BITS_PER_UNIT
-                                     / (unsigned)BITS_PER_UNIT);
-                   }
-               }
+             if (TREE_CODE (constructor_type) == RECORD_TYPE
+                 && ! tree_int_cst_equal (constructor_bit_index,
+                                          bit_position (field)))
+               /* Advance to offset of this element.  */
+               assemble_zeros
+                 (tree_low_cst
+                  (size_binop (TRUNC_DIV_EXPR,
+                               size_binop (MINUS_EXPR, bit_position (field),
+                                           constructor_bit_index),
+                               bitsize_unit_node),
+                   0));
+
              output_constant (digest_init (type, value,
                                            require_constant_value,
                                            require_constant_elements),
@@ -6297,29 +5935,29 @@ output_init_element (value, type, field, pending)
                 keep track of end position of last field.  */
              if (TREE_CODE (constructor_type) == RECORD_TYPE
                  || TREE_CODE (constructor_type) == UNION_TYPE)
-               {
-                 tree temp = size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (field),
-                                         DECL_SIZE (field));
-                 TREE_INT_CST_LOW (constructor_bit_index)
-                   = TREE_INT_CST_LOW (temp);
-                 TREE_INT_CST_HIGH (constructor_bit_index)
-                   = TREE_INT_CST_HIGH (temp);
-               }
+               constructor_bit_index
+                 = size_binop (PLUS_EXPR, bit_position (field),
+                               DECL_SIZE (field));
            }
        }
 
       /* Advance the variable that indicates sequential elements output.  */
       if (TREE_CODE (constructor_type) == ARRAY_TYPE)
+       constructor_unfilled_index
+         = size_binop (PLUS_EXPR, constructor_unfilled_index,
+                       bitsize_one_node);
+      else if (TREE_CODE (constructor_type) == RECORD_TYPE)
        {
-         tree tem = size_binop (PLUS_EXPR, constructor_unfilled_index,
-                                integer_one_node);
-         TREE_INT_CST_LOW (constructor_unfilled_index)
-           = TREE_INT_CST_LOW (tem);
-         TREE_INT_CST_HIGH (constructor_unfilled_index)
-           = TREE_INT_CST_HIGH (tem);
+         constructor_unfilled_fields
+           = TREE_CHAIN (constructor_unfilled_fields);
+
+         /* Skip any nameless bit fields.  */
+         while (constructor_unfilled_fields != 0
+                && DECL_C_BIT_FIELD (constructor_unfilled_fields)
+                && DECL_NAME (constructor_unfilled_fields) == 0)
+           constructor_unfilled_fields =
+             TREE_CHAIN (constructor_unfilled_fields);
        }
-      else if (TREE_CODE (constructor_type) == RECORD_TYPE)
-       constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
       else if (TREE_CODE (constructor_type) == UNION_TYPE)
        constructor_unfilled_fields = 0;
 
@@ -6412,8 +6050,8 @@ output_pending_init_elements (all)
                                   constructor_unfilled_fields,
                                   0);
            }
-         else if (tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields),
-                                   DECL_FIELD_BITPOS (elt->purpose)))
+         else if (tree_int_cst_lt (bit_position (constructor_unfilled_fields),
+                                   bit_position (elt->purpose)))
            {
              /* Advance to the next smaller node.  */
              if (elt->left)
@@ -6439,8 +6077,9 @@ output_pending_init_elements (all)
                    elt = elt->parent;
                  elt = elt->parent;
                  if (elt
-                     && tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields),
-                                         DECL_FIELD_BITPOS (elt->purpose)))
+                     && (tree_int_cst_lt
+                         (bit_position (constructor_unfilled_fields),
+                          bit_position (elt->purpose))))
                    {
                      next = elt->purpose;
                      break;
@@ -6459,12 +6098,13 @@ output_pending_init_elements (all)
   if (constructor_incremental)
     {
       tree filled;
-      tree nextpos_tree = size_int (0);
+      tree nextpos_tree = bitsize_zero_node;
 
       if (TREE_CODE (constructor_type) == RECORD_TYPE
          || TREE_CODE (constructor_type) == UNION_TYPE)
        {
          tree tail;
+
          /* Find the last field written out, if any.  */
          for (tail = TYPE_FIELDS (constructor_type); tail;
               tail = TREE_CHAIN (tail))
@@ -6474,44 +6114,34 @@ output_pending_init_elements (all)
          if (tail)
            /* Find the offset of the end of that field.  */
            filled = size_binop (CEIL_DIV_EXPR,
-                                size_binop (PLUS_EXPR,
-                                            DECL_FIELD_BITPOS (tail),
+                                size_binop (PLUS_EXPR, bit_position (tail),
                                             DECL_SIZE (tail)),
-                                size_int (BITS_PER_UNIT));
+                                bitsize_unit_node);
          else
-           filled = size_int (0);
-
-         nextpos_tree = size_binop (CEIL_DIV_EXPR,
-                                    DECL_FIELD_BITPOS (next),
-                                    size_int (BITS_PER_UNIT));
+           filled = bitsize_zero_node;
 
-         TREE_INT_CST_HIGH (constructor_bit_index)
-           = TREE_INT_CST_HIGH (DECL_FIELD_BITPOS (next));
-         TREE_INT_CST_LOW (constructor_bit_index)
-           = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (next));
+         nextpos_tree = convert (bitsizetype, byte_position (next));
+         constructor_bit_index = bit_position (next);
          constructor_unfilled_fields = next;
        }
       else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
        {
-         filled = size_binop (MULT_EXPR, constructor_unfilled_index,
-                              size_in_bytes (TREE_TYPE (constructor_type)));
+         filled
+           = size_binop (MULT_EXPR, constructor_unfilled_index,
+                         convert (bitsizetype,
+                                  TYPE_SIZE_UNIT
+                                  (TREE_TYPE (constructor_type))));
          nextpos_tree
            = size_binop (MULT_EXPR, next,
-                         size_in_bytes (TREE_TYPE (constructor_type)));
-         TREE_INT_CST_LOW (constructor_unfilled_index)
-           = TREE_INT_CST_LOW (next);
-         TREE_INT_CST_HIGH (constructor_unfilled_index)
-           = TREE_INT_CST_HIGH (next);
+                         convert (bitsizetype, TYPE_SIZE_UNIT
+                                  (TREE_TYPE (constructor_type))));
+         constructor_unfilled_index = next;
        }
       else
        filled = 0;
 
       if (filled)
-       {
-         int nextpos = TREE_INT_CST_LOW (nextpos_tree);
-
-         assemble_zeros (nextpos - TREE_INT_CST_LOW (filled));
-       }
+       assemble_zeros (tree_low_cst (size_diffop (nextpos_tree, filled), 1));
     }
   else
     {
@@ -6522,12 +6152,7 @@ output_pending_init_elements (all)
          || TREE_CODE (constructor_type) == UNION_TYPE)
        constructor_unfilled_fields = next;
       else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
-       {
-         TREE_INT_CST_LOW (constructor_unfilled_index)
-           = TREE_INT_CST_LOW (next);
-         TREE_INT_CST_HIGH (constructor_unfilled_index)
-           = TREE_INT_CST_HIGH (next);
-       }
+       constructor_unfilled_index = next;
     }
 
   /* ELT now points to the node in the pending tree with the next
@@ -6564,14 +6189,15 @@ process_init_element (value)
       && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE
       && integer_zerop (constructor_unfilled_index))
     {
+      if (constructor_stack->replacement_value)
+        error_init ("excess elements in char array initializer");
       constructor_stack->replacement_value = value;
       return;
     }
 
   if (constructor_stack->replacement_value != 0)
     {
-      error_init ("excess elements in struct initializer%s",
-                 " after `%s'", NULL_PTR);
+      error_init ("excess elements in struct initializer");
       return;
     }
 
@@ -6606,8 +6232,7 @@ process_init_element (value)
 
          if (constructor_fields == 0)
            {
-             pedwarn_init ("excess elements in struct initializer%s",
-                           " after `%s'", NULL_PTR);
+             pedwarn_init ("excess elements in struct initializer");
              break;
            }
 
@@ -6645,15 +6270,18 @@ process_init_element (value)
               directly output as a constructor.  */
            {
              /* For a record, keep track of end position of last field.  */
-             tree temp = size_binop (PLUS_EXPR,
-                                     DECL_FIELD_BITPOS (constructor_fields),
-                                     DECL_SIZE (constructor_fields));
-             TREE_INT_CST_LOW (constructor_bit_index)
-               = TREE_INT_CST_LOW (temp);
-             TREE_INT_CST_HIGH (constructor_bit_index)
-               = TREE_INT_CST_HIGH (temp);
+             constructor_bit_index
+               = size_binop (PLUS_EXPR,
+                             bit_position (constructor_fields),
+                             DECL_SIZE (constructor_fields));
 
              constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
+             /* Skip any nameless bit fields.  */
+             while (constructor_unfilled_fields != 0
+                    && DECL_C_BIT_FIELD (constructor_unfilled_fields)
+                    && DECL_NAME (constructor_unfilled_fields) == 0)
+               constructor_unfilled_fields =
+                 TREE_CHAIN (constructor_unfilled_fields);
            }
 
          constructor_fields = TREE_CHAIN (constructor_fields);
@@ -6671,8 +6299,7 @@ process_init_element (value)
 
          if (constructor_fields == 0)
            {
-             pedwarn_init ("excess elements in union initializer%s",
-                           " after `%s'", NULL_PTR);
+             pedwarn_init ("excess elements in union initializer");
              break;
            }
 
@@ -6709,11 +6336,7 @@ process_init_element (value)
            /* Do the bookkeeping for an element that was
               directly output as a constructor.  */
            {
-             TREE_INT_CST_LOW (constructor_bit_index)
-               = TREE_INT_CST_LOW (DECL_SIZE (constructor_fields));
-             TREE_INT_CST_HIGH (constructor_bit_index)
-               = TREE_INT_CST_HIGH (DECL_SIZE (constructor_fields));
-
+             constructor_bit_index = DECL_SIZE (constructor_fields);
              constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
            }
 
@@ -6746,8 +6369,7 @@ process_init_element (value)
          if (constructor_max_index != 0
              && tree_int_cst_lt (constructor_max_index, constructor_index))
            {
-             pedwarn_init ("excess elements in array initializer%s",
-                           " after `%s'", NULL_PTR);
+             pedwarn_init ("excess elements in array initializer");
              break;
            }
 
@@ -6758,12 +6380,8 @@ process_init_element (value)
                  && tree_int_cst_lt (constructor_max_index, 
                                      constructor_range_end))
                {
-                 pedwarn_init ("excess elements in array initializer%s",
-                               " after `%s'", NULL_PTR);
-                 TREE_INT_CST_HIGH (constructor_range_end)
-                   = TREE_INT_CST_HIGH (constructor_max_index);
-                 TREE_INT_CST_LOW (constructor_range_end)
-                   = TREE_INT_CST_LOW (constructor_max_index);
+                 pedwarn_init ("excess elements in array initializer");
+                 constructor_range_end = constructor_max_index;
                }
 
              value = save_expr (value);
@@ -6774,30 +6392,21 @@ process_init_element (value)
             If there is a range, repeat it till we advance past the range.  */
          do
            {
-             tree tem;
-
              if (value)
                {
-                 push_array_bounds (TREE_INT_CST_LOW (constructor_index));
+                 push_array_bounds (tree_low_cst (constructor_index, 0));
                  output_init_element (value, elttype, constructor_index, 1);
                  RESTORE_SPELLING_DEPTH (constructor_depth);
                }
 
-             tem = size_binop (PLUS_EXPR, constructor_index,
-                               integer_one_node);
-             TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (tem);
-             TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (tem);
+             constructor_index
+               = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
 
-             if (!value)
+             if (! value)
                /* If we are doing the bookkeeping for an element that was
-                  directly output as a constructor,
-                  we must update constructor_unfilled_index.  */
-               {
-                 TREE_INT_CST_LOW (constructor_unfilled_index)
-                   = TREE_INT_CST_LOW (constructor_index);
-                 TREE_INT_CST_HIGH (constructor_unfilled_index)
-                   = TREE_INT_CST_HIGH (constructor_index);
-               }
+                  directly output as a constructor, we must update
+                  constructor_unfilled_index.  */
+               constructor_unfilled_index = constructor_index;
            }
          while (! (constructor_range_end == 0
                    || tree_int_cst_lt (constructor_range_end,
@@ -6810,8 +6419,7 @@ process_init_element (value)
         for a scalar variable.  */
       if (constructor_fields == 0)
        {
-         pedwarn_init ("excess elements in scalar initializer%s",
-                       " after `%s'", NULL_PTR);
+         pedwarn_init ("excess elements in scalar initializer");
          break;
        }
 
@@ -6820,12 +6428,6 @@ process_init_element (value)
       constructor_fields = 0;
       break;
     }
-
-  /* If the (lexically) previous elments are not now saved,
-     we can discard the storage for them.  */
-  if (constructor_incremental && constructor_pending_elts == 0 && value != 0
-      && constructor_stack == 0)
-    clear_momentary ();
 }
 \f
 /* Expand an ASM statement with operands, handling output operands
@@ -6857,7 +6459,26 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
 
   /* Record the contents of OUTPUTS before it is modified.  */
   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
-    o[i] = TREE_VALUE (tail);
+    {
+      tree output = TREE_VALUE (tail);
+
+      /* We can remove conversions that just change the type, not the mode.  */
+      STRIP_NOPS (output);
+      o[i] = output;
+
+      /* Allow conversions as LHS here.  build_modify_expr as called below
+        will do the right thing with them.  */
+      while (TREE_CODE (output) == NOP_EXPR
+            || TREE_CODE (output) == CONVERT_EXPR
+            || TREE_CODE (output) == FLOAT_EXPR
+            || TREE_CODE (output) == FIX_TRUNC_EXPR
+            || TREE_CODE (output) == FIX_FLOOR_EXPR
+            || TREE_CODE (output) == FIX_ROUND_EXPR
+            || TREE_CODE (output) == FIX_CEIL_EXPR)
+       output = TREE_OPERAND (output, 0);
+
+      lvalue_or_else (o[i], "invalid lvalue in asm statement");
+    }
 
   /* Perform default conversions on array and function inputs.  */
   /* Don't do this for other types--
@@ -6928,7 +6549,7 @@ c_expand_return (retval)
     }
   else
     {
-      tree t = convert_for_assignment (valtype, retval, "return",
+      tree t = convert_for_assignment (valtype, retval, _("return"),
                                       NULL_TREE, NULL_TREE, 0);
       tree res = DECL_RESULT (current_function_decl);
       tree inner;
@@ -7003,8 +6624,14 @@ tree
 c_expand_start_case (exp)
      tree exp;
 {
-  register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
-  tree type = TREE_TYPE (exp);
+  register enum tree_code code;
+  tree type;
+
+  if (TREE_CODE (exp) == ERROR_MARK)
+    return exp;
+
+  code = TREE_CODE (TREE_TYPE (exp));
+  type = TREE_TYPE (exp);
 
   if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK)
     {
@@ -7017,6 +6644,7 @@ c_expand_start_case (exp)
       type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
 
       if (warn_traditional
+         && ! in_system_header
          && (type == long_integer_type_node
              || type == long_unsigned_type_node))
        pedwarn ("`long' switch expression not converted to `int' in ANSI C");