Uninitialized variables: fixed false positive

This commit is contained in:
Daniel Marjamäki 2013-01-28 18:08:20 +01:00
parent 859793731d
commit 3679a809dd
2 changed files with 19 additions and 5 deletions

View File

@ -1157,8 +1157,11 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
*possibleInit = true; *possibleInit = true;
// might be a noreturn function.. // might be a noreturn function..
if (_tokenizer->IsScopeNoReturn(tok)) if (_tokenizer->IsScopeNoReturn(tok)) {
if (noreturn)
*noreturn = true;
return true; return true;
}
break; break;
} }
@ -1226,7 +1229,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
} }
std::map<unsigned int, int> varValueIf; std::map<unsigned int, int> varValueIf;
if (!initif) { if (!initif && !noreturnIf) {
for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) { for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) {
if (Token::Match(tok2, "[;{}.] %var% = - %var% ;")) if (Token::Match(tok2, "[;{}.] %var% = - %var% ;"))
varValueIf[tok2->next()->varId()] = NOT_ZERO; varValueIf[tok2->next()->varId()] = NOT_ZERO;
@ -1256,7 +1259,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
const bool initelse = checkScopeForVariable(scope, tok->next(), var, &possibleInitElse, NULL, membervar); const bool initelse = checkScopeForVariable(scope, tok->next(), var, &possibleInitElse, NULL, membervar);
std::map<unsigned int, int> varValueElse; std::map<unsigned int, int> varValueElse;
if (!initelse) { if (!initelse && !noreturnElse) {
for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) { for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) {
if (Token::Match(tok2, "[;{}.] %var% = - %var% ;")) if (Token::Match(tok2, "[;{}.] %var% = - %var% ;"))
varValueElse[tok2->next()->varId()] = NOT_ZERO; varValueElse[tok2->next()->varId()] = NOT_ZERO;
@ -1266,7 +1269,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
} }
if (initelse && condVarId > 0U) if (initelse && condVarId > 0U && !noreturnIf && !noreturnElse)
variableValue[condVarId] = condVarValue; variableValue[condVarId] = condVarValue;
// goto the } // goto the }
@ -1278,7 +1281,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
if ((initif && noreturnElse) || (initelse && noreturnIf)) if ((initif && noreturnElse) || (initelse && noreturnIf))
return true; return true;
if (initif || initelse || possibleInitElse) { if ((initif || initelse || possibleInitElse) && !noreturnIf && !noreturnElse) {
++number_of_if; ++number_of_if;
variableValue.insert(varValueIf.begin(), varValueIf.end()); variableValue.insert(varValueIf.begin(), varValueIf.end());
variableValue.insert(varValueElse.begin(), varValueElse.end()); variableValue.insert(varValueElse.begin(), varValueElse.end());

View File

@ -2245,6 +2245,17 @@ private:
"}", "test.c"); "}", "test.c");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar2("int f(void) {\n"
" int a;\n"
" int i;\n"
" if (x) { noreturn(); }\n"
" else { i = 0; }\n"
" if (i==1) { a = 0; }\n"
" else { a = 1; }\n"
" return a;\n"
"}");
ASSERT_EQUALS("", errout.str());
// asm // asm
checkUninitVar2("void f() {\n" checkUninitVar2("void f() {\n"
" int x;\n" " int x;\n"