OSDN Git Service

* c-cppbuiltin.c (builtin_define_with_value_n): Fix whitespace.
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index 297b0f9..0d52a7c 100644 (file)
@@ -31,6 +31,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "rtl.h"
 #include "tree.h"
 #include "c-tree.h"
@@ -51,7 +53,7 @@ static int missing_braces_mentioned;
 static int undeclared_variable_notice;
 
 static tree qualify_type               PARAMS ((tree, tree));
-static int comp_target_types           PARAMS ((tree, tree));
+static int comp_target_types           PARAMS ((tree, tree, int));
 static int function_types_compatible_p PARAMS ((tree, tree));
 static int type_lists_compatible_p     PARAMS ((tree, tree));
 static tree decl_constant_value_for_broken_optimization PARAMS ((tree));
@@ -99,7 +101,7 @@ require_complete_type (value)
   if (COMPLETE_TYPE_P (type))
     return value;
 
-  incomplete_type_error (value, type);
+  c_incomplete_type_error (value, type);
   return error_mark_node;
 }
 
@@ -108,7 +110,7 @@ require_complete_type (value)
    and TYPE is the type that was invalid.  */
 
 void
-incomplete_type_error (value, type)
+c_incomplete_type_error (value, type)
      tree value;
      tree type;
 {
@@ -173,6 +175,28 @@ incomplete_type_error (value, type)
     }
 }
 
+/* Given a type, apply default promotions wrt unnamed function
+   arguments and return the new type.  */
+
+tree
+c_type_promotes_to (type)
+     tree type;
+{
+  if (TYPE_MAIN_VARIANT (type) == float_type_node)
+    return double_type_node;
+
+  if (c_promoting_integer_type_p (type))
+    {
+      /* Preserve unsignedness if not really getting any wider.  */
+      if (TREE_UNSIGNED (type)
+          && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
+        return unsigned_type_node;
+      return integer_type_node;
+    }
+
+  return type;
+}
+
 /* Return a variant of TYPE which has all the type qualifiers of LIKE
    as well as those of TYPE.  */
 
@@ -216,9 +240,9 @@ common_type (t1, t2)
   /* Treat an enum type as the unsigned integer type of the same width.  */
 
   if (TREE_CODE (t1) == ENUMERAL_TYPE)
-    t1 = type_for_size (TYPE_PRECISION (t1), 1);
+    t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
   if (TREE_CODE (t2) == ENUMERAL_TYPE)
-    t2 = type_for_size (TYPE_PRECISION (t2), 1);
+    t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
 
   code1 = TREE_CODE (t1);
   code2 = TREE_CODE (t2);
@@ -465,9 +489,9 @@ comptypes (type1, type2)
      signedness.  */
 
   if (TREE_CODE (t1) == ENUMERAL_TYPE)
-    t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
+    t1 = c_common_type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
   if (TREE_CODE (t2) == ENUMERAL_TYPE)
-    t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
+    t2 = c_common_type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
 
   if (t1 == t2)
     return 1;
@@ -546,10 +570,16 @@ comptypes (type1, type2)
       }
 
     case RECORD_TYPE:
-      if (maybe_objc_comptypes (t1, t2, 0) == 1)
+      if (flag_objc && objc_comptypes (t1, t2, 0) == 1)
        val = 1;
       break;
 
+    case VECTOR_TYPE:
+      /* The target might allow certain vector types to be compatible.  */
+      val = (*targetm.vector_opaque_p) (t1)
+       || (*targetm.vector_opaque_p) (t2);
+      break;
+
     default:
       break;
     }
@@ -557,16 +587,21 @@ comptypes (type1, type2)
 }
 
 /* Return 1 if TTL and TTR are pointers to types that are equivalent,
-   ignoring their qualifiers.  */
+   ignoring their qualifiers.  REFLEXIVE is only used by ObjC - set it
+   to 1 or 0 depending if the check of the pointer types is meant to
+   be reflexive or not (typically, assignments are not reflexive,
+   while comparisons are reflexive).
+*/
 
 static int
-comp_target_types (ttl, ttr)
+comp_target_types (ttl, ttr, reflexive)
      tree ttl, ttr;
