mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 09:58:19 +08:00
* c-exp.y (parse_number): Check for overflow regardless of range
checking. Fix overflow check to use unsigned LONGEST, not unsigned int. * c-exp.y (parse_number): Make it so that integer constants are builtin_type_long_long if builtin_type_long isn't big enough or if an "LL" suffix is used. Properly handle "UL" or "LU" suffixes.
This commit is contained in:
@ -1,5 +1,13 @@
|
|||||||
Sat Jan 15 10:20:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
|
Sat Jan 15 10:20:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
|
||||||
|
|
||||||
|
* c-exp.y (parse_number): Check for overflow regardless of range
|
||||||
|
checking. Fix overflow check to use unsigned LONGEST, not
|
||||||
|
unsigned int.
|
||||||
|
|
||||||
|
* c-exp.y (parse_number): Make it so that integer constants are
|
||||||
|
builtin_type_long_long if builtin_type_long isn't big enough or if
|
||||||
|
an "LL" suffix is used. Properly handle "UL" or "LU" suffixes.
|
||||||
|
|
||||||
* c-typeprint.c (c_type_print_varspec_suffix, case TYPE_CODE_FUNC):
|
* c-typeprint.c (c_type_print_varspec_suffix, case TYPE_CODE_FUNC):
|
||||||
Print our "()" first, then recurse for the target type.
|
Print our "()" first, then recurse for the target type.
|
||||||
|
|
||||||
@ -31,7 +39,6 @@ Fri Jan 14 11:06:10 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
|
|||||||
* config/nm-lynx.h: Fix child_wait prototype and include target.h.
|
* config/nm-lynx.h: Fix child_wait prototype and include target.h.
|
||||||
|
|
||||||
Fri Jan 14 14:17:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
|
Fri Jan 14 14:17:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
|
||||||
>>>>>>> 1.2118
|
|
||||||
|
|
||||||
* Makefile.in (ALLPARAM): Add config/nm-lynx.h.
|
* Makefile.in (ALLPARAM): Add config/nm-lynx.h.
|
||||||
|
|
||||||
|
126
gdb/c-exp.y
126
gdb/c-exp.y
@ -899,13 +899,22 @@ parse_number (p, len, parsed_float, putithere)
|
|||||||
int parsed_float;
|
int parsed_float;
|
||||||
YYSTYPE *putithere;
|
YYSTYPE *putithere;
|
||||||
{
|
{
|
||||||
|
/* FIXME: Shouldn't these be unsigned? We don't deal with negative values
|
||||||
|
here, and we do kind of silly things like cast to unsigned. */
|
||||||
register LONGEST n = 0;
|
register LONGEST n = 0;
|
||||||
register LONGEST prevn = 0;
|
register LONGEST prevn = 0;
|
||||||
|
|
||||||
register int i = 0;
|
register int i = 0;
|
||||||
register int c;
|
register int c;
|
||||||
register int base = input_radix;
|
register int base = input_radix;
|
||||||
int unsigned_p = 0;
|
int unsigned_p = 0;
|
||||||
|
|
||||||
|
/* Number of "L" suffixes encountered. */
|
||||||
int long_p = 0;
|
int long_p = 0;
|
||||||
|
|
||||||
|
/* We have found a "L" or "U" suffix. */
|
||||||
|
int found_suffix = 0;
|
||||||
|
|
||||||
unsigned LONGEST high_bit;
|
unsigned LONGEST high_bit;
|
||||||
struct type *signed_type;
|
struct type *signed_type;
|
||||||
struct type *unsigned_type;
|
struct type *unsigned_type;
|
||||||
@ -956,15 +965,29 @@ parse_number (p, len, parsed_float, putithere)
|
|||||||
if (c != 'l' && c != 'u')
|
if (c != 'l' && c != 'u')
|
||||||
n *= base;
|
n *= base;
|
||||||
if (c >= '0' && c <= '9')
|
if (c >= '0' && c <= '9')
|
||||||
n += i = c - '0';
|
{
|
||||||
|
if (found_suffix)
|
||||||
|
return ERROR;
|
||||||
|
n += i = c - '0';
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (base > 10 && c >= 'a' && c <= 'f')
|
if (base > 10 && c >= 'a' && c <= 'f')
|
||||||
n += i = c - 'a' + 10;
|
{
|
||||||
else if (len == 0 && c == 'l')
|
if (found_suffix)
|
||||||
long_p = 1;
|
return ERROR;
|
||||||
else if (len == 0 && c == 'u')
|
n += i = c - 'a' + 10;
|
||||||
unsigned_p = 1;
|
}
|
||||||
|
else if (c == 'l')
|
||||||
|
{
|
||||||
|
++long_p;
|
||||||
|
found_suffix = 1;
|
||||||
|
}
|
||||||
|
else if (c == 'u')
|
||||||
|
{
|
||||||
|
unsigned_p = 1;
|
||||||
|
found_suffix = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return ERROR; /* Char not a digit */
|
return ERROR; /* Char not a digit */
|
||||||
}
|
}
|
||||||
@ -972,44 +995,61 @@ parse_number (p, len, parsed_float, putithere)
|
|||||||
return ERROR; /* Invalid digit in this base */
|
return ERROR; /* Invalid digit in this base */
|
||||||
|
|
||||||
/* Portably test for overflow (only works for nonzero values, so make
|
/* Portably test for overflow (only works for nonzero values, so make
|
||||||
a second check for zero). */
|
a second check for zero). FIXME: Can't we just make n and prevn
|
||||||
if((prevn >= n) && n != 0)
|
unsigned and avoid this? */
|
||||||
unsigned_p=1; /* Try something unsigned */
|
if (c != 'l' && c != 'u' && (prevn >= n) && n != 0)
|
||||||
/* If range checking enabled, portably test for unsigned overflow. */
|
unsigned_p = 1; /* Try something unsigned */
|
||||||
if(RANGE_CHECK && n!=0)
|
|
||||||
{
|
/* Portably test for unsigned overflow.
|
||||||
if((unsigned_p && (unsigned)prevn >= (unsigned)n))
|
FIXME: This check is wrong; for example it doesn't find overflow
|
||||||
range_error("Overflow on numeric constant.");
|
on 0x123456789 when LONGEST is 32 bits. */
|
||||||
}
|
if (c != 'l' && c != 'u' && n != 0)
|
||||||
prevn=n;
|
{
|
||||||
|
if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n))
|
||||||
|
error ("Numeric constant too large.");
|
||||||
|
}
|
||||||
|
prevn = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the number is too big to be an int, or it's got an l suffix
|
|
||||||
then it's a long. Work out if this has to be a long by
|
|
||||||
shifting right and and seeing if anything remains, and the
|
|
||||||
target int size is different to the target long size.
|
|
||||||
|
|
||||||
In the expression below, we could have tested
|
/* An integer constant is an int, a long, or a long long. An L
|
||||||
(n >> TARGET_INT_BIT)
|
suffix forces it to be long; an LL suffix forces it to be long
|
||||||
to see if it was zero,
|
long. If not forced to a larger size, it gets the first type of
|
||||||
but too many compilers warn about that, when ints and longs
|
the above that it fits in. To figure out whether it fits, we
|
||||||
are the same size. So we shift it twice, with fewer bits
|
shift it right and see whether anything remains. Note that we
|
||||||
each time, for the same result. */
|
can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one
|
||||||
|
operation, because many compilers will warn about such a shift
|
||||||
|
(which always produces a zero result). Sometimes TARGET_INT_BIT
|
||||||
|
or TARGET_LONG_BIT will be that big, sometimes not. To deal with
|
||||||
|
the case where it is we just always shift the value more than
|
||||||
|
once, with fewer bits each time. */
|
||||||
|
|
||||||
if ( (TARGET_INT_BIT != TARGET_LONG_BIT
|
if (long_p == 0
|
||||||
&& ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */
|
&& (((unsigned LONGEST)n >> 2) >> (TARGET_INT_BIT - 2)) == 0)
|
||||||
|| long_p)
|
{
|
||||||
{
|
high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
|
||||||
high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
|
|
||||||
unsigned_type = builtin_type_unsigned_long;
|
/* A large decimal (not hex or octal) constant (between INT_MAX
|
||||||
signed_type = builtin_type_long;
|
and UINT_MAX) is a long or unsigned long, according to ANSI,
|
||||||
}
|
never an unsigned int, but this code treats it as unsigned
|
||||||
else
|
int. This probably should be fixed. GCC gives a warning on
|
||||||
{
|
such constants. */
|
||||||
high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
|
|
||||||
unsigned_type = builtin_type_unsigned_int;
|
unsigned_type = builtin_type_unsigned_int;
|
||||||
signed_type = builtin_type_int;
|
signed_type = builtin_type_int;
|
||||||
}
|
}
|
||||||
|
else if (long_p <= 1
|
||||||
|
&& (((unsigned LONGEST)n >> 2) >> (TARGET_LONG_BIT - 2)) == 0)
|
||||||
|
{
|
||||||
|
high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
|
||||||
|
unsigned_type = builtin_type_unsigned_long;
|
||||||
|
signed_type = builtin_type_long;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_LONG_BIT - 1);
|
||||||
|
unsigned_type = builtin_type_unsigned_long_long;
|
||||||
|
signed_type = builtin_type_long_long;
|
||||||
|
}
|
||||||
|
|
||||||
putithere->typed_val.val = n;
|
putithere->typed_val.val = n;
|
||||||
|
|
||||||
@ -1018,11 +1058,11 @@ parse_number (p, len, parsed_float, putithere)
|
|||||||
|
|
||||||
if (unsigned_p || (n & high_bit))
|
if (unsigned_p || (n & high_bit))
|
||||||
{
|
{
|
||||||
putithere->typed_val.type = unsigned_type;
|
putithere->typed_val.type = unsigned_type;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
putithere->typed_val.type = signed_type;
|
putithere->typed_val.type = signed_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
return INT;
|
return INT;
|
||||||
|
Reference in New Issue
Block a user