Fixed false positives and false negatives in 'oppositeInnerCondition' (among others: #5808)

This commit is contained in:
PKEuS 2014-05-21 14:38:41 +02:00
parent 01a0154daa
commit 48c3d02fc3
2 changed files with 43 additions and 16 deletions

View File

@ -3334,9 +3334,9 @@ void CheckOther::oppositeInnerCondition()
if (cond->varId()) {
vars.insert(cond->varId());
const Variable *var = cond->variable();
nonlocal |= (var && (!var->isLocal() || var->isStatic()));
nonlocal |= (var && (!var->isLocal() || var->isStatic()) && !var->isArgument());
// TODO: if var is pointer check what it points at
nonlocal |= (var && var->isPointer());
nonlocal |= (var && (var->isPointer() || var->isReference()));
} else if (cond->isName()) {
// varid is 0. this is possibly a nonlocal variable..
nonlocal |= (cond->astParent() && cond->astParent()->isConstOp());
@ -3360,17 +3360,14 @@ void CheckOther::oppositeInnerCondition()
break;
if (Token::Match(tok->previous(), "[(,] %var% [,)]")) {
// is variable unchanged? default is false..
bool unchanged = true;
bool unchanged = false;
// locate start parentheses in function call..
unsigned int argumentNumber = 0;
const Token *start = tok;
while (start && !Token::Match(start, "[;{}(]")) {
if (start->str() == ")")
start = start->link();
else if (start->str() == ",")
++argumentNumber;
start = start->previous();
const Token *start = tok->previous();
while (start && start->str() == ",") {
start = start->astParent();
++argumentNumber;
}
start = start ? start->previous() : nullptr;

View File

@ -361,20 +361,50 @@ private:
ASSERT_EQUALS("", errout.str());
check("void foo(int& i)\n"
"{\n"
check("void foo(int& i) {\n"
" i=6;\n"
"}\n"
"void bar(int i)\n"
"{\n"
" if(i>5){\n"
"void bar(int i) {\n"
" if(i>5) {\n"
" foo(i);\n"
" if(i<5){\n"
" if(i<5) {\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void foo(int& i);\n"
"void bar() {\n"
" int i; i = func();\n"
" if(i>5) {\n"
" foo(i);\n"
" if(i<5) {\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void foo(int i);\n"
"void bar(int i) {\n"
" if(i>5) {\n"
" foo(i);\n"
" if(i<5) {\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n", errout.str());
check("void foo(int i);\n"
"void bar() {\n"
" int i; i = func();\n"
" if(i>5) {\n"
" foo(i);\n"
" if(i<5) {\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n", errout.str());
// see linux revision 1f80c0cc
check("int generic_write_sync(int,int,int);\n"
"\n"