+     int reflexive;
 {
   int val;
 
-  /* Give maybe_objc_comptypes a crack at letting these types through.  */
-  if ((val = maybe_objc_comptypes (ttl, ttr, 1)) >= 0)
+  /* Give objc_comptypes a crack at letting these types through.  */
+  if ((val = objc_comptypes (ttl, ttr, reflexive)) >= 0)
     return val;
 
   val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
@@ -658,12 +693,12 @@ type_lists_compatible_p (args1, args2)
         So match anything that self-promotes.  */
       if (TREE_VALUE (args1) == 0)
        {
-         if (simple_type_promotes_to (TREE_VALUE (args2)) != NULL_TREE)
+         if (c_type_promotes_to (TREE_VALUE (args2)) != TREE_VALUE (args2))
            return 0;
        }
       else if (TREE_VALUE (args2) == 0)
        {
-         if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE)
+         if (c_type_promotes_to (TREE_VALUE (args1)) != TREE_VALUE (args1))
            return 0;
        }
       else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)), 
@@ -714,71 +749,6 @@ type_lists_compatible_p (args1, args2)
     }
 }
 \f
-/* Compute the value of the `sizeof' operator.  */
-
-tree
-c_sizeof (type)
-     tree type;
-{
-  enum tree_code code = TREE_CODE (type);
-  tree size;
-
-  if (code == FUNCTION_TYPE)
-    {
-      if (pedantic || warn_pointer_arith)
-       pedwarn ("sizeof applied to a function type");
-      size = size_one_node;
-    }
-  else if (code == VOID_TYPE)
-    {
-      if (pedantic || warn_pointer_arith)
-       pedwarn ("sizeof applied to a void type");
-      size = size_one_node;
-    }
-  else if (code == ERROR_MARK)
-    size = size_one_node;
-  else if (!COMPLETE_TYPE_P (type))
-    {
-      error ("sizeof applied to an incomplete type");
-      size = size_zero_node;
-    }
-  else
-    /* Convert in case a char is more than one unit.  */
-    size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
-                      size_int (TYPE_PRECISION (char_type_node)
-                                / BITS_PER_UNIT));
-
-  /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
-     TYPE_IS_SIZETYPE means that certain things (like overflow) will
-     never happen.  However, this node should really have type
-     `size_t', which is just a typedef for an ordinary integer type.  */
-  return fold (build1 (NOP_EXPR, c_size_type_node, size));
-}
-
-tree
-c_sizeof_nowarn (type)
-     tree type;
-{
-  enum tree_code code = TREE_CODE (type);
-  tree size;
-
-  if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
-    size = size_one_node;
-  else if (!COMPLETE_TYPE_P (type))
-    size = size_zero_node;
-  else
-    /* Convert in case a char is more than one unit.  */
-    size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
-                      size_int (TYPE_PRECISION (char_type_node)
-                                / BITS_PER_UNIT));
-
-  /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
-     TYPE_IS_SIZETYPE means that certain things (like overflow) will
-     never happen.  However, this node should really have type
-     `size_t', which is just a typedef for an ordinary integer type.  */
-  return fold (build1 (NOP_EXPR, c_size_type_node, size));
-}
-
 /* Compute the size to increment a pointer by.  */
 
 tree
@@ -932,7 +902,7 @@ default_function_array_conversion (exp)
             is not the target type of the type of the ADDR_EXPR itself.
             Question is, can this lossage be avoided?  */
          adr = build1 (ADDR_EXPR, ptrtype, exp);
-         if (mark_addressable (exp) == 0)
+         if (!c_mark_addressable (exp))
            return error_mark_node;
          TREE_CONSTANT (adr) = staticp (exp);
          TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
@@ -994,11 +964,11 @@ default_conversion (exp)
      but convert wide enums to something wider.  */
   if (code == ENUMERAL_TYPE)
     {
-      type = type_for_size (MAX (TYPE_PRECISION (type),
-                                TYPE_PRECISION (integer_type_node)),
-                           ((TYPE_PRECISION (type)
-                             >= TYPE_PRECISION (integer_type_node))
-                            && TREE_UNSIGNED (type)));
+      type = c_common_type_for_size (MAX (TYPE_PRECISION (type),
+                                         TYPE_PRECISION (integer_type_node)),
+                                    ((TYPE_PRECISION (type)
+                                      >= TYPE_PRECISION (integer_type_node))
+                                     && TREE_UNSIGNED (type)));
 
       return convert (type, exp);
     }
