1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-11 11:30:13 +00:00

Added a warning on promoting a decimal constant without a 'u'/'U' suffix to unsigned long.

This commit is contained in:
acqn 2020-07-02 10:30:02 +08:00 committed by Oliver Schmidt
parent 381a32d9aa
commit 7d652d42dc

View File

@ -530,10 +530,12 @@ static void NumericConst (void)
if (!IsFloat) { if (!IsFloat) {
unsigned Types; unsigned Types;
int HaveSuffix; unsigned WarnTypes = 0;
/* Check for a suffix and determine the possible types */ /* Check for a suffix and determine the possible types. It is always
HaveSuffix = 1; ** possible to convert the data to unsigned long even if the IT_ULONG
** flag were not set, but we are not doing that.
*/
if (toupper (CurC) == 'U') { if (toupper (CurC) == 'U') {
/* Unsigned type */ /* Unsigned type */
NextChar (); NextChar ();
@ -548,17 +550,18 @@ static void NumericConst (void)
NextChar (); NextChar ();
if (toupper (CurC) != 'U') { if (toupper (CurC) != 'U') {
Types = IT_LONG | IT_ULONG; Types = IT_LONG | IT_ULONG;
WarnTypes = IT_ULONG;
} else { } else {
NextChar (); NextChar ();
Types = IT_ULONG; Types = IT_ULONG;
} }
} else { } else {
HaveSuffix = 0;
if (Prefix == 10) { if (Prefix == 10) {
/* Decimal constants are of any type but uint */ /* Decimal constants are of any type but uint */
Types = IT_INT | IT_LONG | IT_ULONG; Types = IT_INT | IT_LONG | IT_ULONG;
WarnTypes = IT_LONG | IT_ULONG;
} else { } else {
/* Octal or hex constants are of any type */ /* Binary, octal or hex constants can be of any type */
Types = IT_INT | IT_UINT | IT_LONG | IT_ULONG; Types = IT_INT | IT_UINT | IT_LONG | IT_ULONG;
} }
} }
@ -568,11 +571,14 @@ static void NumericConst (void)
/* Out of range for int */ /* Out of range for int */
Types &= ~IT_INT; Types &= ~IT_INT;
/* If the value is in the range 0x8000..0xFFFF, unsigned int is not /* If the value is in the range 0x8000..0xFFFF, unsigned int is not
** allowed, and we don't have a type specifying suffix, emit a ** allowed, and we don't have a long type specifying suffix, emit a
** warning, because the constant is of type long. ** warning, because the constant is of type long while the user
** might expect an unsigned int.
*/ */
if (IVal <= 0xFFFF && (Types & IT_UINT) == 0 && !HaveSuffix) { if (IVal <= 0xFFFF &&
Warning ("Constant is long"); (Types & IT_UINT) == 0 &&
(WarnTypes & IT_LONG) != 0) {
Warning ("Integer constant is long");
} }
} }
if (IVal > 0xFFFF) { if (IVal > 0xFFFF) {
@ -582,6 +588,15 @@ static void NumericConst (void)
if (IVal > 0x7FFFFFFF) { if (IVal > 0x7FFFFFFF) {
/* Out of range for long int */ /* Out of range for long int */
Types &= ~IT_LONG; Types &= ~IT_LONG;
/* If the value is in the range 0x80000000..0xFFFFFFFF, decimal,
** and we have no unsigned type specifying suffix, emit a warning,
** because the constant is of type unsigned long while the user
** might expect a signed integer constant, especially if there is
** a preceding unary op or when it is used in constant calculation.
*/
if (WarnTypes & IT_ULONG) {
Warning ("Integer constant is unsigned long");
}
} }
/* Now set the type string to the smallest type in types */ /* Now set the type string to the smallest type in types */