OSDN Git Service

(lookup_field): Don't recurse unless FIELD is a RECORD_TYPE or
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index fa647db..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.
 
@@ -1151,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;
@@ -1190,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;
@@ -1320,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,
@@ -2107,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");
@@ -2139,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");
@@ -2167,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");
@@ -2469,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));
@@ -3377,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.  */
@@ -5778,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);
@@ -6222,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;
@@ -6384,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.
@@ -6402,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