This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C patch]: check type directly


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;
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]