Uninitialized variables; Improved checking of loops
This commit is contained in:
parent
8e650e4243
commit
4746d4b819
|
@ -891,6 +891,14 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
|
|||
if (tok->varId() != var.declarationId())
|
||||
continue;
|
||||
|
||||
bool conditionalUsage = false;
|
||||
for (const Token* parent = tok; parent; parent = parent->astParent()) {
|
||||
if (Token::Match(parent->astParent(), "%oror%|&&|?") && astIsRHS(parent)) {
|
||||
conditionalUsage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!membervar.empty()) {
|
||||
if (isMemberVariableAssignment(tok, membervar)) {
|
||||
bool assign = true;
|
||||
|
@ -924,17 +932,22 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (isMemberVariableUsage(tok, var.isPointer(), alloc, membervar))
|
||||
return tok;
|
||||
else if (Token::Match(tok->previous(), "[(,] %name% [,)]")) {
|
||||
if (isMemberVariableUsage(tok, var.isPointer(), alloc, membervar)) {
|
||||
if (!conditionalUsage)
|
||||
return tok;
|
||||
if (!errorToken)
|
||||
errorToken = tok;
|
||||
} else if (Token::Match(tok->previous(), "[(,] %name% [,)]")) {
|
||||
bailout = true;
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (const Token *errtok = isVariableUsage(tok, var.isPointer(), alloc))
|
||||
return errtok;
|
||||
else if (tok->strAt(1) == "=") {
|
||||
if (const Token *errtok = isVariableUsage(tok, var.isPointer(), alloc)) {
|
||||
if (!conditionalUsage)
|
||||
return errtok;
|
||||
if (!errorToken)
|
||||
errorToken = errtok;
|
||||
} else if (tok->strAt(1) == "=") {
|
||||
bool varIsUsedInRhs = false;
|
||||
visitAstNodes(tok->next()->astOperand2(), [&](const Token * t) {
|
||||
if (!t)
|
||||
|
|
|
@ -1233,6 +1233,31 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkUninitVar("void foo(void) {\n"
|
||||
" int a = 0;\n"
|
||||
" int x;\n"
|
||||
"\n"
|
||||
" for (;;) {\n"
|
||||
" if (!a || 12 < x) {\n" // <- x is not uninitialized
|
||||
" a = 1;\n"
|
||||
" x = 2;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkUninitVar("void foo(void) {\n"
|
||||
" int a = 0;\n"
|
||||
" int x;\n"
|
||||
"\n"
|
||||
" for (;;) {\n"
|
||||
" if (!a || 12 < x) {\n" // <- x is uninitialized
|
||||
" a = 1;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: x\n", errout.str());
|
||||
|
||||
// Ticket #2226: C++0x loop
|
||||
checkUninitVar("void f() {\n"
|
||||
" container c;\n"
|
||||
|
|
Loading…
Reference in New Issue