@@ -1163,7 +1133,7 @@ build_component_ref (datum, component)
     {
       if (!COMPLETE_TYPE_P (type))
        {
-         incomplete_type_error (NULL_TREE, type);
+         c_incomplete_type_error (NULL_TREE, type);
          return error_mark_node;
        }
 
@@ -1225,7 +1195,6 @@ build_indirect_ref (ptr, errorstring)
   if (TREE_CODE (type) == POINTER_TYPE)
     {
       if (TREE_CODE (pointer) == ADDR_EXPR
-         && !flag_volatile
          && (TREE_TYPE (TREE_OPERAND (pointer, 0))
              == TREE_TYPE (type)))
        return TREE_OPERAND (pointer, 0);
@@ -1251,7 +1220,7 @@ build_indirect_ref (ptr, errorstring)
             to change it via some other pointer.  */
          TREE_READONLY (ref) = TYPE_READONLY (t);
          TREE_SIDE_EFFECTS (ref)
-           = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile;
+           = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
          TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
          return ref;
        }
@@ -1317,7 +1286,7 @@ build_array_ref (array, index)
          || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
              && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
        {
-         if (mark_addressable (array) == 0)
+         if (!c_mark_addressable (array))
            return error_mark_node;
        }
       /* An array that is indexed by a constant value which is not within
@@ -1328,7 +1297,7 @@ build_array_ref (array, index)
          && TYPE_VALUES (TREE_TYPE (array))
          && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array))))
        {
-         if (mark_addressable (array) == 0)
+         if (!c_mark_addressable (array))
            return error_mark_node;
        }
 
@@ -1340,7 +1309,7 @@ build_array_ref (array, index)
          if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
            pedwarn ("ISO C forbids subscripting `register' array");
          else if (! flag_isoc99 && ! lvalue_p (foo))
-           pedwarn ("ISO C89 forbids subscripting non-lvalue array");
+           pedwarn ("ISO C90 forbids subscripting non-lvalue array");
        }
 
       type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
@@ -1484,7 +1453,8 @@ build_external_ref (id, fun)
   if (TREE_TYPE (ref) == error_mark_node)
     return error_mark_node;
 
-  assemble_external (ref);
+  if (!skip_evaluation)
+    assemble_external (ref);
   TREE_USED (ref) = 1;
 
   if (TREE_CODE (ref) == CONST_DECL)
@@ -1507,7 +1477,7 @@ build_function_call (function, params)
 {
   tree fntype, fundecl = 0;
   tree coerced_params;
-  tree name = NULL_TREE, assembler_name = NULL_TREE, result;
+  tree name = NULL_TREE, result;
 
   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
   STRIP_TYPE_NOPS (function);
@@ -1516,7 +1486,6 @@ build_function_call (function, params)
   if (TREE_CODE (function) == FUNCTION_DECL)
     {
       name = DECL_NAME (function);
-      assembler_name = DECL_ASSEMBLER_NAME (function);
 
       /* Differs from default_conversion by not setting TREE_ADDRESSABLE
         (because calling an inline function does not mean the function
@@ -1554,10 +1523,9 @@ build_function_call (function, params)
   coerced_params
     = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl);
 
-  /* Check for errors in format strings.  */
+  /* Check that the arguments to the function are valid.  */
 
-  if (warn_format)
-    check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params);
+  check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params);
 
   /* Recognize certain built-in functions so we can make tree-codes
      other than CALL_EXPR.  We do this when it enables fold-const.c
@@ -2001,7 +1969,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
       /* Subtraction of two similar pointers.
         We must subtract them as integers, then divide by object size.  */
       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
-         && comp_target_types (type0, type1))
+         && comp_target_types (type0, type1, 1))
        return pointer_diff (op0, op1);
       /* Handle pointer minus int.  Just like pointer plus int.  */
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
@@ -2025,9 +1993,9 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
        warning ("division by zero");
 
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
-          || code0 == COMPLEX_TYPE)
+          || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
-             || code1 == COMPLEX_TYPE))
+             || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
        {
          if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
            resultcode = RDIV_EXPR;
@@ -2050,6 +2018,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
     case BIT_XOR_EXPR:
       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
        shorten = -1;
+      else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+       common = 1;
       break;
 
     case TRUNC_MOD_EXPR:
@@ -2084,8 +2054,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
             but that does not mean the operands should be
             converted to ints!  */
          result_type = integer_type_node;
-         op0 = truthvalue_conversion (op0);
-         op1 = truthvalue_conversion (op1);
+         op0 = c_common_truthvalue_conversion (op0);
+         op1 = c_common_truthvalue_conversion (op1);
          converted = 1;
        }
       break;
@@ -2176,9 +2146,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
         but don't convert the args to int!  */
       build_type = integer_type_node;
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
-          || code0 == COMPLEX_TYPE)
+          || code0 == COMPLEX_TYPE
+          || code0 == VECTOR_TYPE)
          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
