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())
|
if (tok->varId() != var.declarationId())
|
||||||
continue;
|
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 (!membervar.empty()) {
|
||||||
if (isMemberVariableAssignment(tok, membervar)) {
|
if (isMemberVariableAssignment(tok, membervar)) {
|
||||||
bool assign = true;
|
bool assign = true;
|
||||||
|
@ -924,17 +932,22 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isMemberVariableUsage(tok, var.isPointer(), alloc, membervar)) {
|
||||||
if (isMemberVariableUsage(tok, var.isPointer(), alloc, membervar))
|
if (!conditionalUsage)
|
||||||
return tok;
|
return tok;
|
||||||
else if (Token::Match(tok->previous(), "[(,] %name% [,)]")) {
|
if (!errorToken)
|
||||||
|
errorToken = tok;
|
||||||
|
} else if (Token::Match(tok->previous(), "[(,] %name% [,)]")) {
|
||||||
bailout = true;
|
bailout = true;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (const Token *errtok = isVariableUsage(tok, var.isPointer(), alloc))
|
if (const Token *errtok = isVariableUsage(tok, var.isPointer(), alloc)) {
|
||||||
|
if (!conditionalUsage)
|
||||||
return errtok;
|
return errtok;
|
||||||
else if (tok->strAt(1) == "=") {
|
if (!errorToken)
|
||||||
|
errorToken = errtok;
|
||||||
|
} else if (tok->strAt(1) == "=") {
|
||||||
bool varIsUsedInRhs = false;
|
bool varIsUsedInRhs = false;
|
||||||
visitAstNodes(tok->next()->astOperand2(), [&](const Token * t) {
|
visitAstNodes(tok->next()->astOperand2(), [&](const Token * t) {
|
||||||
if (!t)
|
if (!t)
|
||||||
|
|
|
@ -1233,6 +1233,31 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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
|
// Ticket #2226: C++0x loop
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" container c;\n"
|
" container c;\n"
|
||||||
|
|
Loading…
Reference in New Issue