OSDN Git Service

gcc/fortran:
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index eca1066..2151f97 100644 (file)
@@ -1876,6 +1876,19 @@ build_indirect_ref (tree ptr, const char *errorstring)
 
   if (TREE_CODE (type) == POINTER_TYPE)
     {
+      if (TREE_CODE (pointer) == CONVERT_EXPR
+          || TREE_CODE (pointer) == NOP_EXPR
+          || TREE_CODE (pointer) == VIEW_CONVERT_EXPR)
+       {
+         /* If a warning is issued, mark it to avoid duplicates from
+            the backend.  This only needs to be done at
+            warn_strict_aliasing > 2.  */
+         if (warn_strict_aliasing > 2)
+           if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (pointer, 0)),
+                                        type, TREE_OPERAND (pointer, 0)))
+             TREE_NO_WARNING (pointer) = 1;
+       }
+
       if (TREE_CODE (pointer) == ADDR_EXPR
          && (TREE_TYPE (TREE_OPERAND (pointer, 0))
              == TREE_TYPE (type)))
@@ -1910,7 +1923,7 @@ build_indirect_ref (tree ptr, const char *errorstring)
        }
     }
   else if (TREE_CODE (pointer) != ERROR_MARK)
-    error ("invalid type argument of %qs", errorstring);
+    error ("invalid type argument of %qs (have %qT)", errorstring, type);
   return error_mark_node;
 }
 
@@ -2077,9 +2090,13 @@ build_external_ref (tree id, int fun, location_t loc)
   if (TREE_DEPRECATED (ref))
     warn_deprecated_use (ref);
 
-  if (!skip_evaluation)
-    assemble_external (ref);
-  TREE_USED (ref) = 1;
+  /* Recursive call does not count as usage.  */
+  if (ref != current_function_decl) 
+    {
+      if (!skip_evaluation)
+       assemble_external (ref);
+      TREE_USED (ref) = 1;
+    }
 
   if (TREE_CODE (ref) == FUNCTION_DECL && !in_alignof)
     {
@@ -2377,6 +2394,8 @@ convert_arguments (int nargs, tree *argarray,
 {
   tree typetail, valtail;
   int parmnum;
+  const bool type_generic = fundecl
+    && lookup_attribute ("type generic", TYPE_ATTRIBUTES(TREE_TYPE (fundecl)));
   tree selector;
 
   /* Change pointer to function to the function itself for
@@ -2568,8 +2587,13 @@ convert_arguments (int nargs, tree *argarray,
               && (TYPE_PRECISION (TREE_TYPE (val))
                   < TYPE_PRECISION (double_type_node))
               && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (val))))
-       /* Convert `float' to `double'.  */
-       argarray[parmnum] = convert (double_type_node, val);
+        {
+         if (type_generic)
+           argarray[parmnum] = val;
+         else
+           /* Convert `float' to `double'.  */
+           argarray[parmnum] = convert (double_type_node, val);
+       }
       else if ((invalid_func_diag =
                targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val)))
        {
@@ -2649,11 +2673,11 @@ parser_build_binary_op (enum tree_code code, struct c_expr arg1,
     {
       if ((code1 == STRING_CST && !integer_zerop (arg2.value))
          || (code2 == STRING_CST && !integer_zerop (arg1.value)))
-       warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour");
+       warning (OPT_Waddress, "comparison with string literal results in unspecified behavior");
     }
   else if (TREE_CODE_CLASS (code) == tcc_comparison
           && (code1 == STRING_CST || code2 == STRING_CST))
-    warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour");
+    warning (OPT_Waddress, "comparison with string literal results in unspecified behavior");
 
   if (TREE_OVERFLOW_P (result.value) 
       && !TREE_OVERFLOW_P (arg1.value) 
@@ -2895,8 +2919,11 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
          arg = stabilize_reference (arg);
          real = build_unary_op (REALPART_EXPR, arg, 1);
          imag = build_unary_op (IMAGPART_EXPR, arg, 1);
+         real = build_unary_op (code, real, 1);
+         if (real == error_mark_node || imag == error_mark_node)
+           return error_mark_node;
          return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
-                        build_unary_op (code, real, 1), imag);
+                        real, imag);
        }
 
       /* Report invalid types.  */
@@ -2943,11 +2970,13 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
              }
 
            inc = c_size_in_bytes (TREE_TYPE (result_type));
+           inc = fold_convert (sizetype, inc);
          }
        else
-         inc = integer_one_node;
-
-       inc = convert (argtype, inc);
+         {
+           inc = integer_one_node;
+           inc = convert (argtype, inc);
+         }
 
        /* Complain about anything else that is not a true lvalue.  */
        if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