-             || code1 == COMPLEX_TYPE))
+             || code1 == COMPLEX_TYPE
+             || code1 == VECTOR_TYPE))
        short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        {
@@ -2187,7 +2159,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
          /* Anything compares with void *.  void * compares with anything.
             Otherwise, the targets must be compatible
             and both must be object or both incomplete.  */
-         if (comp_target_types (type0, type1))
+         if (comp_target_types (type0, type1, 1))
            result_type = common_type (type0, type1);
          else if (VOID_TYPE_P (tt0))
            {
@@ -2234,7 +2206,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
        shorten = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        {
-         if (comp_target_types (type0, type1))
+         if (comp_target_types (type0, type1, 1))
            {
              result_type = common_type (type0, type1);
              if (pedantic 
@@ -2259,7 +2231,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
        short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        {
-         if (comp_target_types (type0, type1))
+         if (comp_target_types (type0, type1, 1))
            {
              result_type = common_type (type0, type1);
              if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
@@ -2321,9 +2293,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
       break;
     }
 
-  if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+  if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
+       || code0 == VECTOR_TYPE)
       &&
-      (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
+      (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
+       || code1 == VECTOR_TYPE))
     {
       int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
 
@@ -2385,22 +2359,24 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
              && unsigned0 == unsigned1
              && (unsigned0 || !uns))
            result_type
-             = signed_or_unsigned_type (unsigned0,
-                                        common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+             = c_common_signed_or_unsigned_type
+             (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
          else if (TREE_CODE (arg0) == INTEGER_CST
                   && (unsigned1 || !uns)
                   && (TYPE_PRECISION (TREE_TYPE (arg1))
                       < TYPE_PRECISION (result_type))
-                  && (type = signed_or_unsigned_type (unsigned1,
-                                                      TREE_TYPE (arg1)),
+                  && (type
+                      = c_common_signed_or_unsigned_type (unsigned1,
+                                                          TREE_TYPE (arg1)),
                       int_fits_type_p (arg0, type)))
            result_type = type;
          else if (TREE_CODE (arg1) == INTEGER_CST
                   && (unsigned0 || !uns)
                   && (TYPE_PRECISION (TREE_TYPE (arg0))
                       < TYPE_PRECISION (result_type))
-                  && (type = signed_or_unsigned_type (unsigned0,
-                                                      TREE_TYPE (arg0)),
+                  && (type
+                      = c_common_signed_or_unsigned_type (unsigned0,
+                                                          TREE_TYPE (arg0)),
                       int_fits_type_p (arg1, type)))
            result_type = type;
        }
@@ -2426,7 +2402,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
            {
              /* Do an unsigned shift if the operand was zero-extended.  */
              result_type
-               = signed_or_unsigned_type (unsigned_arg, TREE_TYPE (arg0));
+               = c_common_signed_or_unsigned_type (unsigned_arg,
+                                                   TREE_TYPE (arg0));
              /* Convert value-to-be-shifted to that type.  */
              if (TREE_TYPE (op0) != result_type)
                op0 = convert (result_type, op0);
@@ -2497,22 +2474,24 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
                     constant expression involving such literals or a
                     conditional expression involving such literals)
                     and it is non-negative.  */
-                 if (tree_expr_nonnegative_p (sop))
+                 if (c_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)))
+                          && int_fits_type_p
+                          (uop, c_common_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)))
+                          && int_fits_type_p
+                          (TYPE_MAX_VALUE (TREE_TYPE(uop)),
+                           c_common_signed_type (result_type)))
                    /* OK */;
                  else
                    warning ("comparison between signed and unsigned");
@@ -2611,6 +2590,27 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
   }
 }
 \f
+
+/* Return true if `t' is known to be non-negative.  */
+
+int
+c_tree_expr_nonnegative_p (t)
+     tree t;
+{
+  if (TREE_CODE (t) == STMT_EXPR)
+    {
+      t = COMPOUND_BODY (STMT_EXPR_STMT (t));
+
+      /* Find the last statement in the chain, ignoring the final
+            * scope statement */
+      while (TREE_CHAIN (t) != NULL_TREE 
+             && TREE_CODE (TREE_CHAIN (t)) != SCOPE_STMT)
+        t = TREE_CHAIN (t);
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
+    }
+  return tree_expr_nonnegative_p (t);
+}
+
 /* Return a tree for the difference of pointers OP0 and OP1.
    The resulting tree has type int.  */
 
@@ -2732,11 +2732,13 @@ build_unary_op (code, xarg, flag)
        }
       else if (!noconvert)
        arg = default_conversion (arg);
+      arg = non_lvalue (arg);
       break;
 
     case NEGATE_EXPR:
       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
