Skip to content

Commit

Permalink
Partial fix for #12387 FP unsignedLessThanZero for template type (#5922)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github committed Jan 31, 2024
1 parent c252427 commit 47c3ad1
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/checkcondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1567,7 +1567,7 @@ void CheckCondition::alwaysTrueFalse()
{
const ValueFlow::Value *zeroValue = nullptr;
const Token *nonZeroExpr = nullptr;
if (CheckOther::comparisonNonZeroExpressionLessThanZero(tok, &zeroValue, &nonZeroExpr) ||
if (CheckOther::comparisonNonZeroExpressionLessThanZero(tok, &zeroValue, &nonZeroExpr, /*suppress*/ true) ||
CheckOther::testIfNonZeroExpressionIsPositive(tok, &zeroValue, &nonZeroExpr))
continue;
}
Expand Down
6 changes: 5 additions & 1 deletion lib/checkother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2737,7 +2737,7 @@ void CheckOther::checkSignOfUnsignedVariable()
}
}

bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr)
bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr, bool suppress)
{
if (!tok->isComparisonOp() || !tok->astOperand1() || !tok->astOperand2())
return false;
Expand All @@ -2755,6 +2755,10 @@ bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const
return false;
}

if (const Variable* var = (*nonZeroExpr)->variable())
if (var->typeStartToken()->isTemplateArg())
return suppress;

const ValueType* vt = (*nonZeroExpr)->valueType();
return vt && (vt->pointer || vt->sign == ValueType::UNSIGNED);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/checkother.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class CPPCHECKLIB CheckOther : public Check {
CheckOther() : Check(myName()) {}

/** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is less than zero? */
static bool comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr);
static bool comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr, bool suppress = false);

/** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is positive? */
static bool testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr);
Expand Down
12 changes: 12 additions & 0 deletions test/testother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8250,6 +8250,18 @@ class TestOther : public TestFixture {
" if (y < x) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Checking if unsigned expression 'y' is less than zero.\n", errout.str());

// #12387
check("template<typename T>\n"
"void f(T t) {\n"
" if constexpr (std::numeric_limits<T>::is_signed) {\n"
" if (t < 0) {}\n"
" }\n"
"}\n"
"void g() {\n"
" f<uint32_t>(0);\n"
"}");
ASSERT_EQUALS("", errout.str());
}

void checkSignOfPointer() {
Expand Down

0 comments on commit 47c3ad1

Please sign in to comment.