OSDN Git Service

* doc/install.texi (xtensa-*-elf): New target.
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index 64f0f07..37f6a87 100644 (file)
@@ -1,6 +1,6 @@
 /* Build expressions with type checking for C compiler.
    Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -31,12 +31,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "rtl.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"
@@ -93,7 +93,7 @@ require_complete_type (value)
 {
   tree type = TREE_TYPE (value);
 
-  if (TREE_CODE (value) == ERROR_MARK)
+  if (value == error_mark_node || type == error_mark_node)
     return error_mark_node;
 
   /* First, detect a valid value with a complete type.  */
@@ -910,8 +910,7 @@ default_function_array_conversion (exp)
        }
 
       lvalue_array_p = !not_lvalue && lvalue_p (exp);
-      if (!flag_isoc99 && !lvalue_array_p
-         && !(TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
+      if (!flag_isoc99 && !lvalue_array_p)
        {
          /* Before C99, non-lvalue arrays do not decay to pointers.
             Normally, using such an array would be invalid; but it can
@@ -1200,6 +1199,10 @@ build_component_ref (datum, component)
            TREE_READONLY (ref) = 1;
          if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum))
            TREE_THIS_VOLATILE (ref) = 1;
+
+         if (TREE_DEPRECATED (subdatum))
+           warn_deprecated_use (subdatum);
+
          datum = ref;
        }
 
@@ -1416,6 +1419,9 @@ build_external_ref (id, fun)
   tree decl = lookup_name (id);
   tree objc_ivar = lookup_objc_ivar (id);
 
+  if (decl && TREE_DEPRECATED (decl))
+    warn_deprecated_use (decl);
+
   if (!decl || decl == error_mark_node || C_DECL_ANTICIPATED (decl))
     {
       if (objc_ivar)
@@ -1793,6 +1799,9 @@ parser_build_binary_op (code, arg1, arg2)
   enum tree_code code1 = ERROR_MARK;
   enum tree_code code2 = ERROR_MARK;
 
+  if (TREE_CODE (result) == ERROR_MARK)
+    return error_mark_node;
+
   if (IS_EXPR_CODE_CLASS (class1))
     code1 = C_EXP_ORIGINAL_CODE (arg1);
   if (IS_EXPR_CODE_CLASS (class2))
@@ -3079,7 +3088,7 @@ build_unary_op (code, xarg, flag)
          readonly_warning (arg, 
                            ((code == PREINCREMENT_EXPR
                              || code == POSTINCREMENT_EXPR)
-                            ? _("increment") : _("decrement")));
+                            ? "increment" : "decrement"));
 
        if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
          val = boolean_increment (code, arg);
@@ -3141,10 +3150,6 @@ build_unary_op (code, xarg, flag)
        }
 #endif
 
-      /* Allow the address of a constructor if all the elements
-        are constant.  */
-      if (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg))
-       ;
       /* Anything not already handled and not a true memory reference
         or a non-lvalue array is an error.  */
       else if (typecode != FUNCTION_TYPE && !flag
@@ -3256,6 +3261,7 @@ lvalue_p (ref)
     case COMPONENT_REF:
       return lvalue_p (TREE_OPERAND (ref, 0));
 
+    case COMPOUND_LITERAL_EXPR:
     case STRING_CST:
       return 1;
 
@@ -3397,7 +3403,7 @@ mark_addressable (exp)
       case COMPONENT_REF:
        if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
          {
-           error ("cannot take address of bitfield `%s'",
+           error ("cannot take address of bit-field `%s'",
                   IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1))));
            return 0;
          }
@@ -3411,6 +3417,7 @@ mark_addressable (exp)
        x = TREE_OPERAND (x, 0);
        break;
 
+      case COMPOUND_LITERAL_EXPR:
       case CONSTRUCTOR:
        TREE_ADDRESSABLE (x) = 1;
        return 1;
@@ -4400,7 +4407,7 @@ warn_for_assignment (msgid, opname, function, argnum)
        }
       else
        {
-         /* Function name unknown (call through ptr); just give arg number.*/
+         /* Function name unknown (call through ptr); just give arg number.  */
          const char *const argnofun = _("passing arg %d of pointer to function");
          new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
          sprintf (new_opname, argnofun, argnum);
@@ -4498,6 +4505,33 @@ store_init_value (decl, init)
   /* ANSI wants warnings about out-of-range constant initializers.  */
   STRIP_TYPE_NOPS (value);
   constant_expression_warning (value);
+
+  /* Check if we need to set array size from compound literal size.  */
+  if (TREE_CODE (type) == ARRAY_TYPE
+      && TYPE_DOMAIN (type) == 0
+      && value != error_mark_node)
+    {
+      tree inside_init = init;
+
+      if (TREE_CODE (init) == NON_LVALUE_EXPR)
+       inside_init = TREE_OPERAND (init, 0);
+      inside_init = fold (inside_init);
+
+      if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
+       {
+         tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
+
+         if (TYPE_DOMAIN (TREE_TYPE (decl)))
+           {
+             /* For int foo[] = (int [3]){1}; we need to set array size
+                now since later on array initializer will be just the
+                brace enclosed list of the compound literal.  */
+             TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (decl));
+             layout_type (type);
+             layout_decl (decl, 0);
+           }
+       }
+    }
 }
 \f
 /* Methods for storing and printing names for error messages.  */