-           || typecode == COMPLEX_TYPE))
+           || typecode == COMPLEX_TYPE
+           || typecode == VECTOR_TYPE))
        {
          error ("wrong type argument to unary minus");
          return error_mark_node;
@@ -2746,7 +2748,12 @@ build_unary_op (code, xarg, flag)
       break;
 
     case BIT_NOT_EXPR:
-      if (typecode == COMPLEX_TYPE)
+      if (typecode == INTEGER_TYPE || typecode == VECTOR_TYPE)
+       {
+         if (!noconvert)
+           arg = default_conversion (arg);
+       }
+      else if (typecode == COMPLEX_TYPE)
        {
          code = CONJ_EXPR;
          if (pedantic)
@@ -2754,13 +2761,11 @@ build_unary_op (code, xarg, flag)
          if (!noconvert)
            arg = default_conversion (arg);
        }
-      else if (typecode != INTEGER_TYPE)
+      else
        {
          error ("wrong type argument to bit-complement");
          return error_mark_node;
        }
-      else if (!noconvert)
-       arg = default_conversion (arg);
       break;
 
     case ABS_EXPR:
@@ -2796,7 +2801,7 @@ build_unary_op (code, xarg, flag)
          error ("wrong type argument to unary exclamation mark");
          return error_mark_node;
        }
-      arg = truthvalue_conversion (arg);
+      arg = c_common_truthvalue_conversion (arg);
       return invert_truthvalue (arg);
 
     case NOP_EXPR:
@@ -2986,7 +2991,7 @@ build_unary_op (code, xarg, flag)
       /* For &x[y], return x+y */
       if (TREE_CODE (arg) == ARRAY_REF)
        {
-         if (mark_addressable (TREE_OPERAND (arg, 0)) == 0)
+         if (!c_mark_addressable (TREE_OPERAND (arg, 0)))
            return error_mark_node;
          return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
                                  TREE_OPERAND (arg, 1), 1);
@@ -3041,7 +3046,7 @@ build_unary_op (code, xarg, flag)
 
       argtype = build_pointer_type (argtype);
 
-      if (mark_addressable (arg) == 0)
+      if (!c_mark_addressable (arg))
        return error_mark_node;
 
       {
@@ -3260,13 +3265,14 @@ readonly_warning (arg, msgid)
 \f
 /* Mark EXP saying that we need to be able to take the
    address of it; it should not be allocated in a register.
-   Value is 1 if successful.  */
+   Returns true if successful.  */
 
-int
-mark_addressable (exp)
+bool
+c_mark_addressable (exp)
      tree exp;
 {
   tree x = exp;
+
   while (1)
     switch (TREE_CODE (x))
       {
@@ -3275,7 +3281,7 @@ mark_addressable (exp)
          {
            error ("cannot take address of bit-field `%s'",
                   IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1))));
-           return 0;
+           return false;
          }
 
        /* ... fall through ...  */
@@ -3290,7 +3296,7 @@ mark_addressable (exp)
       case COMPOUND_LITERAL_EXPR:
       case CONSTRUCTOR:
        TREE_ADDRESSABLE (x) = 1;
-       return 1;
+       return true;
 
       case VAR_DECL:
       case CONST_DECL:
@@ -3303,7 +3309,7 @@ mark_addressable (exp)
              {
                error ("global register variable `%s' used in nested function",
                       IDENTIFIER_POINTER (DECL_NAME (x)));
-               return 0;
+               return false;
              }
            pedwarn ("register variable `%s' used in nested function",
                     IDENTIFIER_POINTER (DECL_NAME (x)));
@@ -3314,7 +3320,7 @@ mark_addressable (exp)
              {
                error ("address of global register variable `%s' requested",
                       IDENTIFIER_POINTER (DECL_NAME (x)));
-               return 0;
+               return false;
              }
 
            /* If we are making this addressable due to its having
@@ -3325,7 +3331,7 @@ mark_addressable (exp)
            else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
              {
                error ("cannot put object with volatile field into register");
-               return 0;
+               return false;
              }
 
            pedwarn ("address of register variable `%s' requested",
@@ -3342,7 +3348,7 @@ mark_addressable (exp)
 #endif
 
       default:
-       return 1;
+       return true;
     }
 }
 \f
@@ -3359,7 +3365,7 @@ build_conditional_expr (ifexp, op1, op2)
   tree result_type = NULL;
   tree orig_op1 = op1, orig_op2 = op2;
 
-  ifexp = truthvalue_conversion (default_conversion (ifexp));
+  ifexp = c_common_truthvalue_conversion (default_conversion (ifexp));
 
 #if 0 /* Produces wrong result if within sizeof.  */
   /* Don't promote the operands separately if they promote
@@ -3432,8 +3438,8 @@ build_conditional_expr (ifexp, op1, op2)
              /* 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)))
+             else if ((unsigned_op2 && c_tree_expr_nonnegative_p (op1))
+                      || (unsigned_op1 && c_tree_expr_nonnegative_p (op2)))
                /* OK */;
              else
                warning ("signed and unsigned type in conditional expression");
