1
0
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:
acqn 2022-11-02 14:22:21 +08:00
parent ad7c5a6617
commit deb5e97732
2 changed files with 22 additions and 12 deletions

View File

@ -615,14 +615,14 @@ static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags)
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.
*/
Error ("Enumerator '%s' overflows the range of '%s'",
Ident, Ident,
GetBasicTypeName (type_ulong)); GetBasicTypeName (type_ulong));
} }
@ -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
View 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;
}