Uninitialized variables: Fixed TODO testcase
This commit is contained in:
parent
e214d94589
commit
68327b3c64
|
@ -1079,7 +1079,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
||||||
while (tok && tok->str() != ";")
|
while (tok && tok->str() != ";")
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
if (stdtype || i->isPointer())
|
if (stdtype || i->isPointer())
|
||||||
checkScopeForVariable(tok, *i, NULL);
|
checkScopeForVariable(tok, *i, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::list<Scope*>::const_iterator i = scope->nestedList.begin(); i != scope->nestedList.end(); ++i) {
|
for (std::list<Scope*>::const_iterator i = scope->nestedList.begin(); i != scope->nestedList.end(); ++i) {
|
||||||
|
@ -1088,7 +1088,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit)
|
bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn)
|
||||||
{
|
{
|
||||||
const bool suppressErrors(possibleInit && *possibleInit);
|
const bool suppressErrors(possibleInit && *possibleInit);
|
||||||
|
|
||||||
|
@ -1117,7 +1117,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
||||||
|
|
||||||
// Unconditional inner scope..
|
// Unconditional inner scope..
|
||||||
if (tok->str() == "{" && Token::Match(tok->previous(), "[;{}]")) {
|
if (tok->str() == "{" && Token::Match(tok->previous(), "[;{}]")) {
|
||||||
if (checkScopeForVariable(tok->next(), var, possibleInit))
|
if (checkScopeForVariable(tok->next(), var, possibleInit, NULL))
|
||||||
return true;
|
return true;
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
continue;
|
continue;
|
||||||
|
@ -1144,7 +1144,8 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
||||||
break;
|
break;
|
||||||
if (tok->str() == "{") {
|
if (tok->str() == "{") {
|
||||||
bool possibleInitIf(number_of_if > 0 || suppressErrors);
|
bool possibleInitIf(number_of_if > 0 || suppressErrors);
|
||||||
const bool initif = checkScopeForVariable(tok->next(), var, &possibleInitIf);
|
bool noreturnIf = false;
|
||||||
|
const bool initif = checkScopeForVariable(tok->next(), var, &possibleInitIf, &noreturnIf);
|
||||||
|
|
||||||
// goto the }
|
// goto the }
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
|
@ -1160,7 +1161,8 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
||||||
tok = tok->tokAt(2);
|
tok = tok->tokAt(2);
|
||||||
|
|
||||||
bool possibleInitElse(number_of_if > 0 || suppressErrors);
|
bool possibleInitElse(number_of_if > 0 || suppressErrors);
|
||||||
const bool initelse = checkScopeForVariable(tok->next(), var, &possibleInitElse);
|
bool noreturnElse = false;
|
||||||
|
const bool initelse = checkScopeForVariable(tok->next(), var, &possibleInitElse, NULL);
|
||||||
|
|
||||||
// goto the }
|
// goto the }
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
|
@ -1168,6 +1170,9 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
||||||
if (initif && initelse)
|
if (initif && initelse)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if ((initif && noreturnElse) || (initelse && noreturnIf))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (initif || initelse || possibleInitElse)
|
if (initif || initelse || possibleInitElse)
|
||||||
++number_of_if;
|
++number_of_if;
|
||||||
}
|
}
|
||||||
|
@ -1203,7 +1208,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
||||||
|
|
||||||
if (tok2 && tok2->str() == "{") {
|
if (tok2 && tok2->str() == "{") {
|
||||||
bool possibleinit = true;
|
bool possibleinit = true;
|
||||||
bool init = checkScopeForVariable(tok2->next(), var, &possibleinit);
|
bool init = checkScopeForVariable(tok2->next(), var, &possibleinit, NULL);
|
||||||
|
|
||||||
// variable is initialized in the loop..
|
// variable is initialized in the loop..
|
||||||
if (possibleinit || init)
|
if (possibleinit || init)
|
||||||
|
@ -1213,6 +1218,9 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
||||||
if (!suppressErrors) {
|
if (!suppressErrors) {
|
||||||
checkIfForWhileHead(tok->next(), var, false, bool(number_of_if == 0));
|
checkIfForWhileHead(tok->next(), var, false, bool(number_of_if == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// goto "}"
|
||||||
|
tok = tok2->link();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1226,9 +1234,12 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok, "return|break|continue|throw|goto"))
|
if (Token::Match(tok, "return|break|continue|throw|goto")) {
|
||||||
ret = true;
|
if (noreturn)
|
||||||
else if (ret && tok->str() == ";")
|
*noreturn = true;
|
||||||
|
else
|
||||||
|
ret = true;
|
||||||
|
} else if (tok->str() == "goto")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// variable is seen..
|
// variable is seen..
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
/** Check for uninitialized variables */
|
/** Check for uninitialized variables */
|
||||||
void check();
|
void check();
|
||||||
void checkScope(const Scope* scope);
|
void checkScope(const Scope* scope);
|
||||||
bool checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit);
|
bool checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn);
|
||||||
bool checkIfForWhileHead(const Token *startparanthesis, const Variable& var, bool suppressErrors, bool isuninit);
|
bool checkIfForWhileHead(const Token *startparanthesis, const Variable& var, bool suppressErrors, bool isuninit);
|
||||||
bool isVariableUsage(const Token *vartok, bool ispointer) const;
|
bool isVariableUsage(const Token *vartok, bool ispointer) const;
|
||||||
|
|
||||||
|
|
|
@ -2077,13 +2077,18 @@ private:
|
||||||
checkUninitVar2("void f() {\n"
|
checkUninitVar2("void f() {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
" if (y == 1) { return; }\n"
|
" if (y == 1) { return; }\n"
|
||||||
" if (y == 2) { break; }\n"
|
|
||||||
" if (y == 3) { continue; }\n"
|
|
||||||
" else { x = 1; }\n"
|
" else { x = 1; }\n"
|
||||||
" return x;\n"
|
" return x;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("void f() {\n"
|
||||||
|
" int x;\n"
|
||||||
|
" if (y == 1) { return; }\n"
|
||||||
|
" return x;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar2("void f() {\n"
|
checkUninitVar2("void f() {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
" return;\n"
|
" return;\n"
|
||||||
|
@ -2109,7 +2114,7 @@ private:
|
||||||
" if (foo) break;\n"
|
" if (foo) break;\n"
|
||||||
" return x;\n"
|
" return x;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
TODO_ASSERT_EQUALS("error", "", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: x\n", errout.str());
|
||||||
|
|
||||||
// if goto is simplified there might be conditions that are always true
|
// if goto is simplified there might be conditions that are always true
|
||||||
checkUninitVar2("void f() {\n"
|
checkUninitVar2("void f() {\n"
|
||||||
|
|
Loading…
Reference in New Issue