@@ -3448,7 +3454,7 @@ build_conditional_expr (ifexp, op1, op2)
     }
   else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
     {
-      if (comp_target_types (type1, type2))
+      if (comp_target_types (type1, type2, 1))
        result_type = common_type (type1, type2);
       else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
               && TREE_CODE (orig_op1) != NOP_EXPR)
@@ -3569,7 +3575,7 @@ internal_build_compound_expr (list, first_p)
   if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
     {
       /* The left-hand operand of a comma expression is like an expression
-         statement: with -W or -Wunused, we should warn if it doesn't have
+         statement: with -Wextra or -Wunused, we should warn if it doesn't have
         any side-effects, unless it was explicitly cast to (void).  */
       if ((extra_warnings || warn_unused_value)
            && ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR
@@ -3603,7 +3609,12 @@ build_c_cast (type, expr)
   
   if (type == error_mark_node || expr == error_mark_node)
     return error_mark_node;
-  type = TYPE_MAIN_VARIANT (type);
+
+  /* The ObjC front-end uses TYPE_MAIN_VARIANT to tie together types differing
+     only in <protocol> qualifications.  But when constructing cast expressions,
+     the protocols do matter and must be kept around.  */
+  if (!flag_objc || !objc_is_id (type))
+    type = TYPE_MAIN_VARIANT (type);
 
 #if 0
   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
@@ -3644,20 +3655,10 @@ build_c_cast (type, expr)
 
       if (field)
        {
-         const char *name;
          tree t;
 
          if (pedantic)
            pedwarn ("ISO C forbids casts to union type");
-         if (TYPE_NAME (type) != 0)
-           {
-             if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
-               name = IDENTIFIER_POINTER (TYPE_NAME (type));
-             else
-               name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
-           }
-         else
-           name = "";
          t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE,
                                        build_tree_list (field, value)), 0);
          TREE_CONSTANT (t) = TREE_CONSTANT (value);
@@ -3754,7 +3755,27 @@ build_c_cast (type, expr)
          && !TREE_CONSTANT (value))
        warning ("cast to pointer from integer of different size");
 
+      if (TREE_CODE (type) == POINTER_TYPE
+         && TREE_CODE (otype) == POINTER_TYPE
+         && TREE_CODE (expr) == ADDR_EXPR
+         && DECL_P (TREE_OPERAND (expr, 0))
+         && flag_strict_aliasing && warn_strict_aliasing
+         && !VOID_TYPE_P (TREE_TYPE (type)))
+       {
+         /* Casting the address of a decl to non void pointer. Warn
+            if the cast breaks type based aliasing.  */
+         if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
+           warning ("type-punning to incomplete type might break strict-aliasing rules");
+         else if (!alias_sets_conflict_p
+                  (get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0))),
+                   get_alias_set (TREE_TYPE (type))))
+           warning ("dereferencing type-punned pointer will break strict-aliasing rules");
+       }
+
       ovalue = value;
+      /* Replace a nonvolatile const static variable with its value.  */
+      if (optimize && TREE_CODE (value) == VAR_DECL)
+       value = decl_constant_value (value);
       value = convert (type, value);
 
       /* Ignore any integer overflow caused by the cast.  */
@@ -4010,9 +4031,11 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
     {
       overflow_warning (rhs);
-      /* Check for Objective-C protocols.  This will issue a warning if
-        there are protocol violations.  No need to use the return value.  */
-      maybe_objc_comptypes (type, rhstype, 0);
+      /* Check for Objective-C protocols.  This will automatically
+        issue a warning if there are protocol violations.  No need to
+        use the return value.  */
+      if (flag_objc)
+       objc_comptypes (type, rhstype, 0);
       return rhs;
     }
 
@@ -4032,7 +4055,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
          error ("cannot pass rvalue to reference parameter");
          return error_mark_node;
        }
-      if (mark_addressable (rhs) == 0)
+      if (!c_mark_addressable (rhs))
        return error_mark_node;
       rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
 
@@ -4047,11 +4070,16 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
       rhs = build1 (NOP_EXPR, type, rhs);
       return rhs;
     }
