OSDN Git Service

* c-cppbuiltin.c (builtin_define_with_value_n): Fix whitespace.
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index 1bca1bf..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"
@@ -572,6 +574,12 @@ comptypes (type1, type2)
        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;
     }
@@ -1187,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);
@@ -1213,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;
        }
@@ -1470,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);
@@ -1479,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
@@ -2593,13 +2599,13 @@ c_tree_expr_nonnegative_p (t)
 {
   if (TREE_CODE (t) == STMT_EXPR)
     {
-      t=COMPOUND_BODY (STMT_EXPR_STMT (t));
+      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);
+        t = TREE_CHAIN (t);
       return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
     }
   return tree_expr_nonnegative_p (t);
@@ -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
@@ -3649,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);
@@ -3759,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.  */
@@ -4054,6 +4070,11 @@ 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
@@ -4292,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.  */
 
@@ -4313,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'");
@@ -5118,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;
@@ -5176,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)
@@ -5228,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
@@ -5366,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)
@@ -6580,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);
@@ -6819,9 +6870,9 @@ simple_asm_stmt (expr)
     {
       tree stmt;
 
-      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;
     }
@@ -6919,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.  */
@@ -7130,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");
@@ -7151,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;