This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C patch]: check type directly
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: "Joseph S. Myers" <jsm at polyomino dot org dot uk>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 04 Aug 2004 14:32:13 +0100
- Subject: [C patch]: check type directly
- Organization: CodeSourcery LLC
Hi,
this patch changes narrowest_(un)signed_type to do range checking directly,
rather than build a temporary const and several highlevel comparisons. This
is part of the move to sharing int_cst nodes.
booted & tested on i686-pc-linux-gnu, ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2004-08-03 Nathan Sidwell <nathan@codesourcery.com>
* c-lex.c (narrowest_unsigned_type, narrowest_signed_type): Take
low/high pair. Do range checking directly.
(interpret_integer): Adjust.
Index: c-lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lex.c,v
retrieving revision 1.229
diff -c -3 -p -r1.229 c-lex.c
*** c-lex.c 26 Jul 2004 00:29:40 -0000 1.229
--- c-lex.c 4 Aug 2004 08:52:01 -0000
*************** int c_lex_string_translate = 1;
*** 62,71 ****
static tree interpret_integer (const cpp_token *, unsigned int);
static tree interpret_float (const cpp_token *, unsigned int);
! static enum integer_type_kind
! narrowest_unsigned_type (tree, unsigned int);
! static enum integer_type_kind
! narrowest_signed_type (tree, unsigned int);
static enum cpp_ttype lex_string (const cpp_token *, tree *, bool);
static tree lex_charconst (const cpp_token *);
static void update_header_times (const char *);
--- 62,71 ----
static tree interpret_integer (const cpp_token *, unsigned int);
static tree interpret_float (const cpp_token *, unsigned int);
! static enum integer_type_kind narrowest_unsigned_type
! (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
! static enum integer_type_kind narrowest_signed_type
! (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
static enum cpp_ttype lex_string (const cpp_token *, tree *, bool);
static tree lex_charconst (const cpp_token *);
static void update_header_times (const char *);
*************** c_lex (tree *value)
*** 461,470 ****
}
/* Returns the narrowest C-visible unsigned type, starting with the
! minimum specified by FLAGS, that can fit VALUE, or itk_none if
there isn't one. */
static enum integer_type_kind
! narrowest_unsigned_type (tree value, unsigned int flags)
{
enum integer_type_kind itk;
--- 461,473 ----
}
/* Returns the narrowest C-visible unsigned type, starting with the
! minimum specified by FLAGS, that can fit HIGH:LOW, or itk_none if
there isn't one. */
+
static enum integer_type_kind
! narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
! unsigned HOST_WIDE_INT high,
! unsigned int flags)
{
enum integer_type_kind itk;
*************** narrowest_unsigned_type (tree value, uns
*** 475,494 ****
else
itk = itk_unsigned_long_long;
- /* int_fits_type_p must think the type of its first argument is
- wider than its second argument, or it won't do the proper check. */
- TREE_TYPE (value) = widest_unsigned_literal_type_node;
-
for (; itk < itk_none; itk += 2 /* skip unsigned types */)
! if (int_fits_type_p (value, integer_types[itk]))
! return itk;
return itk_none;
}
/* Ditto, but narrowest signed type. */
static enum integer_type_kind
! narrowest_signed_type (tree value, unsigned int flags)
{
enum integer_type_kind itk;
--- 478,500 ----
else
itk = itk_unsigned_long_long;
for (; itk < itk_none; itk += 2 /* skip unsigned types */)
! {
! tree upper = TYPE_MAX_VALUE (integer_types[itk]);
!
! if ((unsigned HOST_WIDE_INT)TREE_INT_CST_HIGH (upper) > high
! || ((unsigned HOST_WIDE_INT)TREE_INT_CST_HIGH (upper) == high
! && TREE_INT_CST_LOW (upper) >= low))
! return itk;
! }
return itk_none;
}
/* Ditto, but narrowest signed type. */
static enum integer_type_kind
! narrowest_signed_type (unsigned HOST_WIDE_INT low,
! unsigned HOST_WIDE_INT high, unsigned int flags)
{
enum integer_type_kind itk;
*************** narrowest_signed_type (tree value, unsig
*** 499,511 ****
else
itk = itk_long_long;
- /* int_fits_type_p must think the type of its first argument is
- wider than its second argument, or it won't do the proper check. */
- TREE_TYPE (value) = widest_unsigned_literal_type_node;
for (; itk < itk_none; itk += 2 /* skip signed types */)
! if (int_fits_type_p (value, integer_types[itk]))
! return itk;
return itk_none;
}
--- 505,520 ----
else
itk = itk_long_long;
for (; itk < itk_none; itk += 2 /* skip signed types */)
! {
! tree upper = TYPE_MAX_VALUE (integer_types[itk]);
!
! if ((unsigned HOST_WIDE_INT)TREE_INT_CST_HIGH (upper) > high
! || ((unsigned HOST_WIDE_INT)TREE_INT_CST_HIGH (upper) == high
! && TREE_INT_CST_LOW (upper) >= low))
! return itk;
! }
return itk_none;
}
*************** interpret_integer (const cpp_token *toke
*** 521,538 ****
integer = cpp_interpret_integer (parse_in, token, flags);
integer = cpp_num_sign_extend (integer, options->precision);
- value = build_int_2 (integer.low, integer.high);
/* The type of a constant with a U suffix is straightforward. */
if (flags & CPP_N_UNSIGNED)
! itk = narrowest_unsigned_type (value, flags);
else
{
/* The type of a potentially-signed integer constant varies
depending on the base it's in, the standard in use, and the
length suffixes. */
! enum integer_type_kind itk_u = narrowest_unsigned_type (value, flags);
! enum integer_type_kind itk_s = narrowest_signed_type (value, flags);
/* In both C89 and C99, octal and hex constants may be signed or
unsigned, whichever fits tighter. We do not warn about this
--- 530,548 ----
integer = cpp_interpret_integer (parse_in, token, flags);
integer = cpp_num_sign_extend (integer, options->precision);
/* The type of a constant with a U suffix is straightforward. */
if (flags & CPP_N_UNSIGNED)
! itk = narrowest_unsigned_type (integer.low, integer.high, flags);
else
{
/* The type of a potentially-signed integer constant varies
depending on the base it's in, the standard in use, and the
length suffixes. */
! enum integer_type_kind itk_u
! = narrowest_unsigned_type (integer.low, integer.high, flags);
! enum integer_type_kind itk_s
! = narrowest_signed_type (integer.low, integer.high, flags);
/* In both C89 and C99, octal and hex constants may be signed or
unsigned, whichever fits tighter. We do not warn about this
*************** interpret_integer (const cpp_token *toke
*** 578,588 ****
pedwarn ("integer constant is too large for \"%s\" type",
(flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
TREE_TYPE (value) = type;
/* Convert imaginary to a complex type. */
if (flags & CPP_N_IMAGINARY)
! value = build_complex (NULL_TREE, convert (type, integer_zero_node), value);
return value;
}
--- 588,600 ----
pedwarn ("integer constant is too large for \"%s\" type",
(flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
+ value = build_int_2 (integer.low, integer.high);
TREE_TYPE (value) = type;
/* Convert imaginary to a complex type. */
if (flags & CPP_N_IMAGINARY)
! value = build_complex (NULL_TREE,
! convert (type, integer_zero_node), value);
return value;
}