+  /* Some types can interconvert without explicit casts.  */
+  else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE
+          && ((*targetm.vector_opaque_p) (type)
+              || (*targetm.vector_opaque_p) (rhstype)))
+    return convert (type, rhs);
   /* Arithmetic types all interconvert, and enum is treated like int.  */
   else if ((codel == INTEGER_TYPE || codel == REAL_TYPE 
            || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
            || codel == BOOLEAN_TYPE)
-          && (coder == INTEGER_TYPE || coder == REAL_TYPE 
+          && (coder == INTEGER_TYPE || coder == REAL_TYPE
               || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
               || coder == BOOLEAN_TYPE))
     return convert_and_check (type, rhs);
@@ -4085,7 +4113,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
                 Meanwhile, the lhs target must have all the qualifiers of
                 the rhs.  */
              if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
-                 || comp_target_types (memb_type, rhstype))
+                 || comp_target_types (memb_type, rhstype, 0))
                {
                  /* If this type won't generate any warnings, use it.  */
                  if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
@@ -4160,9 +4188,9 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
         and vice versa; otherwise, targets must be the same.
         Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
       if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
-         || comp_target_types (type, rhstype)
-         || (unsigned_type (TYPE_MAIN_VARIANT (ttl))
-             == unsigned_type (TYPE_MAIN_VARIANT (ttr))))
+         || comp_target_types (type, rhstype, 0)
+         || (c_common_unsigned_type (TYPE_MAIN_VARIANT (ttl))
+             == c_common_unsigned_type (TYPE_MAIN_VARIANT (ttr))))
        {
          if (pedantic
              && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE)
@@ -4185,7 +4213,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
              /* If this is not a case of ignoring a mismatch in signedness,
                 no warning.  */
              else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
-                      || comp_target_types (type, rhstype))
+                      || comp_target_types (type, rhstype, 0))
                ;
              /* If there is a mismatch, do warn.  */
              else if (pedantic)
