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

View File

@ -361,20 +361,50 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(int& i)\n" check("void foo(int& i) {\n"
"{\n"
" i=6;\n" " i=6;\n"
"}\n" "}\n"
"void bar(int i)\n" "void bar(int i) {\n"
"{\n" " if(i>5) {\n"
" if(i>5){\n"
" foo(i);\n" " foo(i);\n"
" if(i<5){\n" " if(i<5) {\n"
" }\n" " }\n"
" }\n" " }\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); 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 // see linux revision 1f80c0cc
check("int generic_write_sync(int,int,int);\n" check("int generic_write_sync(int,int,int);\n"
"\n" "\n"