mirror of
https://github.com/cc65/cc65.git
synced 2025-01-22 21:32:57 +00:00
Fixed diagnostic messages on enumerator overflow.
An enumerator that would be incremented greater than ULONG_MAX now causes an error.
This commit is contained in:
parent
ad7c5a6617
commit
deb5e97732
@ -611,20 +611,20 @@ static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Defaulted with the same signedness as the previous member's */
|
/* Defaulted with the same signedness as the previous member's */
|
||||||
IsSigned = IsSignSigned (MemberType) &&
|
IsSigned = IsSignSigned (MemberType) &&
|
||||||
(unsigned long)EnumVal != GetIntegerTypeMax (MemberType);
|
(unsigned long)EnumVal != GetIntegerTypeMax (MemberType);
|
||||||
|
|
||||||
/* Enumerate. Signed integer overflow is UB but unsigned integers
|
/* Enumerate by adding one to the previous value */
|
||||||
** are guaranteed to wrap around.
|
EnumVal = (long)(((unsigned long)EnumVal + 1UL) & 0xFFFFFFFFUL);
|
||||||
*/
|
|
||||||
EnumVal = (long)((unsigned long)EnumVal + 1UL);
|
|
||||||
|
|
||||||
if (UnqualifiedType (MemberType->C) == T_ULONG && EnumVal == 0) {
|
if (UnqualifiedType (MemberType->C) == T_ULONG && EnumVal == 0) {
|
||||||
/* Warn on 'unsigned long' overflow in enumeration */
|
/* Error since the new value cannot be represented in the
|
||||||
Warning ("Enumerator '%s' overflows the range of '%s'",
|
** largest unsigned integer type supported by cc65 for enum.
|
||||||
Ident,
|
*/
|
||||||
GetBasicTypeName (type_ulong));
|
Error ("Enumerator '%s' overflows the range of '%s'",
|
||||||
|
Ident,
|
||||||
|
GetBasicTypeName (type_ulong));
|
||||||
}
|
}
|
||||||
|
|
||||||
IsIncremented = 1;
|
IsIncremented = 1;
|
||||||
@ -657,11 +657,12 @@ static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags)
|
|||||||
/* Warn if the incremented value exceeds the range of the previous
|
/* Warn if the incremented value exceeds the range of the previous
|
||||||
** type.
|
** type.
|
||||||
*/
|
*/
|
||||||
if (IsIncremented &&
|
if (PrevErrorCount == ErrorCount &&
|
||||||
EnumVal >= 0 &&
|
IsIncremented &&
|
||||||
|
(!IsSigned || EnumVal >= 0) &&
|
||||||
NewType->C != UnqualifiedType (MemberType->C)) {
|
NewType->C != UnqualifiedType (MemberType->C)) {
|
||||||
/* The possible overflow here can only be when EnumVal > 0 */
|
/* The possible overflow here can only be when EnumVal > 0 */
|
||||||
Warning ("Enumerator '%s' (value = %lu) is of type '%s'",
|
Warning ("Enumerator '%s' (value = %lu) implies type '%s'",
|
||||||
Ident,
|
Ident,
|
||||||
(unsigned long)EnumVal,
|
(unsigned long)EnumVal,
|
||||||
GetBasicTypeName (NewType));
|
GetBasicTypeName (NewType));
|
||||||
|
9
test/err/bug1890.c
Normal file
9
test/err/bug1890.c
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* bug #1890 - Overflow in enumerator value is not detected */
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
enum { a = ULONG_MAX, b } c = b;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user