OSDN Git Service

(lookup_field): Don't recurse unless FIELD is a RECORD_TYPE or
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index 9a0030d..32111d0 100644 (file)
@@ -1,5 +1,5 @@
 /* Build expressions with type checking for C compiler.
-   Copyright (C) 1987, 88, 91, 92-5, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 91-6, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -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;
@@ -1148,10 +1151,13 @@ lookup_field (type, component, indirect)
              /* Step through all anon unions in linear fashion.  */
              while (DECL_NAME (field_array[bot]) == NULL_TREE)
                {
-                 tree anon, junk;
+                 tree anon = 0, junk;
 
                  field = field_array[bot++];
-                 anon = lookup_field (TREE_TYPE (field), component, &junk);
+                 if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
+                     || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+                   anon = lookup_field (TREE_TYPE (field), component, &junk);
+
                  if (anon != NULL_TREE)
                    {
                      *indirect = field;
@@ -1187,7 +1193,12 @@ lookup_field (type, component, indirect)
          if (DECL_NAME (field) == NULL_TREE)
            {
              tree junk;
-             tree anon = lookup_field (TREE_TYPE (field), component, &junk);
+             tree anon = 0;
+
+             if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
+                 || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+               anon = lookup_field (TREE_TYPE (field), component, &junk);
+
              if (anon != NULL_TREE)
                {
                  *indirect = field;
@@ -1317,7 +1328,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,
@@ -2104,7 +2115,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");
@@ -2136,7 +2147,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");
@@ -2164,7 +2175,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");
@@ -2466,7 +2477,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));
@@ -3374,15 +3385,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.  */
@@ -5775,10 +5777,8 @@ set_init_index (first, last)
     error_init ("duplicate array index in initializer%s", " for `%s'", NULL);
   else
     {
-      TREE_INT_CST_LOW (constructor_index)
-       = TREE_INT_CST_LOW (first);
-      TREE_INT_CST_HIGH (constructor_index)
-       = TREE_INT_CST_HIGH (first);
+      TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (first);
+      TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (first);
 
       if (last != 0 && tree_int_cst_lt (last, first))
        error_init ("empty index range in initializer%s", " for `%s'", NULL);
@@ -6219,7 +6219,9 @@ process_init_element (value)
          && constructor_fields == 0)
        process_init_element (pop_init_level (1));
       else if (TREE_CODE (constructor_type) == ARRAY_TYPE
-              && tree_int_cst_lt (constructor_max_index, constructor_index))
+              && (constructor_max_index == 0
+                  || tree_int_cst_lt (constructor_max_index,
+                                      constructor_index)))
        process_init_element (pop_init_level (1));
       else
        break;
@@ -6381,7 +6383,21 @@ process_init_element (value)
 
          /* In the case of [LO .. HI] = VALUE, only evaluate VALUE once.  */
          if (constructor_range_end)
-           value = save_expr (value);
+           {
+             if (constructor_max_index != 0
+                 && 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);
+               }
+
+             value = save_expr (value);
+           }
 
          /* Now output the actual element.
             Ordinarily, output once.
@@ -6399,10 +6415,8 @@ process_init_element (value)
 
              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);
+             TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (tem);
+             TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (tem);
 
              if (!value)
                /* If we are doing the bookkeeping for an element that was