OSDN Git Service

(struct function): Make frame_offset be HOST_WIDE_INT.
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index 48c93a0..7e5608c 100644 (file)
@@ -395,7 +395,7 @@ common_type (t1, t2)
          }
 
        t1 = build_function_type (valtype, newargs);
-       /* ... falls through ... */
+       /* ... falls through ...  */
       }
 
     default:
@@ -735,7 +735,8 @@ unsigned_type (type)
     return unsigned_intHI_type_node;
   if (type1 == intQI_type_node)
     return unsigned_intQI_type_node;
-  return type;
+
+  return signed_or_unsigned_type (1, type);
 }
 
 /* Return a signed type the same as TYPE in other respects.  */
@@ -763,7 +764,8 @@ signed_type (type)
     return intHI_type_node;
   if (type1 == unsigned_intQI_type_node)
     return intQI_type_node;
-  return type;
+
+  return signed_or_unsigned_type (0, type);
 }
 
 /* Return a type the same as TYPE except unsigned or
@@ -774,7 +776,8 @@ signed_or_unsigned_type (unsignedp, type)
      int unsignedp;
      tree type;
 {
-  if (! INTEGRAL_TYPE_P (type))
+  if (! INTEGRAL_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;
@@ -938,16 +941,16 @@ c_alignof_expr (expr)
   else
     return c_alignof (TREE_TYPE (expr));
 }
+
 /* Return either DECL or its known constant value (if it has one).  */
 
 static tree
 decl_constant_value (decl)
      tree decl;
 {
-  if (! TREE_PUBLIC (decl)
-      /* Don't change a variable array bound or initial value to a constant
+  if (/* Don't change a variable array bound or initial value to a constant
         in a place where a variable is invalid.  */
-      && current_function_decl != 0
+      current_function_decl != 0
       && ! pedantic
       && ! TREE_THIS_VOLATILE (decl)
       && TREE_READONLY (decl) && ! ITERATOR_P (decl)
@@ -1010,6 +1013,24 @@ default_conversion (exp)
       return convert (type, exp);
     }
 
+  if (TREE_CODE (exp) == COMPONENT_REF
+      && DECL_BIT_FIELD (TREE_OPERAND (exp, 1)))
+    {
+    tree width = DECL_SIZE (TREE_OPERAND (exp, 1));
+    HOST_WIDE_INT low = TREE_INT_CST_LOW (width);
+
+    /* 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);
+      }
+    }
+
   if (C_PROMOTING_INTEGER_TYPE_P (type))
     {
       /* Traditionally, unsignedness is preserved in default promotions.
@@ -1299,7 +1320,7 @@ build_indirect_ref (ptr, errorstring)
              error ("dereferencing pointer to incomplete type");
              return error_mark_node;
            }
-         if (TREE_CODE (t) == VOID_TYPE)
+         if (TREE_CODE (t) == VOID_TYPE && skip_evaluation == 0)
            warning ("dereferencing `void *' pointer");
 
          /* We *must* set TREE_READONLY when dereferencing a pointer to const,
@@ -1433,6 +1454,14 @@ build_array_ref (array, index)
     tree ar = default_conversion (array);
     tree ind = default_conversion (index);
 
+    /* Do the same warning check as above, but only on the part that's
+       syntactically the index and only if it is also semantically
+       the index.  */
+    if (warn_char_subscripts
+       && TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE
+       && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
+      warning ("subscript has type `char'");
+
     /* Put the integer in IND to simplify error checking.  */
     if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
       {
@@ -1703,7 +1732,7 @@ convert_arguments (typelist, values, name, fundecl)
                }
 
              parmval = convert_for_assignment (type, val, 
-                                               (char *)0, /* arg passing  */
+                                               (char *) 0, /* arg passing  */
                                                fundecl, name, parmnum + 1);
              
 #ifdef PROMOTE_PROTOTYPES
@@ -2078,7 +2107,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
     case RSHIFT_EXPR:
       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
        {
-         if (TREE_CODE (op1) == INTEGER_CST)
+         if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
            {
              if (tree_int_cst_sgn (op1) < 0)
                warning ("right shift count is negative");
@@ -2110,7 +2139,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
     case LSHIFT_EXPR:
       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
        {
-         if (TREE_CODE (op1) == INTEGER_CST)
+         if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
            {
              if (tree_int_cst_sgn (op1) < 0)
                warning ("left shift count is negative");
@@ -2138,7 +2167,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
     case LROTATE_EXPR:
       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
        {
-         if (TREE_CODE (op1) == INTEGER_CST)
+         if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
            {
              if (tree_int_cst_sgn (op1) < 0)
                warning ("shift count is negative");
@@ -2440,7 +2469,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
          converted = 1;
          resultcode = xresultcode;
 
-         if (warn_sign_compare)
+         if (warn_sign_compare && skip_evaluation == 0)
            {
              int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
              int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
@@ -2649,8 +2678,10 @@ pointer_int_sum (resultcode, ptrop, intop)
   /* Convert the integer argument to a type the same size as sizetype
      so the multiply won't overflow spuriously.  */
 
-  if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype))
-    intop = convert (type_for_size (TYPE_PRECISION (sizetype), 0), intop);
+  if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
+      || TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
+    intop = convert (type_for_size (TYPE_PRECISION (sizetype), 
+                                   TREE_UNSIGNED (sizetype)), intop);
 
   /* Replace the integer argument with a suitable product by the object size.
      Do this multiplication as signed, then convert to the appropriate
@@ -2691,10 +2722,12 @@ pointer_diff (op0, op1)
     }
 
   /* First do the subtraction as integers;
-     then drop through to build the divide operator.  */
+     then drop through to build the divide operator.
+     Do not do default conversions on the minus operator
+     in case restype is a short type.  */
 
   op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
-                        convert (restype, op1), 1);
+                        convert (restype, op1), 0);
   /* This generates an error if op1 is pointer to incomplete type.  */
   if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
     error ("arithmetic on pointer to an incomplete type");
@@ -3264,7 +3297,7 @@ mark_addressable (exp)
            return 0;
          }
 
-       /* ... fall through ... */
+       /* ... fall through ...  */
 
       case ADDR_EXPR:
       case ARRAY_REF:
@@ -3344,15 +3377,6 @@ build_conditional_expr (ifexp, op1, op2)
   register tree result_type = NULL;
   tree orig_op1 = op1, orig_op2 = op2;
 
-  /* If second operand is omitted, it is the same as the first one;
-     make sure it is calculated only once.  */
-  if (op1 == 0)
-    {
-      if (pedantic)
-       pedwarn ("ANSI C forbids omitting the middle term of a ?: expression");
-      ifexp = orig_op1 = op1 = save_expr (ifexp);
-    }
-
   ifexp = truthvalue_conversion (default_conversion (ifexp));
 
 #if 0 /* Produces wrong result if within sizeof.  */
@@ -4059,7 +4083,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
          if (! memb_types)
            {
              /* We have only a marginally acceptable member type;
-                it needs a warning. */
+                it needs a warning.  */
              register tree ttl = TREE_TYPE (marginal_memb_type);
              register tree ttr = TREE_TYPE (rhstype);
 
@@ -5015,7 +5039,7 @@ static tree constructor_pending_elts;
 static int constructor_depth;
 
 /* 0 if implicitly pushing constructor levels is allowed.  */
-int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages. */
+int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages.  */
 
 /* 1 if this constructor level was entered implicitly.  */
 static int constructor_implicit;
@@ -5331,10 +5355,12 @@ push_init_level (implicit)
        break;
     }
 
-  /* Structure elements may require alignment.  Do this now
-     if necessary for the subaggregate.  */
+  /* Structure elements may require alignment.  Do this now if necessary
+     for the subaggregate, and if it comes next in sequence.  Don't do
+     this for subaggregates that will go on the pending list.  */
   if (constructor_incremental && constructor_type != 0
-      && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_fields)
+      && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_fields
+      && constructor_fields == constructor_unfilled_fields)
     {
       /* Advance to offset of this element.  */
       if (! tree_int_cst_equal (constructor_bit_index,
@@ -5737,6 +5763,8 @@ set_init_index (first, last)
     error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
   else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
     error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+  else if (! constructor_unfilled_index)
+    error_init ("array index in non-array initializer%s", " for `%s'", NULL);
   else if (tree_int_cst_lt (first, constructor_unfilled_index))
     error_init ("duplicate array index in initializer%s", " for `%s'", NULL);
   else
@@ -6345,7 +6373,7 @@ process_init_element (value)
              break;
            }
 
-         /* In the case of [LO .. HI] = VALUE, only evaluate VALUE once. */
+         /* In the case of [LO .. HI] = VALUE, only evaluate VALUE once.  */
          if (constructor_range_end)
            value = save_expr (value);