Skip to content

Commit 20278d9

Browse files
committed
Clarify signConversion warning message
1 parent 1718963 commit 20278d9

3 files changed

Lines changed: 19 additions & 8 deletions

File tree

lib/checktype.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void CheckType::checkTooBigBitwiseShift()
7070

7171
// get number of bits of lhs
7272
const ValueType * const lhstype = tok->astOperand1()->valueType();
73-
if (!lhstype || !lhstype->isIntegral() || lhstype->pointer >= 1U)
73+
if (!lhstype || !lhstype->isIntegral() || lhstype->pointer >= 1)
7474
continue;
7575
// C11 Standard, section 6.5.7 Bitwise shift operators, states:
7676
// The integer promotions are performed on each of the operands.
@@ -237,15 +237,16 @@ void CheckType::checkSignConversion()
237237
tokens.pop();
238238
if (!tok1)
239239
continue;
240-
if (!tok1->getValueLE(-1,mSettings))
240+
const ValueFlow::Value *negativeValue = tok1->getValueLE(-1,mSettings);
241+
if (!negativeValue)
241242
continue;
242243
if (tok1->valueType() && tok1->valueType()->sign != ValueType::Sign::UNSIGNED)
243-
signConversionError(tok1, tok1->isNumber());
244+
signConversionError(tok1, negativeValue, tok1->isNumber());
244245
}
245246
}
246247
}
247248

248-
void CheckType::signConversionError(const Token *tok, const bool constvalue)
249+
void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, const bool constvalue)
249250
{
250251
const std::string expr(tok ? tok->expressionString() : "var");
251252

@@ -257,7 +258,17 @@ void CheckType::signConversionError(const Token *tok, const bool constvalue)
257258
else
258259
msg << "Expression '" << expr << "' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.";
259260

260-
reportError(tok, Severity::warning, "signConversion", msg.str(), CWE195, false);
261+
if (!negativeValue)
262+
reportError(tok, Severity::warning, "signConversion", msg.str(), CWE195, false);
263+
else {
264+
const ErrorPath &errorPath = getErrorPath(tok,negativeValue,"Negative value is converted to an unsigned value");
265+
reportError(errorPath,
266+
Severity::warning,
267+
Check::getMessageId(*negativeValue, "signConversion").c_str(),
268+
msg.str(),
269+
CWE195,
270+
negativeValue->isInconclusive());
271+
}
261272
}
262273

263274

lib/checktype.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class CPPCHECKLIB CheckType : public Check {
8181
void tooBigBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits);
8282
void tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits);
8383
void integerOverflowError(const Token *tok, const ValueFlow::Value &value);
84-
void signConversionError(const Token *tok, const bool constvalue);
84+
void signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, const bool constvalue);
8585
void longCastAssignError(const Token *tok);
8686
void longCastReturnError(const Token *tok);
8787
void floatToIntegerOverflowError(const Token *tok, const ValueFlow::Value &value);
@@ -91,7 +91,7 @@ class CPPCHECKLIB CheckType : public Check {
9191
c.tooBigBitwiseShiftError(nullptr, 32, ValueFlow::Value(64));
9292
c.tooBigSignedBitwiseShiftError(nullptr, 31, ValueFlow::Value(31));
9393
c.integerOverflowError(nullptr, ValueFlow::Value(1LL<<32));
94-
c.signConversionError(nullptr, false);
94+
c.signConversionError(nullptr, nullptr, false);
9595
c.longCastAssignError(nullptr);
9696
c.longCastReturnError(nullptr);
9797
ValueFlow::Value f;

test/testtype.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ class TestType : public TestFixture {
194194
" if (x==0) {}\n"
195195
" return (x-1)*sizeof(int);\n"
196196
"}\n");
197-
ASSERT_EQUALS("[test.cpp:3]: (warning) Expression 'x-1' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str());
197+
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Expression 'x-1' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str());
198198

199199
check("unsigned int f1(signed int x, unsigned int y) {" // x is signed
200200
" return x * y;\n"

0 commit comments

Comments
 (0)