Skip to content

Commit 47c3ad1

Browse files
Partial fix for #12387 FP unsignedLessThanZero for template type (#5922)
1 parent c252427 commit 47c3ad1

4 files changed

Lines changed: 19 additions & 3 deletions

File tree

lib/checkcondition.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1567,7 +1567,7 @@ void CheckCondition::alwaysTrueFalse()
15671567
{
15681568
const ValueFlow::Value *zeroValue = nullptr;
15691569
const Token *nonZeroExpr = nullptr;
1570-
if (CheckOther::comparisonNonZeroExpressionLessThanZero(tok, &zeroValue, &nonZeroExpr) ||
1570+
if (CheckOther::comparisonNonZeroExpressionLessThanZero(tok, &zeroValue, &nonZeroExpr, /*suppress*/ true) ||
15711571
CheckOther::testIfNonZeroExpressionIsPositive(tok, &zeroValue, &nonZeroExpr))
15721572
continue;
15731573
}

lib/checkother.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2737,7 +2737,7 @@ void CheckOther::checkSignOfUnsignedVariable()
27372737
}
27382738
}
27392739

2740-
bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr)
2740+
bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr, bool suppress)
27412741
{
27422742
if (!tok->isComparisonOp() || !tok->astOperand1() || !tok->astOperand2())
27432743
return false;
@@ -2755,6 +2755,10 @@ bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const
27552755
return false;
27562756
}
27572757

2758+
if (const Variable* var = (*nonZeroExpr)->variable())
2759+
if (var->typeStartToken()->isTemplateArg())
2760+
return suppress;
2761+
27582762
const ValueType* vt = (*nonZeroExpr)->valueType();
27592763
return vt && (vt->pointer || vt->sign == ValueType::UNSIGNED);
27602764
}

lib/checkother.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class CPPCHECKLIB CheckOther : public Check {
5656
CheckOther() : Check(myName()) {}
5757

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

6161
/** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is positive? */
6262
static bool testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr);

test/testother.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8250,6 +8250,18 @@ class TestOther : public TestFixture {
82508250
" if (y < x) {}\n"
82518251
"}");
82528252
ASSERT_EQUALS("[test.cpp:4]: (style) Checking if unsigned expression 'y' is less than zero.\n", errout.str());
8253+
8254+
// #12387
8255+
check("template<typename T>\n"
8256+
"void f(T t) {\n"
8257+
" if constexpr (std::numeric_limits<T>::is_signed) {\n"
8258+
" if (t < 0) {}\n"
8259+
" }\n"
8260+
"}\n"
8261+
"void g() {\n"
8262+
" f<uint32_t>(0);\n"
8263+
"}");
8264+
ASSERT_EQUALS("", errout.str());
82538265
}
82548266

82558267
void checkSignOfPointer() {

0 commit comments

Comments
 (0)