@@ -4240,7 +4268,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
     {
       if (funname)
        {
-         tree selector = maybe_building_objc_message_expr ();
+         tree selector = objc_message_selector ();
  
          if (selector && parmnum > 2)
            error ("incompatible type for argument %d of `%s'",
@@ -4285,7 +4313,8 @@ c_convert_parm_for_inlining (parm, value, fn)
 
 /* 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'".
+   if OPNAME is null and ARGNUM is 0, it is replaced by "passing arg of `FUNCTION'".
+   Otherwise 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.  */
 
@@ -4298,7 +4327,7 @@ warn_for_assignment (msgid, opname, function, argnum)
 {
   if (opname == 0)
     {
-      tree selector = maybe_building_objc_message_expr ();
+      tree selector = objc_message_selector ();
       char * new_opname;
       
       if (selector && argnum > 2)
@@ -4306,7 +4335,27 @@ warn_for_assignment (msgid, opname, function, argnum)
          function = selector;
          argnum -= 2;
        }
-      if (function)
+      if (argnum == 0)
+       {
+         if (function)
+           {       
+             /* Function name is known; supply it.  */
+             const char *const argstring = _("passing arg of `%s'");
+             new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
+                                           + strlen (argstring) + 1
+                                           + 1);
+             sprintf (new_opname, argstring,
+                      IDENTIFIER_POINTER (function));
+           }
+         else
+           {
+             /* Function name unknown (call through ptr).  */
+             const char *const argnofun = _("passing arg of pointer to function");
+             new_opname = (char *) alloca (strlen (argnofun) + 1 + 1);
+             sprintf (new_opname, argnofun);
+           }
+       }
+      else if (function)
        {
          /* Function name is known; supply it.  */
          const char *const argstring = _("passing arg %d of `%s'");
@@ -4473,15 +4522,6 @@ static int spelling_size;                /* Size of the spelling stack.  */
 #define SPELLING_DEPTH() (spelling - spelling_base)
 #define RESTORE_SPELLING_DEPTH(DEPTH) (spelling = spelling_base + (DEPTH))
 
-/* Save and restore the spelling stack around arbitrary C code.  */
-
-#define SAVE_SPELLING_DEPTH(code)              \
-{                                              \
-  int __depth = SPELLING_DEPTH ();             \
-  code;                                                \
-  RESTORE_SPELLING_DEPTH (__depth);            \
-}
-
 /* Push an element on the spelling stack with type KIND and assign VALUE
    to MEMBER.  */
 
@@ -5120,6 +5160,9 @@ really_start_incremental_init (type)
   if (type == 0)
     type = TREE_TYPE (constructor_decl);
 
+  if ((*targetm.vector_opaque_p) (type))
+    error ("opaque vector types cannot be initialized");
+
   p->type = constructor_type;
   p->fields = constructor_fields;
   p->index = constructor_index;
@@ -5178,7 +5221,7 @@ really_start_incremental_init (type)
            constructor_max_index = build_int_2 (-1, -1);
 
          /* constructor_max_index needs to be an INTEGER_CST.  Attempts
-            to initialize VLAs will cause an proper error; avoid tree
+            to initialize VLAs will cause a proper error; avoid tree
             checking errors as well by setting a safe value.  */
          if (constructor_max_index
              && TREE_CODE (constructor_max_index) != INTEGER_CST)
@@ -5230,6 +5273,7 @@ push_init_level (implicit)
          && constructor_fields == 0)
        process_init_element (pop_init_level (1));
       else if (TREE_CODE (constructor_type) == ARRAY_TYPE
+              && constructor_max_index 
               && tree_int_cst_lt (constructor_max_index, constructor_index))
        process_init_element (pop_init_level (1));
       else
@@ -5368,7 +5412,7 @@ push_init_level (implicit)
            constructor_max_index = build_int_2 (-1, -1);
 
          /* constructor_max_index needs to be an INTEGER_CST.  Attempts
-            to initialize VLAs will cause an proper error; avoid tree
+            to initialize VLAs will cause a proper error; avoid tree
             checking errors as well by setting a safe value.  */
          if (constructor_max_index
              && TREE_CODE (constructor_max_index) != INTEGER_CST)
@@ -5557,7 +5601,7 @@ pop_init_level (implicit)
 }
 
 /* Common handling for both array range and field name designators.
-   ARRAY argument is non-zero for array ranges.  Returns zero for success.  */
+   ARRAY argument is nonzero for array ranges.  Returns zero for success.  */
 
 static int
 set_designator (array)
@@ -6582,13 +6626,18 @@ process_init_element (value)
                                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);
+             /* If the current field was the first one not yet written out,
+                it isn't now, so update.  */
+             if (constructor_unfilled_fields == 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);
@@ -6821,11 +6870,9 @@ simple_asm_stmt (expr)
     {
       tree stmt;
 
-      if (TREE_CHAIN (expr))
-       expr = combine_strings (expr);
-      stmt = add_stmt (build_stmt (ASM_STMT, NULL_TREE, expr,
-                                  NULL_TREE, NULL_TREE,
-                                  NULL_TREE));
+      /* Simple asm statements are treated as volatile.  */
+      stmt = add_stmt (build_stmt (ASM_STMT, ridpointers[(int) RID_VOLATILE],
+                                  expr, NULL_TREE, NULL_TREE, NULL_TREE));
       ASM_INPUT_P (stmt) = 1;
       return stmt;
     }
@@ -6847,8 +6894,6 @@ build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers)
 {
   tree tail;
 
-  if (TREE_CHAIN (string))
-    string = combine_strings (string);
   if (TREE_CODE (string) != STRING_CST)
     {
       error ("asm template is not a string constant");
@@ -6925,7 +6970,11 @@ 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);
+    {
+      o[i] = TREE_VALUE (tail);
+      if (o[i] == error_mark_node)
+       return;
+    }
 
   /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
      OUTPUTS some trees for where the values were actually stored.  */
@@ -7136,11 +7185,19 @@ do_case (low_value, high_value)
 
   if (switch_stack)
     {
+      bool switch_was_empty_p = (SWITCH_BODY (switch_stack->switch_stmt) == NULL_TREE);
+
       label = c_add_case_label (switch_stack->cases, 
                                SWITCH_COND (switch_stack->switch_stmt), 
                                low_value, high_value);
       if (label == error_mark_node)
        label = NULL_TREE;
+      else if (switch_was_empty_p)
+       {
+         /* Attach the first case label to the SWITCH_BODY.  */
+         SWITCH_BODY (switch_stack->switch_stmt) = TREE_CHAIN (switch_stack->switch_stmt);
+         TREE_CHAIN (switch_stack->switch_stmt) = NULL_TREE;
+       }
     }
   else if (low_value)
     error ("case label not within a switch statement");
@@ -7157,7 +7214,8 @@ c_finish_case ()
 {
   struct c_switch *cs = switch_stack;
 
-  RECHAIN_STMTS (cs->switch_stmt, SWITCH_BODY (cs->switch_stmt)); 
+  /* Rechain the next statements to the SWITCH_STMT.  */
+  last_tree = cs->switch_stmt;
 
   /* Pop the stack.  */
   switch_stack = switch_stack->next;