Skip to content

Commit 110c50f

Browse files
committed
fix #5591
1 parent 4314496 commit 110c50f

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

lib/checkother.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -4384,6 +4384,41 @@ void CheckOther::overlappingWriteFunction(const Token *tok, const std::string& f
43844384
reportError(tok, Severity::error, "overlappingWriteFunction", "Overlapping read/write in " + funcname + "() is undefined behavior");
43854385
}
43864386

4387+
void CheckOther::checkSuspiciousComma()
4388+
{
4389+
if (!mSettings->severity.isEnabled(Severity::style)) {
4390+
return;
4391+
}
4392+
4393+
logChecker("CheckOther::suspiciousComma");
4394+
4395+
for (const Token* tok = mTokenizer->list.front(); tok; tok = tok->next()) {
4396+
if (tok->str() == "," && tok->isBinaryOp()) {
4397+
const Token * parent = tok->astParent();
4398+
if (parent && Token::Match(parent->previous(), "if|while (")) {
4399+
if (tok->strAt(-1) == ")") {
4400+
const Function * func = tok->linkAt(-1)->previous()->function();
4401+
if (func && func->initArgCount > 0) {
4402+
const Token * r_op = tok->astOperand2();
4403+
if (r_op && (r_op->isVariable() ||
4404+
r_op->tokType() == Token::eNumber ||
4405+
r_op->tokType() == Token::eString ||
4406+
r_op->tokType() == Token::eChar ||
4407+
r_op->tokType() == Token::eBoolean)) {
4408+
checkSuspiciousCommaError(tok);
4409+
}
4410+
}
4411+
}
4412+
}
4413+
}
4414+
}
4415+
}
4416+
4417+
void CheckOther::checkSuspiciousCommaError(const Token *tok)
4418+
{
4419+
reportError(tok, Severity::style, "suspiciousComma", "There is a suspicious comma expression in an if/while condition statement.");
4420+
}
4421+
43874422
void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
43884423
{
43894424
CheckOther checkOther(&tokenizer, &tokenizer.getSettings(), errorLogger);
@@ -4431,6 +4466,7 @@ void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
44314466
checkOther.checkAccessOfMovedVariable();
44324467
checkOther.checkModuloOfOne();
44334468
checkOther.checkOverlappingWrite();
4469+
checkOther.checkSuspiciousComma();
44344470
}
44354471

44364472
void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const
@@ -4503,6 +4539,7 @@ void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *sett
45034539
c.comparePointersError(nullptr, nullptr, nullptr);
45044540
c.redundantAssignmentError(nullptr, nullptr, "var", false);
45054541
c.redundantInitializationError(nullptr, nullptr, "var", false);
4542+
c.checkSuspiciousCommaError(nullptr);
45064543

45074544
const std::vector<const Token *> nullvec;
45084545
c.funcArgOrderDifferent("function", nullptr, nullptr, nullvec, nullvec);

lib/checkother.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ class CPPCHECKLIB CheckOther : public Check {
192192
void overlappingWriteUnion(const Token *tok);
193193
void overlappingWriteFunction(const Token *tok, const std::string& funcname);
194194

195+
void checkSuspiciousComma();
196+
195197
// Error messages..
196198
void checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* tok, const std::string &functionName, const std::string &varName, bool result);
197199
void checkCastIntToCharAndBackError(const Token *tok, const std::string &strFunctionName);
@@ -249,6 +251,7 @@ class CPPCHECKLIB CheckOther : public Check {
249251
void knownPointerToBoolError(const Token* tok, const ValueFlow::Value* value);
250252
void comparePointersError(const Token *tok, const ValueFlow::Value *v1, const ValueFlow::Value *v2);
251253
void checkModuloOfOneError(const Token *tok);
254+
void checkSuspiciousCommaError(const Token *tok);
252255

253256
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override;
254257

@@ -312,7 +315,8 @@ class CPPCHECKLIB CheckOther : public Check {
312315
"- shadow variable.\n"
313316
"- variable can be declared const.\n"
314317
"- calculating modulo of one.\n"
315-
"- known function argument, suspicious calculation.\n";
318+
"- known function argument, suspicious calculation.\n"
319+
"- suspicious comma in if/while condition statement.\n";
316320
}
317321

318322
bool diag(const Token* tok) {

test/testother.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ class TestOther : public TestFixture {
305305

306306
TEST_CASE(knownConditionFloating);
307307
TEST_CASE(knownConditionPrefixed);
308+
309+
TEST_CASE(suspiciousComma);
308310
}
309311

310312
#define check(...) check_(__FILE__, __LINE__, __VA_ARGS__)
@@ -13070,6 +13072,25 @@ class TestOther : public TestFixture {
1307013072
"[test.cpp:2:13] -> [test.cpp:3:11]: (style) The comparison 'i > +1' is always false. [knownConditionTrueFalse]\n",
1307113073
errout_str());
1307213074
}
13075+
13076+
void suspiciousComma()
13077+
{
13078+
check("void f(int a, int b = 0);\n"
13079+
"void foo() {\n"
13080+
" if (f(100), 100) {}\n"
13081+
"}\n");
13082+
ASSERT_EQUALS(
13083+
"[test.cpp:3:15]: (style) There is a suspicious comma expression in an if/while condition statement. [suspiciousComma]\n",
13084+
errout_str());
13085+
13086+
check("void f(int a, int b = 0);\n"
13087+
"void foo() {\n"
13088+
" while (f(100), 100) {}\n"
13089+
"}\n");
13090+
ASSERT_EQUALS(
13091+
"[test.cpp:3:18]: (style) There is a suspicious comma expression in an if/while condition statement. [suspiciousComma]\n",
13092+
errout_str());
13093+
}
1307313094
};
1307413095

1307513096
REGISTER_TEST(TestOther)

0 commit comments

Comments
 (0)