Take simplifyIfNotNull and simplifyIfNot out of simplifyTokenList1 (first step for #6072)

This commit is contained in:
PKEuS 2015-01-31 20:12:02 +01:00
parent 1f97e3001b
commit 21cb0cfd60
11 changed files with 99 additions and 109 deletions

View File

@ -3528,10 +3528,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
// simplify bit fields.. // simplify bit fields..
simplifyBitfields(); simplifyBitfields();
// Simplify '(p == 0)' to '(!p)'
simplifyIfNot();
simplifyIfNotNull();
// The simplifyTemplates have inner loops // The simplifyTemplates have inner loops
if (_settings->terminated()) if (_settings->terminated())
return false; return false;
@ -6119,15 +6115,15 @@ void Tokenizer::simplifyIfNotNull()
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
Token *deleteFrom = nullptr; Token *deleteFrom = nullptr;
// Remove 'x = (x != 0)' // Remove 'x = x != 0;'
if (Token::simpleMatch(tok, "= (")) { if (Token::simpleMatch(tok, "=")) {
if (Token::Match(tok->tokAt(-2), "[;{}] %name%")) { if (Token::Match(tok->tokAt(-2), "[;{}] %name%")) {
const std::string& varname(tok->previous()->str()); const std::string& varname(tok->previous()->str());
if (Token::simpleMatch(tok->tokAt(2), (varname + " != 0 ) ;").c_str()) || if (Token::simpleMatch(tok->next(), (varname + " != 0 ;").c_str()) ||
Token::simpleMatch(tok->tokAt(2), ("0 != " + varname + " ) ;").c_str())) { Token::simpleMatch(tok->next(), ("0 != " + varname + " ;").c_str())) {
tok = tok->tokAt(-2); tok = tok->tokAt(-2);
tok->deleteNext(8); tok->deleteNext(6);
} }
} }
continue; continue;

View File

@ -1927,7 +1927,7 @@ private:
" }\n" " }\n"
" a[i - 1] = 0;\n" " a[i - 1] = 0;\n"
" }\n" " }\n"
"}"); "}", true, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n" check("void f() {\n"

View File

@ -3889,7 +3889,7 @@ private:
" if( m_d != 0 )\n" " if( m_d != 0 )\n"
" return m_iRealVal / m_d;\n" " return m_iRealVal / m_d;\n"
" return dRet;\n" " return dRet;\n"
"};\n" "};", nullptr, true, false
); );
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'A::dGetValue' can be const.\n", errout.str()); ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'A::dGetValue' can be const.\n", errout.str());
} }

View File

