Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions lib/checktype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,35 +198,39 @@ void CheckType::checkIntegerOverflow()
const MathLib::bigint maxvalue = (((MathLib::biguint)1) << (bits - 1)) - 1;

// is there a overflow result value
bool isOverflow = true;
const ValueFlow::Value *value = tok->getValueGE(maxvalue + 1, *mSettings);
if (!value)
if (!value) {
value = tok->getValueLE(-maxvalue - 2, *mSettings);
isOverflow = false;
}
if (!value || !mSettings->isEnabled(value,false))
continue;

// For left shift, it's common practice to shift into the sign bit
if (tok->str() == "<<" && value->intvalue > 0 && value->intvalue < (((MathLib::bigint)1) << bits))
continue;

integerOverflowError(tok, *value);
integerOverflowError(tok, *value, isOverflow);
}
}

void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &value)
void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &value, bool isOverflow)
{
const std::string expr(tok ? tok->expressionString() : "");
const std::string type = isOverflow ? "overflow" : "underflow";

std::string msg;
if (value.condition)
msg = ValueFlow::eitherTheConditionIsRedundant(value.condition) +
" or there is signed integer overflow for expression '" + expr + "'.";
" or there is signed integer " + type + " for expression '" + expr + "'.";
else
msg = "Signed integer overflow for expression '" + expr + "'.";
msg = "Signed integer " + type + " for expression '" + expr + "'.";

if (value.safe)
msg = "Safe checks: " + msg;

reportError(getErrorPath(tok, &value, "Integer overflow"),
reportError(getErrorPath(tok, &value, "Integer " + type),
value.errorSeverity() ? Severity::error : Severity::warning,
getMessageId(value, "integerOverflow").c_str(),
msg,
Expand Down
2 changes: 1 addition & 1 deletion lib/checktype.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class CPPCHECKLIB CheckType : public Check {
// Error messages..
void tooBigBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits);
void tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits);
void integerOverflowError(const Token *tok, const ValueFlow::Value &value);
void integerOverflowError(const Token *tok, const ValueFlow::Value &value, bool isOverflow = true);
void signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, bool constvalue);
void longCastAssignError(const Token *tok, const ValueType* src = nullptr, const ValueType* tgt = nullptr);
void longCastReturnError(const Token *tok, const ValueType* src = nullptr, const ValueType* tgt = nullptr);
Expand Down
12 changes: 11 additions & 1 deletion test/testtype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ class TestType : public TestFixture {
" if (x==123456) {}\n"
" return -123456 * x;\n"
"}",settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==123456' is redundant or there is signed integer overflow for expression '-123456*x'.\n", errout_str());
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==123456' is redundant or there is signed integer underflow for expression '-123456*x'.\n", errout_str());

check("int foo(signed int x) {\n"
" if (x==123456) {}\n"
Expand All @@ -303,6 +303,16 @@ class TestType : public TestFixture {
" return (i == 31) ? 1 << i : 0;\n"
"}", settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (warning) Shifting signed 32-bit value by 31 bits is undefined behaviour. See condition at line 2.\n", errout_str());

check("void f() {\n" // #13092
" int n = 0;\n"
" for (int i = 0; i < 10; i++) {\n"
" n = n * 47163 - 57412;\n"
" }\n"
"}", settings);
ASSERT_EQUALS("[test.cpp:4]: (error) Signed integer underflow for expression 'n*47163'.\n"
"[test.cpp:4]: (error) Signed integer underflow for expression 'n*47163-57412'.\n",
errout_str());
}

void signConversion() {
Expand Down