OSDN Git Service

* tree-vectorizer.h (vect_get_single_scalar_iteraion_cost): Fix typo.
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index 689423e..ac37751 100644 (file)
@@ -3527,7 +3527,13 @@ build_unary_op (location_t location,
                    "wrong type argument to unary exclamation mark");
          return error_mark_node;
        }
-      arg = c_objc_common_truthvalue_conversion (location, arg);
+      if (int_operands)
+       {
+         arg = c_objc_common_truthvalue_conversion (location, xarg);
+         arg = remove_c_maybe_const_expr (arg);
+       }
+      else
+       arg = c_objc_common_truthvalue_conversion (location, arg);
       ret = invert_truthvalue_loc (location, arg);
       /* If the TRUTH_NOT_EXPR has been folded, reset the location.  */
       if (EXPR_P (ret) && EXPR_HAS_LOCATION (ret))
@@ -3802,11 +3808,7 @@ build_unary_op (location_t location,
       if (val && TREE_CODE (val) == INDIRECT_REF
           && TREE_CONSTANT (TREE_OPERAND (val, 0)))
        {
-         tree op0 = fold_convert_loc (location, sizetype,
-                                      fold_offsetof (arg, val)), op1;
-
-         op1 = fold_convert_loc (location, argtype, TREE_OPERAND (val, 0));
-         ret = fold_build2_loc (location, POINTER_PLUS_EXPR, argtype, op1, op0);
+         ret = fold_convert_loc (location, argtype, fold_offsetof_1 (arg));
          goto return_build_unary_op;
        }
 
@@ -4319,6 +4321,11 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
     ret = fold_build3_loc (colon_loc, COND_EXPR, result_type, ifexp, op1, op2);
   else
     {
+      if (int_operands)
+       {
+         op1 = remove_c_maybe_const_expr (op1);
+         op2 = remove_c_maybe_const_expr (op2);
+       }
       ret = build3 (COND_EXPR, result_type, ifexp, op1, op2);
       if (int_operands)
        ret = note_integer_operands (ret);
@@ -4754,8 +4761,11 @@ c_cast_expr (location_t loc, struct c_type_name *type_name, tree expr)
   ret = build_c_cast (loc, type, expr);
   if (type_expr)
     {
+      bool inner_expr_const = true;
+      ret = c_fully_fold (ret, require_constant_value, &inner_expr_const);
       ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret), type_expr, ret);
-      C_MAYBE_CONST_EXPR_NON_CONST (ret) = !type_expr_const;
+      C_MAYBE_CONST_EXPR_NON_CONST (ret) = !(type_expr_const
+                                            && inner_expr_const);
       SET_EXPR_LOCATION (ret, loc);
     }
 
@@ -5773,11 +5783,13 @@ store_init_value (location_t init_loc, tree decl, tree init, tree origtype)
              /* 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.  */
+             tree etype = strip_array_types (TREE_TYPE (decl));
              type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
-             TREE_TYPE (decl) = type;
              TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (cldecl));
              layout_type (type);
              layout_decl (cldecl, 0);
+             TREE_TYPE (decl)
+               = c_build_qualified_type (type, TYPE_QUALS (etype));
            }
        }
     }
@@ -9093,7 +9105,11 @@ c_process_expr_stmt (location_t loc, tree expr)
   exprv = expr;
   while (TREE_CODE (exprv) == COMPOUND_EXPR)
     exprv = TREE_OPERAND (exprv, 1);
-  if (DECL_P (exprv) || handled_component_p (exprv))
+  while (CONVERT_EXPR_P (exprv))
+    exprv = TREE_OPERAND (exprv, 0);
+  if (DECL_P (exprv)
+      || handled_component_p (exprv)
+      || TREE_CODE (exprv) == ADDR_EXPR)
     mark_exp_read (exprv);
 
   /* If the expression is not of a type to which we cannot assign a line
@@ -9626,8 +9642,20 @@ build_binary_op (location_t location, enum tree_code code,
             but that does not mean the operands should be
             converted to ints!  */
          result_type = integer_type_node;
-         op0 = c_common_truthvalue_conversion (location, op0);
-         op1 = c_common_truthvalue_conversion (location, op1);
+         if (op0_int_operands)
+           {
+             op0 = c_objc_common_truthvalue_conversion (location, orig_op0);
+             op0 = remove_c_maybe_const_expr (op0);
+           }
+         else
+           op0 = c_objc_common_truthvalue_conversion (location, op0);
+         if (op1_int_operands)
+           {
+             op1 = c_objc_common_truthvalue_conversion (location, orig_op1);
+             op1 = remove_c_maybe_const_expr (op1);
+           }
+         else
+           op1 = c_objc_common_truthvalue_conversion (location, op1);
          converted = 1;
          boolean_op = true;
        }
@@ -10031,6 +10059,7 @@ build_binary_op (location_t location, enum tree_code code,
                {
                case MULT_EXPR:
                case TRUNC_DIV_EXPR:
+                 op1 = c_save_expr (op1);
                  imag = build2 (resultcode, real_type, imag, op1);
                  /* Fall through.  */
                case PLUS_EXPR:
@@ -10051,6 +10080,7 @@ build_binary_op (location_t location, enum tree_code code,
              switch (code)
                {
                case MULT_EXPR:
+                 op0 = c_save_expr (op0);
                  imag = build2 (resultcode, real_type, op0, imag);
                  /* Fall through.  */
                case PLUS_EXPR:
@@ -10176,7 +10206,7 @@ build_binary_op (location_t location, enum tree_code code,
                warn_for_sign_compare (location, orig_op0_folded,
                                       orig_op1_folded, op0, op1,
                                       result_type, resultcode);
-             if (!in_late_binary_op)
+             if (!in_late_binary_op && !int_operands)
                {
                  if (!op0_maybe_const || TREE_CODE (op0) != INTEGER_CST)
                    op0 = c_wrap_maybe_const (op0, !op0_maybe_const);
@@ -10270,6 +10300,10 @@ c_objc_common_truthvalue_conversion (location_t location, tree expr)
       error_at (location, "used union type value where scalar is required");
       return error_mark_node;
 
+    case VOID_TYPE:
+      error_at (location, "void value not ignored as it ought to be");
+      return error_mark_node;
+
     case FUNCTION_TYPE:
       gcc_unreachable ();
 
@@ -10279,12 +10313,17 @@ c_objc_common_truthvalue_conversion (location_t location, tree expr)
 
   int_const = (TREE_CODE (expr) == INTEGER_CST && !TREE_OVERFLOW (expr));
   int_operands = EXPR_INT_CONST_OPERANDS (expr);
-  if (int_operands)
-    expr = remove_c_maybe_const_expr (expr);
-
-  /* ??? Should we also give an error for void and vectors rather than
-     leaving those to give errors later?  */
-  expr = c_common_truthvalue_conversion (location, expr);
+  if (int_operands && TREE_CODE (expr) != INTEGER_CST)
+    {
+      expr = remove_c_maybe_const_expr (expr);
+      expr = build2 (NE_EXPR, integer_type_node, expr,
+                    convert (TREE_TYPE (expr), integer_zero_node));
+      expr = note_integer_operands (expr);
+    }
+  else
+    /* ??? Should we also give an error for vectors rather than leaving
+       those to give errors later?  */
+    expr = c_common_truthvalue_conversion (location, expr);
 
   if (TREE_CODE (expr) == INTEGER_CST && int_operands && !int_const)
     {