@@ -4649,7 +4683,7 @@ error_init (msgid)
 {
   char *ofwhat;
 
-  error ("%s", msgid);
+  error ("%s", _(msgid));
   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
     error ("(near initialization for `%s')", ofwhat);
@@ -4665,7 +4699,7 @@ pedwarn_init (msgid)
 {
   char *ofwhat;
 
-  pedwarn ("%s", msgid);
+  pedwarn ("%s", _(msgid));
   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
     pedwarn ("(near initialization for `%s')", ofwhat);
@@ -4681,7 +4715,7 @@ warning_init (msgid)
 {
   char *ofwhat;
 
-  warning ("%s", msgid);
+  warning ("%s", _(msgid));
   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
     warning ("(near initialization for `%s')", ofwhat);
@@ -4704,7 +4738,7 @@ digest_init (type, init, require_constant, constructor_constant)
 
   if (type == error_mark_node
       || init == error_mark_node
-      || TREE_TYPE (init)  == error_mark_node)
+      || TREE_TYPE (init) == error_mark_node)
     return error_mark_node;
 
   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
@@ -4783,8 +4817,19 @@ digest_init (type, init, require_constant, constructor_constant)
     {
       if (code == POINTER_TYPE)
        inside_init = default_function_array_conversion (inside_init);
-      else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
-              && TREE_CODE (inside_init) != CONSTRUCTOR)
+
+      if (require_constant && !flag_isoc99
+         && TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
+       {
+         /* As an extension, allow initializing objects with static storage
+            duration with compound literals (which are then treated just as
+            the brace enclosed list they contain).  */
+         tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
+         inside_init = DECL_INITIAL (decl);
+       }
+
+      if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
+         && TREE_CODE (inside_init) != CONSTRUCTOR)
        {
          error_init ("array initialized from non-constant array expression");
          return error_mark_node;
@@ -5259,6 +5304,13 @@ really_start_incremental_init (type)
              && TYPE_SIZE (constructor_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
+            checking errors as well by setting a safe value.  */
+         if (constructor_max_index
+             && TREE_CODE (constructor_max_index) != INTEGER_CST)
+           constructor_max_index = build_int_2 (-1, -1);
+
          constructor_index
            = convert (bitsizetype,
                       TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
@@ -5426,6 +5478,13 @@ push_init_level (implicit)
              && TYPE_SIZE (constructor_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
+            checking errors as well by setting a safe value.  */
+         if (constructor_max_index
+             && TREE_CODE (constructor_max_index) != INTEGER_CST)
+           constructor_max_index = build_int_2 (-1, -1);
+
          constructor_index
            = convert (bitsizetype, 
                       TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
@@ -5505,7 +5564,7 @@ pop_init_level (implicit)
       else
        /* Zero-length arrays are no longer special, so we should no longer
           get here.  */
-       abort();
+       abort ();
     }
 
   /* Warn when some struct elements are implicitly initialized to zero.  */
@@ -6226,6 +6285,16 @@ output_init_element (value, type, field, pending)
                         TYPE_MAIN_VARIANT (type))))
     value = default_conversion (value);
 
+  if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
+      && require_constant_value && !flag_isoc99 && pending)
+    {
+      /* As an extension, allow initializing objects with static storage
+        duration with compound literals (which are then treated just as
+        the brace enclosed list they contain).  */
+      tree decl = COMPOUND_LITERAL_EXPR_DECL (value);
+      value = DECL_INITIAL (decl);
+    }
+
   if (value == error_mark_node)
     constructor_erroneous = 1;
   else if (!TREE_CONSTANT (value))
@@ -6256,6 +6325,8 @@ output_init_element (value, type, field, pending)
                  || TREE_CHAIN (field)))))
     return;
 