@ -793,7 +793,7 @@ private:
void incorrectLogicOperator4() { void incorrectLogicOperator4() {
check("void f(int x) {\n" check("void f(int x) {\n"
" if (x && x != $0) {}\n" " if (x && x != $0) {}\n"
"}"); "}", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }

View File

@ -69,6 +69,7 @@ private:
TEST_CASE(garbageCode26); TEST_CASE(garbageCode26);
TEST_CASE(garbageCode27); TEST_CASE(garbageCode27);
TEST_CASE(garbageCode28); TEST_CASE(garbageCode28);
TEST_CASE(garbageCode29);
TEST_CASE(garbageValueFlow); TEST_CASE(garbageValueFlow);
TEST_CASE(garbageSymbolDatabase); TEST_CASE(garbageSymbolDatabase);
@ -379,6 +380,11 @@ private:
"};\n"), InternalError); "};\n"), InternalError);
} }
void garbageCode29() {
// ticket #2601 segmentation fault
checkCode("|| #if #define <=");
}
void garbageValueFlow() { void garbageValueFlow() {
// #6089 // #6089
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n" const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"

View File

@ -308,7 +308,7 @@ private:
" return;\n" " return;\n"
" }\n" " }\n"
" if (!abc);\n" " if (!abc);\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:5]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:5]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null.\n", errout.str());
// TODO: False negative if member of member is dereferenced // TODO: False negative if member of member is dereferenced
@ -323,7 +323,7 @@ private:
" abc->a = 0;\n" " abc->a = 0;\n"
" if (abc && abc->b == 0)\n" " if (abc && abc->b == 0)\n"
" ;\n" " ;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null.\n", errout.str());
// ok dereferencing in a condition // ok dereferencing in a condition
@ -560,7 +560,7 @@ private:
"{\n" "{\n"
" if (*p == 0) { }\n" " if (*p == 0) { }\n"
" if (!p) { }\n" " if (!p) { }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
// no error // no error
@ -597,7 +597,7 @@ private:
" int a = 2 * x;" " int a = 2 * x;"
" if (x == 0)\n" " if (x == 0)\n"
" ;\n" " ;\n"
"}", true); "}", true, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(int *p)\n" check("void foo(int *p)\n"
@ -823,12 +823,12 @@ private:
check("void f(struct ABC *abc) {\n" check("void f(struct ABC *abc) {\n"
" WARN_ON(!abc || abc->x == 0);\n" " WARN_ON(!abc || abc->x == 0);\n"
" if (!abc) { }\n" " if (!abc) { }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(struct ABC *abc) {\n" check("void f(struct ABC *abc) {\n"
" WARN_ON(!abc || abc->x == 7);\n" " WARN_ON(!abc || abc->x == 7);\n"
" if (!abc) { }\n" " if (!abc) { }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #3425 - false positives when there are macros // #3425 - false positives when there are macros
@ -1343,34 +1343,34 @@ private:
" if (NULL == p) {\n" " if (NULL == p) {\n"
" }\n" " }\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
check("void foo(char *p) {\n" check("void foo(char *p) {\n"
" if (p == NULL) {\n" " if (p == NULL) {\n"
" }\n" " }\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
check("void foo(char *p) {\n" check("void foo(char *p) {\n"
" if (p == NULL) {\n" " if (p == NULL) {\n"
" }\n" " }\n"
" printf(\"%c\", *p);\n" " printf(\"%c\", *p);\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
check("void foo(char *p) {\n" check("void foo(char *p) {\n"
" if (p && *p == 0) {\n" " if (p && *p == 0) {\n"
" }\n" " }\n"
" printf(\"%c\", *p);\n" " printf(\"%c\", *p);\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
check("void foo(char *p) {\n" check("void foo(char *p) {\n"
" if (p && *p == 0) {\n" " if (p && *p == 0) {\n"
" } else { *p = 0; }\n" " } else { *p = 0; }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
check("void foo(char *p) {\n" check("void foo(char *p) {\n"
@ -1500,7 +1500,7 @@ private:
" MACRO;\n" " MACRO;\n"
" }\n" " }\n"
" fred->a();\n" " fred->a();\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #2493 - switch // #2493 - switch
@ -1513,7 +1513,7 @@ private:
" fred->a();\n" " fred->a();\n"
" break;\n" " break;\n"
" };\n" " };\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #4118 - second if // #4118 - second if
@ -1549,7 +1549,7 @@ private:
" else {\n" " else {\n"
" int b = *i;\n" " int b = *i;\n"
" }\n" " }\n"
"}", true); "}", true, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #2696 - false positives nr 1 // #2696 - false positives nr 1
@ -1611,7 +1611,7 @@ private:
" if (p == 0 && (p = malloc(10)) != 0) {\n" " if (p == 0 && (p = malloc(10)) != 0) {\n"
" *p = 0;\n" " *p = 0;\n"
" }\n" " }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// check, assign and use // check, assign and use
@ -1620,7 +1620,7 @@ private:
" if (p == 0 && (p = malloc(10)) != a && (*p = a)) {\n" " if (p == 0 && (p = malloc(10)) != a && (*p = a)) {\n"
" *p = 0;\n" " *p = 0;\n"
" }\n" " }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// check, and use // check, and use
@ -1629,7 +1629,7 @@ private:
" if (p == 0 && (*p = 0)) {\n" " if (p == 0 && (*p = 0)) {\n"
" return;\n" " return;\n"
" }\n" " }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
// check, and use // check, and use
@ -1638,7 +1638,7 @@ private:
" if (p == 0 && p->x == 10) {\n" " if (p == 0 && p->x == 10) {\n"
" return;\n" " return;\n"
" }\n" " }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
// check, and use // check, and use
@ -1647,7 +1647,7 @@ private:
" if (p == 0 || p->x == 10) {\n" " if (p == 0 || p->x == 10) {\n"
" return;\n" " return;\n"
" }\n" " }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// check, and use // check, and use
@ -1656,7 +1656,7 @@ private:
" if (p == NULL && (*p = a)) {\n" " if (p == NULL && (*p = a)) {\n"
" return;\n" " return;\n"
" }\n" " }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
// check, and use // check, and use
@ -1664,7 +1664,7 @@ private:
" if (!p && x==1 || p && p->x==0) {\n" " if (!p && x==1 || p && p->x==0) {\n"
" return;\n" " return;\n"
" }\n" " }\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
{ {
@ -1673,17 +1673,17 @@ private:
" fred->x();\n" " fred->x();\n"
"}"; "}";
check(code); // non-inconclusive check(code, false, "test.cpp", false); // non-inconclusive
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check(code, true); // inconclusive check(code, true, "test.cpp", false); // inconclusive
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning, inconclusive) Possible null pointer dereference: fred - otherwise it is redundant to check it against null.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning, inconclusive) Possible null pointer dereference: fred - otherwise it is redundant to check it against null.\n", errout.str());
} }
check("void f(char *s) {\n" // #3358 check("void f(char *s) {\n" // #3358
" if (s==0);\n" " if (s==0);\n"
" strcpy(a, s?b:c);\n" " strcpy(a, s?b:c);\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// sizeof // sizeof
@ -2054,7 +2054,7 @@ private:
" std::cin >> p;\n" " std::cin >> p;\n"
" std::cout << abc << p;\n" " std::cout << abc << p;\n"
" }\n" " }\n"
"}"); "}", false, "test.cpp", false);
TODO_ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n" TODO_ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n"
"[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n" "[test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n"
"[test.cpp:5] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n" "[test.cpp:5] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n"
@ -2281,7 +2281,7 @@ private:
check("void f(int *p = 0) {\n" check("void f(int *p = 0) {\n"
" if (p != 0 && bar())\n" " if (p != 0 && bar())\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int *p) {\n" check("void f(int *p) {\n"
@ -2292,7 +2292,7 @@ private:
check("void f(int *p = 0) {\n" check("void f(int *p = 0) {\n"
" if (p != 0)\n" " if (p != 0)\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int *p = 0) {\n" check("void f(int *p = 0) {\n"
@ -2300,13 +2300,13 @@ private:
" if (p == 0)\n" " if (p == 0)\n"
" p = &y;\n" " p = &y;\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int *p = 0) {\n" check("void f(int *p = 0) {\n"
" if (a != 0)\n" " if (a != 0)\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("[test.cpp:3]: (warning) Possible null pointer dereference if the default parameter value is used: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (warning) Possible null pointer dereference if the default parameter value is used: p\n", errout.str());
check("void f(int *p = 0) {\n" check("void f(int *p = 0) {\n"
@ -2326,7 +2326,7 @@ private:
" return 0;\n" " return 0;\n"
" }\n" " }\n"
" return *p;\n" " return *p;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int *p = 0) {\n" check("void f(int *p = 0) {\n"
@ -2400,7 +2400,7 @@ private:
" init(&p);\n" " init(&p);\n"
" }\n" " }\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int *p = 0) {\n" check("void f(int *p = 0) {\n"
@ -2408,7 +2408,7 @@ private:
" throw SomeException;\n" " throw SomeException;\n"
" }\n" " }\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", false, "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(int *p = 0) {\n" check("void foo(int *p = 0) {\n"

View File

@ -179,7 +179,7 @@ private:
TEST_CASE(redundantPointerOp); TEST_CASE(redundantPointerOp);
} }
void check(const char raw_code[], const char *filename = nullptr, bool experimental = false, bool inconclusive = true, bool posix = false, bool runSimpleChecks=true, Settings* settings = 0) { void check(const char raw_code[], const char *filename = nullptr, bool experimental = false, bool inconclusive = true, bool posix = false, bool runSimpleChecks=true, Settings* settings = 0, bool verify = true) {
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
@ -219,7 +219,7 @@ private:
const std::string str1(tokenizer.tokens()->stringifyList(0,true)); const std::string str1(tokenizer.tokens()->stringifyList(0,true));
tokenizer.simplifyTokenList2(); tokenizer.simplifyTokenList2();
const std::string str2(tokenizer.tokens()->stringifyList(0,true)); const std::string str2(tokenizer.tokens()->stringifyList(0,true));
if (str1 != str2) if (verify && str1 != str2)
warnUnsimplified(str1, str2); warnUnsimplified(str1, str2);
checkOther.runSimplifiedChecks(&tokenizer, settings, this); checkOther.runSimplifiedChecks(&tokenizer, settings, this);
} }
@ -418,13 +418,13 @@ private:
check("void f(int x) {\n" check("void f(int x) {\n"
" int y = 17 / x;\n" " int y = 17 / x;\n"
" if (x == 0) {}\n" " if (x == 0) {}\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Either the condition 'x==0' is useless or there is division by zero at line 2.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Either the condition 'x==0' is useless or there is division by zero at line 2.\n", errout.str());
check("void f(unsigned int x) {\n" check("void f(unsigned int x) {\n"
" int y = 17 / x;\n" " int y = 17 / x;\n"
" if (x != 0) {}\n" " if (x != 0) {}\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Either the condition 'x!=0' is useless or there is division by zero at line 2.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Either the condition 'x!=0' is useless or there is division by zero at line 2.\n", errout.str());
// function call // function call
@ -441,7 +441,7 @@ private:
" int y = 17 / x;\n" " int y = 17 / x;\n"
" x = some+calculation;\n" " x = some+calculation;\n"
" if (x != 0) {}\n" " if (x != 0) {}\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
{ {
@ -452,7 +452,7 @@ private:
" int y = 17 / x;\n" " int y = 17 / x;\n"
" do_something();\n" " do_something();\n"
" if (x != 0) {}\n" " if (x != 0) {}\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// function is called. but don't care, variable is local // function is called. but don't care, variable is local
@ -462,7 +462,7 @@ private:
" int y = 17 / x;\n" " int y = 17 / x;\n"
" do_something();\n" " do_something();\n"
" if (x != 0) {}\n" " if (x != 0) {}\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:4]: (warning) Either the condition 'x!=0' is useless or there is division by zero at line 4.\n", errout.str()); ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:4]: (warning) Either the condition 'x!=0' is useless or there is division by zero at line 4.\n", errout.str());
} }
@ -477,7 +477,7 @@ private:
"void f() {\n" "void f() {\n"
" int y = 17 / x;\n" " int y = 17 / x;\n"
" while (y || x == 0) { x--; }\n" " while (y || x == 0) { x--; }\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// ticket 5033 segmentation fault (valid code) in CheckOther::checkZeroDivisionOrUselessCondition // ticket 5033 segmentation fault (valid code) in CheckOther::checkZeroDivisionOrUselessCondition
@ -500,19 +500,19 @@ private:
check("int f(int d) {\n" check("int f(int d) {\n"
" int r = (a?b:c) / d;\n" " int r = (a?b:c) / d;\n"
" if (d == 0) {}\n" " if (d == 0) {}\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Either the condition 'd==0' is useless or there is division by zero at line 2.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Either the condition 'd==0' is useless or there is division by zero at line 2.\n", errout.str());
check("int f(int a) {\n" check("int f(int a) {\n"
" int r = a ? 1 / a : 0;\n" " int r = a ? 1 / a : 0;\n"
" if (a == 0) {}\n" " if (a == 0) {}\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int f(int a) {\n" check("int f(int a) {\n"
" int r = (a == 0) ? 0 : 1 / a;\n" " int r = (a == 0) ? 0 : 1 / a;\n"
" if (a == 0) {}\n" " if (a == 0) {}\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -3209,7 +3209,7 @@ private:
" for (i == 0; i < 10; i ++) {\n" " for (i == 0; i < 10; i ++) {\n"
" c ++;\n" " c ++;\n"
" }\n" " }\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead?\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead?\n", errout.str());
check("void foo(int c) {\n" check("void foo(int c) {\n"
@ -3266,7 +3266,7 @@ private:
" for (int i = (x == 0) ? 0 : 5; i < 10; i ++) {\n" " for (int i = (x == 0) ? 0 : 5; i < 10; i ++) {\n"
" x++;\n" " x++;\n"
" }\n" " }\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(int x) {\n" check("void foo(int x) {\n"
@ -3348,7 +3348,7 @@ private:
check("void f(int x) {\n" check("void f(int x) {\n"
" x = (x != 0);" " x = (x != 0);"
" func(x);\n" " func(x);\n"
"}"); "}", nullptr, false, true, false, true, nullptr, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// ticket #3001 - false positive // ticket #3001 - false positive
@ -3749,12 +3749,12 @@ private:
void clarifyCalculation() { void clarifyCalculation() {
check("int f(char c) {\n" check("int f(char c) {\n"
" return 10 * (c == 0) ? 1 : 2;\n" " return 10 * (c == 0) ? 1 : 2;\n"
"}"); "}", nullptr, false, false, false, true, nullptr, false);
ASSERT_EQUALS("[test.cpp:2]: (style) Clarify calculation precedence for '*' and '?'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Clarify calculation precedence for '*' and '?'.\n", errout.str());
check("void f(char c) {\n" check("void f(char c) {\n"
" printf(\"%i\", 10 * (c == 0) ? 1 : 2);\n" " printf(\"%i\", 10 * (c == 0) ? 1 : 2);\n"
"}"); "}", nullptr, false, false, false, true, nullptr, false);
ASSERT_EQUALS("[test.cpp:2]: (style) Clarify calculation precedence for '*' and '?'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Clarify calculation precedence for '*' and '?'.\n", errout.str());
check("void f() {\n" check("void f() {\n"
@ -4264,7 +4264,7 @@ private:
check("void foo() {\n" check("void foo() {\n"
" if ((strcmp(a, b) == 0) || (strcmp(a, b) == 0)) {}\n" " if ((strcmp(a, b) == 0) || (strcmp(a, b) == 0)) {}\n"
"}", "test.cpp", false, false, false, true, &settings_std); "}", "test.cpp", false, false, false, true, &settings_std, false);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Same expression on both sides of '||'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Same expression on both sides of '||'.\n", errout.str());
check("void GetValue() { return rand(); }\n" check("void GetValue() { return rand(); }\n"

View File

@ -104,7 +104,9 @@ private:
TEST_CASE(test_4881); // similar to doWhileAssign (#4911), taken from #4881 with full code TEST_CASE(test_4881); // similar to doWhileAssign (#4911), taken from #4881 with full code
// "if(0==x)" => "if(!x)" // "if(0==x)" => "if(!x)"
TEST_CASE(ifnot); TEST_CASE(simplifyIfNot);
TEST_CASE(simplifyIfNotNull);
TEST_CASE(combine_wstrings); TEST_CASE(combine_wstrings);
// Simplify "not" to "!" (#345) // Simplify "not" to "!" (#345)
@ -261,7 +263,6 @@ private:
TEST_CASE(removeUnnecessaryQualification9); // ticket #3151 TEST_CASE(removeUnnecessaryQualification9); // ticket #3151
TEST_CASE(removeUnnecessaryQualification10); // ticket #3310 segmentation fault TEST_CASE(removeUnnecessaryQualification10); // ticket #3310 segmentation fault
TEST_CASE(simplifyIfNotNull);
TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault
TEST_CASE(simplifyVarDecl2); // ticket # 2834 segmentation fault TEST_CASE(simplifyVarDecl2); // ticket # 2834 segmentation fault
TEST_CASE(return_strncat); // ticket # 2860 Returning value of strncat() reported as memory leak TEST_CASE(return_strncat); // ticket # 2860 Returning value of strncat() reported as memory leak
@ -1672,17 +1673,24 @@ private:
ASSERT_EQUALS("; do { current = f ( ) ; } while ( ( current ) != 0 ) ;", simplifyIfAndWhileAssign(";do { } while((current=f()) != NULL);")); ASSERT_EQUALS("; do { current = f ( ) ; } while ( ( current ) != 0 ) ;", simplifyIfAndWhileAssign(";do { } while((current=f()) != NULL);"));
} }
void ifnot() { void simplifyIfNot() {
ASSERT_EQUALS("if ( ! x ) { ; }", tok("if(0==x);", false)); ASSERT_EQUALS("if ( ! x ) { ; }", tok("if(0==x);"));
ASSERT_EQUALS("if ( ! x ) { ; }", tok("if(x==0);", false)); ASSERT_EQUALS("if ( ! x ) { ; }", tok("if(x==0);"));
ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", tok("if(0==(a=b));", false)); ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", tok("if(0==(a=b));"));
ASSERT_EQUALS("if ( ! a && b ( ) ) { ; }", tok("if( 0 == a && b() );", false)); ASSERT_EQUALS("if ( ! a && b ( ) ) { ; }", tok("if( 0 == a && b() );"));
ASSERT_EQUALS("if ( b ( ) && ! a ) { ; }", tok("if( b() && 0 == a );", false)); ASSERT_EQUALS("if ( b ( ) && ! a ) { ; }", tok("if( b() && 0 == a );"));
ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", tok("if((a=b)==0);", false)); ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", tok("if((a=b)==0);"));
ASSERT_EQUALS("if ( ! x . y ) { ; }", tok("if(x.y==0);", false)); ASSERT_EQUALS("if ( ! x . y ) { ; }", tok("if(x.y==0);"));
ASSERT_EQUALS("if ( ! x ) { ; }", tok("if((x==0));", false)); ASSERT_EQUALS("if ( ! x ) { ; }", tok("if((x==0));"));
ASSERT_EQUALS("if ( ( ! x ) && ! y ) { ; }", tok("if((x==0) && y==0);", false)); ASSERT_EQUALS("if ( ( ! x ) && ! y ) { ; }", tok("if((x==0) && y==0);"));
ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) ) { ; }", tok("if(!(fclose(fd) == 0));", false)); ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) ) { ; }", tok("if(!(fclose(fd) == 0));"));
}
void simplifyIfNotNull() {
const char code[] = "void f(int x) {\n"
" x = (x != 0);\n"
"}";
ASSERT_EQUALS("void f ( int x ) { }", tok(code, true));
} }
void not1() { void not1() {
@ -4004,22 +4012,6 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void simplifyIfNotNull() {
{
// ticket # 2601 segmentation fault
const char code[] = "|| #if #define <=";
tok(code, false);
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f(int x) {\n"
" x = (x != 0);\n"
"}";
ASSERT_EQUALS("void f ( int x ) { }", tok(code, false));
}
}
void simplifyVarDecl1() { // ticket # 2682 segmentation fault void simplifyVarDecl1() { // ticket # 2682 segmentation fault
const char code[] = "x a[0] ="; const char code[] = "x a[0] =";
tok(code, false); tok(code, false);

View File

@ -395,7 +395,7 @@ private:
check("void foo(char* c) {\n" check("void foo(char* c) {\n"
" if(c == '\\0') bar();\n" " if(c == '\\0') bar();\n"
"}"); "}");
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) Char literal compared with pointer 'c'. Did you intend to dereference it?\n", "", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (warning) Char literal compared with pointer 'c'. Did you intend to dereference it?\n", errout.str());
check("void f() {\n" check("void f() {\n"
" struct { struct { char *str; } x; } a;\n" " struct { struct { char *str; } x; } a;\n"

View File

@ -259,7 +259,7 @@ private:
TEST_CASE(simplify_constants4); TEST_CASE(simplify_constants4);
TEST_CASE(simplify_constants5); TEST_CASE(simplify_constants5);
TEST_CASE(simplify_constants6); // Ticket #5625: Ternary operator as template parameter TEST_CASE(simplify_constants6); // Ticket #5625: Ternary operator as template parameter
TEST_CASE(simplify_null); TEST_CASE(simplifyNull);
TEST_CASE(simplifyMulAndParens); // Ticket #2784 + #3184 TEST_CASE(simplifyMulAndParens); // Ticket #2784 + #3184
TEST_CASE(simplifyStructDecl); TEST_CASE(simplifyStructDecl);
@ -396,8 +396,6 @@ private:
TEST_CASE(simplifyOperatorName8); // ticket #5706 TEST_CASE(simplifyOperatorName8); // ticket #5706
TEST_CASE(simplifyOperatorName9); // ticket #5709 - comma operator not properly tokenized TEST_CASE(simplifyOperatorName9); // ticket #5709 - comma operator not properly tokenized
TEST_CASE(simplifyNull);
TEST_CASE(simplifyNullArray); TEST_CASE(simplifyNullArray);
// Some simple cleanups of unhandled macros in the global scope // Some simple cleanups of unhandled macros in the global scope
@ -1867,7 +1865,7 @@ private:
"{" "{"
" int i ;" " int i ;"
" for ( i = 0 ; i < 10 ; ++ i ) {" " for ( i = 0 ; i < 10 ; ++ i ) {"
" if ( ! * str ) { goto label ; }" " if ( * str == 0 ) { goto label ; }"
" }" " }"
" return ;" " return ;"
" label : ;" " label : ;"
@ -3336,7 +3334,7 @@ private:
" return;" " return;"
"}"; "}";
ASSERT_EQUALS("void foo ( ) { if ( ! s ) { return ; } }", tokenizeAndStringify(code)); ASSERT_EQUALS("void foo ( ) { if ( s == 0 ) { return ; } }", tokenizeAndStringify(code));
} }
void removeParentheses3() { void removeParentheses3() {
@ -3449,7 +3447,7 @@ private:
} }
void removeParentheses14() { void removeParentheses14() {
ASSERT_EQUALS("; if ( ! ( i & 1 ) ) { ; } ;", tokenizeAndStringify("; if ( (i & 1) == 0 ); ;", false)); ASSERT_EQUALS("; if ( ( i & 1 ) == 0 ) { ; } ;", tokenizeAndStringify("; if ( (i & 1) == 0 ); ;", false));
} }
void removeParentheses15() { void removeParentheses15() {
@ -3678,7 +3676,7 @@ private:
} }
} }
void simplify_null() { void simplifyNull() {
{ {
const char code[] = const char code[] =
"int * p = NULL;\n" "int * p = NULL;\n"
@ -3689,7 +3687,11 @@ private:
} }
ASSERT_EQUALS("( a == nullptr )", tokenizeAndStringify("(a==nullptr)", false, false, Settings::Unspecified, "test.c")); ASSERT_EQUALS("( a == nullptr )", tokenizeAndStringify("(a==nullptr)", false, false, Settings::Unspecified, "test.c"));
ASSERT_EQUALS("( ! a )", tokenizeAndStringify("(a==nullptr)", false, false, Settings::Unspecified, "test.cpp")); ASSERT_EQUALS("( a == 0 )", tokenizeAndStringify("(a==nullptr)", false, false, Settings::Unspecified, "test.cpp"));
ASSERT_EQUALS("if ( p == 0 )", tokenizeAndStringify("if (p==NULL)"));
ASSERT_EQUALS("f ( NULL ) ;", tokenizeAndStringify("f(NULL);"));
ASSERT_EQUALS("char * i ; i = 0 ;", tokenizeAndStringify("char* i = (NULL);"));
} }
void simplifyMulAndParens() { void simplifyMulAndParens() {
@ -6217,12 +6219,6 @@ private:
ASSERT_EQUALS(code, tokenizeAndStringify(code)); ASSERT_EQUALS(code, tokenizeAndStringify(code));
} }
void simplifyNull() {
ASSERT_EQUALS("if ( ! p )", tokenizeAndStringify("if (p==NULL)"));
ASSERT_EQUALS("f ( NULL ) ;", tokenizeAndStringify("f(NULL);"));
ASSERT_EQUALS("char * i ; i = 0 ;", tokenizeAndStringify("char* i = (NULL);"));
}
void simplifyNullArray() { void simplifyNullArray() {
ASSERT_EQUALS("* ( foo . bar [ 5 ] ) = x ;", tokenizeAndStringify("0[foo.bar[5]] = x;")); ASSERT_EQUALS("* ( foo . bar [ 5 ] ) = x ;", tokenizeAndStringify("0[foo.bar[5]] = x;"));
} }

View File

@ -2555,7 +2555,7 @@ private:
checkUninitVar2("static void f(int x, int y) {\n" checkUninitVar2("static void f(int x, int y) {\n"
" int a;\n" " int a;\n"
" if (x == 0 && (a == 1)) { }\n" " if (x == 0 && (a == 1)) { }\n"
"}"); "}", "test.cpp", false);
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
checkUninitVarB("void f() {\n" checkUninitVarB("void f() {\n"
@ -3002,7 +3002,7 @@ private:
" if (y != 0) return;\n" " if (y != 0) return;\n"
" i++;\n" " i++;\n"
" }\n" " }\n"
"}"); "}", "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar2("void f() {\n" checkUninitVar2("void f() {\n"
@ -3012,7 +3012,7 @@ private:
" if (y != 0) return;\n" " if (y != 0) return;\n"
" i++;\n" " i++;\n"
" }\n" " }\n"
"}"); "}", "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVarB("void f() {\n" checkUninitVarB("void f() {\n"
@ -3399,7 +3399,7 @@ private:
" struct FRED fred;\n" " struct FRED fred;\n"
" fred.a = do_something();\n" " fred.a = do_something();\n"
" if (fred.b == 0) { }\n" " if (fred.b == 0) { }\n"
"}\n", "test.c"); "}\n", "test.c", false);
ASSERT_EQUALS("[test.c:9]: (error) Uninitialized struct member: fred.b\n", errout.str()); ASSERT_EQUALS("[test.c:9]: (error) Uninitialized struct member: fred.b\n", errout.str());
checkUninitVar2("struct Fred { int a; };\n" checkUninitVar2("struct Fred { int a; };\n"