@@ -3035,10 +3064,10 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
       if (val && TREE_CODE (val) == INDIRECT_REF
           && TREE_CONSTANT (TREE_OPERAND (val, 0)))
        {
-         tree op0 = fold_convert (argtype, fold_offsetof (arg, val)), op1;
+         tree op0 = fold_convert (sizetype, fold_offsetof (arg, val)), op1;
 
          op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
-         return fold_build2 (PLUS_EXPR, argtype, op0, op1);
+         return fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0);
        }
 
       val = build1 (ADDR_EXPR, argtype, arg);
@@ -3402,7 +3431,8 @@ build_compound_expr (tree expr1, tree expr2)
                       || TREE_CODE (TREE_OPERAND (expr1, 1)) == NOP_EXPR))
            ; /* (void) a, (void) b, c */
          else
-           warning (0, "left-hand operand of comma expression has no effect");
+           warning (OPT_Wunused_value, 
+                    "left-hand operand of comma expression has no effect");
        }
     }
 
@@ -3573,7 +3603,8 @@ build_c_cast (tree type, tree expr)
        warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
                 "of different size");
 
-      strict_aliasing_warning (otype, type, expr);
+      if (warn_strict_aliasing <= 2)
+        strict_aliasing_warning (otype, type, expr);
 
       /* If pedantic, warn for conversions between function and object
         pointer types, except for converting a null pointer constant
@@ -3896,10 +3927,16 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
               || coder == BOOLEAN_TYPE))
     return convert_and_check (type, rhs);
 
+  /* Aggregates in different TUs might need conversion.  */
+  if ((codel == RECORD_TYPE || codel == UNION_TYPE)
+      && codel == coder
+      && comptypes (type, rhstype))
+    return convert_and_check (type, rhs);
+
   /* Conversion to a transparent union from its member types.
      This applies only to function arguments.  */
-  else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
-          && (errtype == ic_argpass || errtype == ic_argpass_nonproto))
+  if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
+      && (errtype == ic_argpass || errtype == ic_argpass_nonproto))
     {
       tree memb, marginal_memb = NULL_TREE;
 
@@ -4221,37 +4258,6 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
 
   return error_mark_node;
 }
-
-/* Convert VALUE for assignment into inlined parameter PARM.  ARGNUM
-   is used for error and warning reporting and indicates which argument
-   is being processed.  */
-
-tree
-c_convert_parm_for_inlining (tree parm, tree value, tree fn, int argnum)
-{
-  tree ret, type;
-
-  /* If FN was prototyped at the call site, the value has been converted
-     already in convert_arguments.
-     However, we might see a prototype now that was not in place when
-     the function call was seen, so check that the VALUE actually matches
-     PARM before taking an early exit.  */
-  if (!value
-      || (TYPE_ARG_TYPES (TREE_TYPE (fn))
-         && (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
-             == TYPE_MAIN_VARIANT (TREE_TYPE (value)))))
-    return value;
-
-  type = TREE_TYPE (parm);
-  ret = convert_for_assignment (type, value,
-                               ic_argpass_nonproto, fn,
-                               fn, argnum);
-  if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
-      && INTEGRAL_TYPE_P (type)
-      && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
-    ret = default_conversion (ret);
-  return ret;
-}
 \f
 /* If VALUE is a compound expr all of whose expressions are constant, then
    return its value.  Otherwise, return error_mark_node.
@@ -7229,7 +7235,7 @@ c_finish_if_stmt (location_t if_locus, tree cond, tree then_block,
                  &if_locus);
     }
 
-  empty_body_warning (then_block, else_block);
+  empty_if_body_warning (then_block, else_block);
 
   stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block);
   SET_EXPR_LOCATION (stmt, if_locus);
@@ -8114,7 +8120,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
          || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
                                                    TREE_TYPE (type1))))
     {
-      binary_op_error (code);
+      binary_op_error (code, type0, type1);
       return error_mark_node;
     }
 
@@ -8127,7 +8133,11 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
       int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
 
       if (shorten || common || short_compare)
-       result_type = c_common_type (type0, type1);
+       {
+         result_type = c_common_type (type0, type1);
+         if (result_type == error_mark_node)
+           return error_mark_node;
+       }
 
       /* For certain operations (which identify themselves by shorten != 0)
         if both args were extended from the same smaller type,
@@ -8410,7 +8420,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
 
   if (!result_type)
     {
-      binary_op_error (code);
+      binary_op_error (code, TREE_TYPE (op0), TREE_TYPE (op1));
       return error_mark_node;
     }