Skip to content

Commit d5fc8de

Browse files
committed
fix #5591
1 parent 4d7aa5a commit d5fc8de

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

lib/checkother.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4387,6 +4387,43 @@ void CheckOther::overlappingWriteFunction(const Token *tok, const std::string& f
43874387
reportError(tok, Severity::error, "overlappingWriteFunction", "Overlapping read/write in " + funcname + "() is undefined behavior");
43884388
}
43894389

4390+
void CheckOther::checkSuspiciousComma()
4391+
{
4392+
if (!mSettings->severity.isEnabled(Severity::style)) {
4393+
return;
4394+
}
4395+
4396+
logChecker("CheckOther::suspiciousComma");
4397+
4398+
for (const Token* tok = mTokenizer->list.front(); tok; tok = tok->next()) {
4399+
if (tok->str() == "," && tok->isBinaryOp()) {
4400+
const Token * parent = tok->astParent();
4401+
if (parent && Token::Match(parent->previous(), "if|while (")) {
4402+
if (tok->strAt(-1) == ")") {
4403+
const Function * func = tok->linkAt(-1)->previous()->function();
4404+
if (func && func->initArgCount > 0 && !tok->astOperand2()->hasKnownValue()) {
4405+
std::vector<const Token*> arg_vec = getArguments(tok->linkAt(-1)->previous());
4406+
if (arg_vec.size() < func->argCount() && arg_vec.size() > 0) {
4407+
const ValueType * type1 = tok->astOperand2()->valueType();
4408+
std::vector<Variable> v(func->argumentList.begin(), func->argumentList.end());
4409+
const ValueType * type2 = v[arg_vec.size()].valueType();
4410+
if (type1 && type2 && type1->isTypeEqual(type2)) {
4411+
checkSuspiciousCommaError(tok);
4412+
}
4413+
}
4414+
}
4415+
}
4416+
}
4417+
}
4418+
}
4419+
}
4420+
4421+
void CheckOther::checkSuspiciousCommaError(const Token *tok)
4422+
{
4423+
reportError(tok, Severity::style, "suspiciousComma", "There is a suspicious comma expression directly after a function call "
4424+
"in an if/while condition statement, is there a misplaced paranthesis?");
4425+
}
4426+
43904427
void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
43914428
{
43924429
CheckOther checkOther(&tokenizer, &tokenizer.getSettings(), errorLogger);
@@ -4434,6 +4471,7 @@ void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
44344471
checkOther.checkAccessOfMovedVariable();
44354472
checkOther.checkModuloOfOne();
44364473
checkOther.checkOverlappingWrite();
4474+
checkOther.checkSuspiciousComma();
44374475
}
44384476

44394477
void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const
@@ -4506,6 +4544,7 @@ void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *sett
45064544
c.comparePointersError(nullptr, nullptr, nullptr);
45074545
c.redundantAssignmentError(nullptr, nullptr, "var", false);
45084546
c.redundantInitializationError(nullptr, nullptr, "var", false);
4547+
c.checkSuspiciousCommaError(nullptr);
45094548

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

lib/checkother.h

Lines changed: 5 additions & 1 deletion
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 immediately after function call in if/while condition statement.\n";
316320
}
317321

318322
bool diag(const Token* tok) {

releasenotes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ New checks:
44
-
55

66
Improved checking:
7+
- Check the suspicious comma expression directly after a function call in an if/while condition statement.
78
-
89

910
GUI:

test/testother.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ class TestOther : public TestFixture {
306306

307307
TEST_CASE(knownConditionFloating);
308308
TEST_CASE(knownConditionPrefixed);
309+
310+
TEST_CASE(suspiciousComma);
309311
}
310312

311313
#define check(...) check_(__FILE__, __LINE__, __VA_ARGS__)
@@ -13093,6 +13095,43 @@ class TestOther : public TestFixture {
1309313095
"[test.cpp:2:13] -> [test.cpp:3:11]: (style) The comparison 'i > +1' is always false. [knownConditionTrueFalse]\n",
1309413096
errout_str());
1309513097
}
13098+
13099+
void suspiciousComma()
13100+
{
13101+
check("void f(int a, int b = 0);\n"
13102+
"void foo(int var) {\n"
13103+
" if (f(100), var) {}\n"
13104+
"}\n");
13105+
ASSERT_EQUALS(
13106+
"[test.cpp:3:15]: (style) There is a suspicious comma expression directly after a function call "
13107+
"in an if/while condition statement, is there a misplaced paranthesis? [suspiciousComma]\n",
13108+
errout_str());
13109+
13110+
check("void f(int a, int b = 0);\n"
13111+
"void foo(int var) {\n"
13112+
" while (f(100), var) {}\n"
13113+
"}\n");
13114+
ASSERT_EQUALS(
13115+
"[test.cpp:3:18]: (style) There is a suspicious comma expression directly after a function call "
13116+
"in an if/while condition statement, is there a misplaced paranthesis? [suspiciousComma]\n",
13117+
errout_str());
13118+
13119+
check("void f(int a, int b = 0);\n"
13120+
"void foo(int * var) {\n"
13121+
" if (f(100), var) {}\n"
13122+
"}\n");
13123+
ASSERT_EQUALS(
13124+
"",
13125+
errout_str());
13126+
13127+
check("void f(int a);\n"
13128+
"void foo(int var) {\n"
13129+
" if (f(100), var) {}\n"
13130+
"}\n");
13131+
ASSERT_EQUALS(
13132+
"",
13133+
errout_str());
13134+
}
1309613135
};
1309713136

1309813137
REGISTER_TEST(TestOther)

0 commit comments

Comments
 (0)