+  value = digest_init (type, value, require_constant_value,
+                      require_constant_elements);
   if (value == error_mark_node)
     {
       constructor_erroneous = 1;
@@ -6272,9 +6343,7 @@ output_init_element (value, type, field, pending)
          && tree_int_cst_lt (field, constructor_unfilled_index))
        set_nonincremental_init ();
 
-      add_pending_init (field,
-                       digest_init (type, value, require_constant_value, 
-                                    require_constant_elements));
+      add_pending_init (field, value);
       return;
     }
   else if (TREE_CODE (constructor_type) == RECORD_TYPE
@@ -6300,9 +6369,7 @@ output_init_element (value, type, field, pending)
            }
        }
 
-      add_pending_init (field,
-                       digest_init (type, value, require_constant_value, 
-                                    require_constant_elements));
+      add_pending_init (field, value);
       return;
     }
   else if (TREE_CODE (constructor_type) == UNION_TYPE
@@ -6321,10 +6388,7 @@ output_init_element (value, type, field, pending)
   if (field && TREE_CODE (field) == INTEGER_CST)
     field = copy_node (field);
   constructor_elements
-    = tree_cons (field, digest_init (type, value,
-                                    require_constant_value, 
-                                    require_constant_elements),
-                constructor_elements);
+    = tree_cons (field, value, constructor_elements);
 
   /* Advance the variable that indicates sequential elements output.  */
   if (TREE_CODE (constructor_type) == ARRAY_TYPE)
@@ -6557,7 +6621,14 @@ process_init_element (value)
 
   /* In the case of [LO ... HI] = VALUE, only evaluate VALUE once.  */
   if (constructor_range_stack)
-    value = save_expr (value);
+    {
+      /* If value is a compound literal and we'll be just using its
+        content, don't put it into a SAVE_EXPR.  */
+      if (TREE_CODE (value) != COMPOUND_LITERAL_EXPR
+         || !require_constant_value
+         || flag_isoc99)
+       value = save_expr (value);
+    }
 
   while (1)
     {
@@ -7108,7 +7179,6 @@ c_start_case (exp)
        }
       else
        {
-         tree index;
          type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
 
          if (warn_traditional && !in_system_header
@@ -7118,14 +7188,6 @@ c_start_case (exp)
 
          exp = default_conversion (exp);
          type = TREE_TYPE (exp);
-         index = get_unwidened (exp, NULL_TREE);
-         /* We can't strip a conversion from a signed type to an
-            unsigned, because if we did, int_fits_type_p would do the
-            wrong thing when checking case values for being in range,
-            and it's too hard to do the right thing.  */
-         if (TREE_UNSIGNED (TREE_TYPE (exp))
-             == TREE_UNSIGNED (TREE_TYPE (index)))
-           exp = index;
        }
     }