Refactorized postfix operator check:
- Support class members - Support references (removed wrong bailout) - Removed wrong unit tests and wrong messages for std::cout << k-- << std::endl;
This commit is contained in:
parent
ac0df7104e
commit
12f5ccfb4e
|
@ -43,26 +43,34 @@ void CheckPostfixOperator::postfixOperator()
|
|||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (tok->type() == Token::eIncDecOp) {
|
||||
bool result = false;
|
||||
if (Token::Match(tok->tokAt(-2), ";|{|}") && Token::Match(tok->next(), ";|)|,")) {
|
||||
const Variable *var = tok->variable();
|
||||
if (var && Token::Match(tok, "%var% ++|--")) {
|
||||
if (Token::Match(tok->previous(), ";|{|}") && Token::Match(tok->tokAt(2), ";|,|)")) {
|
||||
result = true;
|
||||
} else if (tok->strAt(-2) == ",") {
|
||||
int ii(1);
|
||||
while (tok->strAt(ii) != ")" && tok->tokAt(ii) != 0) {
|
||||
if (tok->strAt(ii) == ";") {
|
||||
} else if (tok->strAt(-1) == ",") {
|
||||
for (const Token* tok2 = tok->tokAt(2); tok2 != 0 && tok2->str() != ")"; tok2 = tok2->next()) {
|
||||
if (tok2->str() == ";") {
|
||||
result = true;
|
||||
break;
|
||||
} else if (tok2->str() == "(")
|
||||
tok2 = tok2->link();
|
||||
}
|
||||
++ii;
|
||||
}
|
||||
} else if (tok->strAt(-2) == "<<" && tok->strAt(1) == "<<") {
|
||||
} else if (tok->strAt(-1) == ".") {
|
||||
for (const Token* tok2 = tok->tokAt(-2); tok2 != 0; tok2 = tok2->previous()) {
|
||||
if (Token::Match(tok2, ";|{|}")) {
|
||||
result = true;
|
||||
break;
|
||||
} else if (Token::Match(tok2, ")|]|>") && tok2->link())
|
||||
tok2 = tok2->link();
|
||||
else if (tok2->isAssignmentOp() || Token::Match(tok2, "(|["))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result && tok->previous()->varId()) {
|
||||
const Variable *var = tok->previous()->variable();
|
||||
if (!var || var->isPointer() || var->isArray() || var->isReference())
|
||||
if (result) {
|
||||
if (var->isPointer() || var->isArray())
|
||||
continue;
|
||||
|
||||
const Token *decltok = var->nameToken();
|
||||
|
@ -77,7 +85,6 @@ void CheckPostfixOperator::postfixOperator()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -56,13 +56,14 @@ private:
|
|||
void run() {
|
||||
TEST_CASE(testsimple);
|
||||
TEST_CASE(testfor);
|
||||
TEST_CASE(teststream);
|
||||
TEST_CASE(testvolatile);
|
||||
TEST_CASE(testiterator);
|
||||
TEST_CASE(test2168);
|
||||
TEST_CASE(pointer); // #2321 - postincrement of pointer is OK
|
||||
TEST_CASE(testHangWithInvalidCode); // #2847 - cppcheck hangs with 100% cpu load
|
||||
TEST_CASE(testtemplate); // #4686
|
||||
TEST_CASE(testmember);
|
||||
TEST_CASE(testcomma);
|
||||
}
|
||||
|
||||
void testHangWithInvalidCode() {
|
||||
|
@ -106,6 +107,13 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
|
||||
|
||||
check("struct K {};\n"
|
||||
"void foo(K& k)\n"
|
||||
"{\n"
|
||||
" k++;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
|
||||
|
||||
check("union K {};"
|
||||
"void foo()\n"
|
||||
"{\n"
|
||||
|
@ -230,39 +238,6 @@ private:
|
|||
|
||||
}
|
||||
|
||||
void teststream() {
|
||||
check("int main()\n"
|
||||
"{\n"
|
||||
" int k(0);\n"
|
||||
" std::cout << k << std::endl;\n"
|
||||
" std::cout << k++ << std::endl;\n"
|
||||
" std::cout << k-- << std::endl;\n"
|
||||
" return 0;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("class K {};\n"
|
||||
"int main()\n"
|
||||
"{\n"
|
||||
" K k(0);\n"
|
||||
" std::cout << k << std::endl;\n"
|
||||
" std::cout << k-- << std::endl;\n"
|
||||
" return 0;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
|
||||
|
||||
check("class K {};\n"
|
||||
"int main()\n"
|
||||
"{\n"
|
||||
" K k(0);\n"
|
||||
" std::cout << k << std::endl;\n"
|
||||
" std::cout << ++k << std::endl;\n"
|
||||
" std::cout << --k << std::endl;\n"
|
||||
" return 0;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void testvolatile() {
|
||||
check("class K {};\n"
|
||||
"int main()\n"
|
||||
|
@ -354,6 +329,39 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
|
||||
}
|
||||
|
||||
void testmember() {
|
||||
check("bool foo() {\n"
|
||||
" class A {}; class B {A a;};\n"
|
||||
" B b;\n"
|
||||
" b.a++;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
|
||||
|
||||
check("bool foo() {\n"
|
||||
" class A {}; class B {A a;};\n"
|
||||
" B b;\n"
|
||||
" foo(b.a++);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void testcomma() {
|
||||
check("bool foo(int i) {\n"
|
||||
" class A {};\n"
|
||||
" A a;\n"
|
||||
" i++, a++;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
|
||||
|
||||
check("bool foo(int i) {\n"
|
||||
" class A {};\n"
|
||||
" A a;\n"
|
||||
" foo(i, a++);\n"
|
||||
" foo(a++, i);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestPostfixOperator)
|
||||
|
|
Loading…
Reference in New Issue