#include "tm.h"
#include "intl.h"
#include "tree.h"
+#include "fold-const.h"
+#include "stor-layout.h"
+#include "calls.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "varasm.h"
+#include "trans-mem.h"
#include "flags.h"
#include "c-pragma.h"
#include "ggc.h"
for (saved = TREE_PURPOSE (stack); saved; saved = TREE_CHAIN (saved))
{
tree decl = TREE_PURPOSE (saved);
- unsigned ix = tree_to_hwi (TREE_VALUE (saved));
+ unsigned ix = TREE_INT_CST_LOW (TREE_VALUE (saved));
*fname_vars[ix].decl = decl;
}
}
/* Checks if expression EXPR of real/integer type cannot be converted
- to the real/integer type TYPE. Function returns true when:
+ to the real/integer type TYPE. Function returns non-zero when:
* EXPR is a constant which cannot be exactly converted to TYPE
* EXPR is not a constant and size of EXPR's type > than size of TYPE,
for EXPR type and TYPE being both integers or both real.
* EXPR is not a constant of integer type which cannot be
exactly converted to real type.
Function allows conversions between types of different signedness and
- does not return true in that case. Function can produce signedness
- warnings if PRODUCE_WARNS is true. */
-bool
+ can return SAFE_CONVERSION (zero) in that case. Function can produce
+ signedness warnings if PRODUCE_WARNS is true. */
+enum conversion_safety
unsafe_conversion_p (tree type, tree expr, bool produce_warns)
{
- bool give_warning = false;
+ enum conversion_safety give_warning = SAFE_CONVERSION; /* is 0 or false */
tree expr_type = TREE_TYPE (expr);
location_t loc = EXPR_LOC_OR_HERE (expr);
&& TREE_CODE (type) == INTEGER_TYPE)
{
if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (expr_type)))
- give_warning = true;
+ give_warning = UNSAFE_REAL;
}
/* Warn for an integer constant that does not fit into integer type. */
else if (TREE_CODE (expr_type) == INTEGER_TYPE
" constant value to negative integer");
}
else
- give_warning = true;
+ give_warning = UNSAFE_OTHER;
}
else if (TREE_CODE (type) == REAL_TYPE)
{
{
REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr);
if (!exact_real_truncate (TYPE_MODE (type), &a))
- give_warning = true;
+ give_warning = UNSAFE_REAL;
}
/* Warn for a real constant that does not fit into a smaller
real type. */
{
REAL_VALUE_TYPE a = TREE_REAL_CST (expr);
if (!exact_real_truncate (TYPE_MODE (type), &a))
- give_warning = true;
+ give_warning = UNSAFE_REAL;
}
}
}
/* Warn for real types converted to integer types. */
if (TREE_CODE (expr_type) == REAL_TYPE
&& TREE_CODE (type) == INTEGER_TYPE)
- give_warning = true;
+ give_warning = UNSAFE_REAL;
else if (TREE_CODE (expr_type) == INTEGER_TYPE
&& TREE_CODE (type) == INTEGER_TYPE)
&& int_fits_type_p (op1, c_common_signed_type (type))
&& int_fits_type_p (op1,
c_common_unsigned_type (type))))
- return false;
+ return SAFE_CONVERSION;
/* If constant is unsigned and fits in the target
type, then the result will also fit. */
else if ((TREE_CODE (op0) == INTEGER_CST
|| (TREE_CODE (op1) == INTEGER_CST
&& unsigned1
&& int_fits_type_p (op1, type)))
- return false;
+ return SAFE_CONVERSION;
}
}
/* Warn for integer types converted to smaller integer types. */
if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
- give_warning = true;
+ give_warning = UNSAFE_OTHER;
/* When they are the same width but different signedness,
then the value may change. */
if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
|| !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
- give_warning = true;
+ give_warning = UNSAFE_OTHER;
}
/* Warn for real types converted to smaller real types. */
else if (TREE_CODE (expr_type) == REAL_TYPE
&& TREE_CODE (type) == REAL_TYPE
&& TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
- give_warning = true;
+ give_warning = UNSAFE_REAL;
}
return give_warning;
{
tree expr_type = TREE_TYPE (expr);
location_t loc = EXPR_LOC_OR_HERE (expr);
+ enum conversion_safety conversion_kind;
- if (!warn_conversion && !warn_sign_conversion)
+ if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
return;
switch (TREE_CODE (expr))
case REAL_CST:
case INTEGER_CST:
- if (unsafe_conversion_p (type, expr, true))
+ conversion_kind = unsafe_conversion_p (type, expr, true);
+ if (conversion_kind == UNSAFE_REAL)
+ warning_at (loc, OPT_Wfloat_conversion,
+ "conversion to %qT alters %qT constant value",
+ type, expr_type);
+ else if (conversion_kind)
warning_at (loc, OPT_Wconversion,
"conversion to %qT alters %qT constant value",
type, expr_type);
}
default: /* 'expr' is not a constant. */
- if (unsafe_conversion_p (type, expr, true))
+ conversion_kind = unsafe_conversion_p (type, expr, true);
+ if (conversion_kind == UNSAFE_REAL)
+ warning_at (loc, OPT_Wfloat_conversion,
+ "conversion to %qT from %qT may alter its value",
+ type, expr_type);
+ else if (conversion_kind)
warning_at (loc, OPT_Wconversion,
"conversion to %qT from %qT may alter its value",
type, expr_type);
if (TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
size = 0;
else
- size = tree_to_hwi (TYPE_SIZE (t));
+ size = TREE_INT_CST_LOW (TYPE_SIZE (t));
return ((size << 24) | (n_elements << shift));
}
{
char buf[WIDE_INT_PRINT_BUFFER_SIZE];
- if (tree_fits_hwi_p (key, TYPE_SIGN (type)))
- print_dec (key, buf, TYPE_SIGN (type));
+ if (tree_fits_uhwi_p (key))
+ print_dec (key, buf, UNSIGNED);
+ else if (tree_fits_shwi_p (key))
+ print_dec (key, buf, SIGNED);
else
print_hex (key, buf);
if (TREE_VALUE (attr))
{
tree p = TREE_VALUE (TREE_VALUE (attr));
- pos = tree_to_hwi (p);
+ pos = TREE_INT_CST_LOW (p);
}
/* The sentinel must be one of the varargs, i.e.
/* Verify the arg number is a small constant. */
if (cst_fits_uhwi_p (arg_num_expr))
{
- *valp = tree_to_hwi (arg_num_expr);
+ *valp = TREE_INT_CST_LOW (arg_num_expr);
return true;
}
else
if (TREE_CODE (value) == INTEGER_CST)
{
char buffer[20];
- sprintf (buffer, "-O%ld", (long) tree_to_hwi (value));
+ sprintf (buffer, "-O%ld", (long) TREE_INT_CST_LOW (value));
vec_safe_push (optimize_args, ggc_strdup (buffer));
}
to be valid. */
format_num_expr = TREE_VALUE (TREE_VALUE (attrs));
- gcc_assert (tree_fits_uhwi_p (format_num_expr));
-
format_num = tree_to_uhwi (format_num_expr);
for (inner_arg = first_call_expr_arg (param, &iter), i = 1;
|| token_type == CPP_CHAR16
|| token_type == CPP_CHAR32)
{
- unsigned int val = tree_to_hwi (value);
+ unsigned int val = TREE_INT_CST_LOW (value);
const char *prefix;
switch (token_type)
{
error ("size of array is too large");
/* If we proceed with the array type as it is, we'll eventually
- crash in tree_to_uhwi(). */
+ crash in tree_to_[su]hwi(). */
type = error_mark_node;
}
if (TREE_CODE (index) == INTEGER_CST)
if (!tree_fits_uhwi_p (index)
- || ((unsigned HOST_WIDE_INT) tree_to_uhwi (index)
- >= TYPE_VECTOR_SUBPARTS (type)))
+ || tree_to_uhwi (index) >= TYPE_VECTOR_SUBPARTS (type))
warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
c_common_mark_addressable_vec (*vecp);