From 409235aee65ce5fd807a50b32a2a4ba664aaab70 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Tue, 2 May 2023 22:27:28 -0400 Subject: [PATCH] Optional warning for implicit constant conversion overflow --- doc/cc65.sgml | 2 ++ src/cc65/error.c | 2 ++ src/cc65/error.h | 1 + src/cc65/typeconv.c | 5 +++++ 4 files changed, 10 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 683249bda..5a094571a 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -754,6 +754,8 @@ Here is a description of all the command line options: Warn about unused function parameters. Warn about unused variables. + + Warn if numerical constant conversion implies overflow. (Disabled by default.) The full list of available warning names can be retrieved by using the diff --git a/src/cc65/error.c b/src/cc65/error.c index 3f36d9e97..6ac3e594b 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -79,6 +79,7 @@ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ +IntStack WarnConstOverflow = INTSTACK(0); /* - overflow conversion of numerical constants */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -102,6 +103,7 @@ static WarnMapEntry WarnMap[] = { { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, + { &WarnConstOverflow, "const-overflow" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index 7fcb03467..83be8c782 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -76,6 +76,7 @@ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ extern IntStack WarnUnusedFunc; /* - unused functions */ +extern IntStack WarnConstOverflow; /* - overflow conversion of numerical constants */ /* Forward */ struct StrBuf; diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index f77ec3951..49dfcc597 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -128,6 +128,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** internally already represented by a long. */ if (NewBits <= OldBits) { + unsigned long OldVal = Expr->IVal; /* Cut the value to the new size */ Expr->IVal &= (0xFFFFFFFFUL >> (32 - NewBits)); @@ -139,6 +140,10 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) Expr->IVal |= shl_l (~0UL, NewBits); } } + + if ((OldVal != Expr->IVal) && IS_Get (&WarnConstOverflow)) { + Warning ("Implicit conversion of constant overflows %d-bit destination", NewBits); + } } /* Do the integer constant <-> absolute address conversion if necessary */