Merge branch 'master' of github.com:danmar/cppcheck
This commit is contained in:
commit
233210a619
|
@ -1081,7 +1081,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
|||
while (tok && tok->str() != ";")
|
||||
tok = tok->next();
|
||||
if (stdtype || i->isPointer())
|
||||
checkScopeForVariable(scope, tok, *i, NULL, NULL, NULL);
|
||||
checkScopeForVariable(scope, tok, *i, NULL, NULL, "");
|
||||
if (Token::Match(i->typeStartToken(), "struct %type% %var% ;")) {
|
||||
const std::string structname(i->typeStartToken()->next()->str());
|
||||
const SymbolDatabase * symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
@ -1089,7 +1089,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
|||
const Scope *scope2 = symbolDatabase->classAndStructScopes[j];
|
||||
if (scope2->className == structname && scope2->numConstructors == 0U) {
|
||||
for (std::list<Variable>::const_iterator it = scope2->varlist.begin(); it != scope2->varlist.end(); ++it)
|
||||
checkScopeForVariable(scope, tok, *i, NULL, NULL, &(*it));
|
||||
checkScopeForVariable(scope, tok, *i, NULL, NULL, it->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1101,7 +1101,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
|||
}
|
||||
}
|
||||
|
||||
bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, const Variable * const membervar)
|
||||
bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, const std::string &membervar)
|
||||
{
|
||||
const bool suppressErrors(possibleInit && *possibleInit);
|
||||
|
||||
|
@ -1156,7 +1156,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
|||
}
|
||||
|
||||
// initialization / usage in condition..
|
||||
if (!alwaysTrue && checkIfForWhileHead(scope, tok->next(), var, suppressErrors || (membervar != NULL), bool(number_of_if == 0)))
|
||||
if (!alwaysTrue && checkIfForWhileHead(scope, tok->next(), var, suppressErrors, bool(number_of_if == 0), membervar))
|
||||
return true;
|
||||
|
||||
// checking if a not-zero variable is zero => bail out
|
||||
|
@ -1281,7 +1281,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
|||
// for/while..
|
||||
if (Token::Match(tok, "for|while (")) {
|
||||
// is variable initialized in for-head (don't report errors yet)?
|
||||
if (checkIfForWhileHead(scope, tok->next(), var, true, false))
|
||||
if (checkIfForWhileHead(scope, tok->next(), var, true, false, membervar))
|
||||
return true;
|
||||
|
||||
// goto the {
|
||||
|
@ -1297,7 +1297,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
|||
|
||||
// is variable used in for-head?
|
||||
if (!suppressErrors) {
|
||||
checkIfForWhileHead(scope, tok->next(), var, false, bool(number_of_if == 0));
|
||||
checkIfForWhileHead(scope, tok->next(), var, false, bool(number_of_if == 0), membervar);
|
||||
}
|
||||
|
||||
// goto "}"
|
||||
|
@ -1321,7 +1321,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
|||
|
||||
while (tok && tok->str() != ";") {
|
||||
// variable is seen..
|
||||
if (tok->varId() == var.varId() && (membervar == NULL)) {
|
||||
if (tok->varId() == var.varId() && (membervar.empty())) {
|
||||
// Use variable
|
||||
if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer()))
|
||||
uninitvarError(tok, tok->str());
|
||||
|
@ -1342,12 +1342,12 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
|||
|
||||
// variable is seen..
|
||||
if (tok->varId() == var.varId()) {
|
||||
if (membervar) {
|
||||
if (Token::Match(tok, "%var% . %var%") && tok->strAt(2) == membervar->name()) {
|
||||
if (!membervar.empty()) {
|
||||
if (Token::Match(tok, "%var% . %var%") && tok->strAt(2) == membervar) {
|
||||
if (Token::Match(tok->tokAt(3), "[=.[]"))
|
||||
return true;
|
||||
else if (Token::Match(tok->previous(), "%op%") || Token::Match(tok->previous(), "[|="))
|
||||
uninitStructMemberError(tok, tok->str() + "." + membervar->name());
|
||||
uninitStructMemberError(tok, tok->str() + "." + membervar);
|
||||
else
|
||||
return true;
|
||||
} else if (tok->strAt(1) == "=")
|
||||
|
@ -1355,7 +1355,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
|||
else if (tok->strAt(-1) == "&")
|
||||
return true;
|
||||
else if (Token::Match(tok->previous(), "[(,] %var% [,)]") && isVariableUsage(scope, tok, var.isPointer()))
|
||||
uninitStructMemberError(tok, tok->str() + "." + membervar->name());
|
||||
uninitStructMemberError(tok, tok->str() + "." + membervar);
|
||||
} else {
|
||||
// Use variable
|
||||
if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer()))
|
||||
|
@ -1371,11 +1371,17 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CheckUninitVar::checkIfForWhileHead(const Scope *scope, const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit)
|
||||
bool CheckUninitVar::checkIfForWhileHead(const Scope *scope, const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, const std::string &membervar)
|
||||
{
|
||||
const Token * const endpar = startparentheses->link();
|
||||
for (const Token *tok = startparentheses->next(); tok && tok != endpar; tok = tok->next()) {
|
||||
if (tok->varId() == var.varId()) {
|
||||
if (Token::Match(tok, "%var% . %var%")) {
|
||||
if (tok->strAt(2) == membervar)
|
||||
uninitStructMemberError(tok, tok->str() + "." + membervar);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isVariableUsage(scope, tok, var.isPointer())) {
|
||||
if (!suppressErrors)
|
||||
uninitvarError(tok, tok->str());
|
||||
|
|
|
@ -64,8 +64,8 @@ public:
|
|||
/** Check for uninitialized variables */
|
||||
void check();
|
||||
void checkScope(const Scope* scope);
|
||||
bool checkScopeForVariable(const Scope* scope, const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, const Variable * const membervar);
|
||||
bool checkIfForWhileHead(const Scope *scope, const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit);
|
||||
bool checkScopeForVariable(const Scope* scope, const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, const std::string &membervar);
|
||||
bool checkIfForWhileHead(const Scope *scope, const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, const std::string &membervar);
|
||||
bool isVariableUsage(const Scope* scope, const Token *vartok, bool ispointer) const;
|
||||
|
||||
|
||||
|
|
|
@ -6253,6 +6253,7 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign
|
|||
if (!Token::Match(tok3->previous(), "( %var% )") &&
|
||||
Token::Match(tok3->previous(), "&&|(|%oror% %varid% &&|%oror%|)", varid)) {
|
||||
tok3->str(value);
|
||||
tok3->varId(valueVarId);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
|
@ -6261,6 +6262,7 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign
|
|||
// If the parameter is passed by value then simplify it
|
||||
if (isFunctionParameterPassedByValue(tok3)) {
|
||||
tok3->str(value);
|
||||
tok3->varId(valueVarId);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
@ -7588,7 +7590,10 @@ bool Tokenizer::isFunctionParameterPassedByValue(const Token *fpar) const
|
|||
|
||||
// Is this a function call?
|
||||
if (ftok && Token::Match(ftok->tokAt(-2), "[;{}=] %var% (")) {
|
||||
const std::string functionName(ftok->previous()->str() + " (");
|
||||
const std::string functionName(ftok->previous()->str());
|
||||
|
||||
if (functionName == "return")
|
||||
return true;
|
||||
|
||||
// Locate function declaration..
|
||||
unsigned int indentlevel = 0;
|
||||
|
@ -7597,7 +7602,7 @@ bool Tokenizer::isFunctionParameterPassedByValue(const Token *fpar) const
|
|||
++indentlevel;
|
||||
else if (tok->str() == "}")
|
||||
indentlevel = (indentlevel > 0) ? indentlevel - 1U : 0U;
|
||||
else if (indentlevel == 0 && tok->isName() && Token::simpleMatch(tok, functionName.c_str())) {
|
||||
else if (indentlevel == 0 && Token::Match(tok, "%type% (") && tok->str() == functionName) {
|
||||
// Goto parameter
|
||||
tok = tok->tokAt(2);
|
||||
unsigned int par = 1;
|
||||
|
|
|
@ -180,6 +180,7 @@ private:
|
|||
TEST_CASE(simplifyKnownVariablesFloat); // #2454 - float variable
|
||||
TEST_CASE(simplifyKnownVariablesClassMember); // #2815 - value of class member may be changed by function call
|
||||
TEST_CASE(simplifyKnownVariablesFunctionCalls); // Function calls (don't assume pass by reference)
|
||||
TEST_CASE(simplifyKnownVariablesReturn); // 3500 - return
|
||||
TEST_CASE(simplifyExternC);
|
||||
|
||||
TEST_CASE(varid1);
|
||||
|
@ -2782,6 +2783,14 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void simplifyKnownVariablesReturn() {
|
||||
const char code[] = "int a() {"
|
||||
" int x = 123;"
|
||||
" return (x);"
|
||||
"}";
|
||||
ASSERT_EQUALS("int a ( ) { return 123 ; }", tokenizeAndStringify(code,true));
|
||||
}
|
||||
|
||||
void simplifyKnownVariablesClassMember() {
|
||||
// Ticket #2815
|
||||
{
|
||||
|
|
|
@ -2661,7 +2661,7 @@ private:
|
|||
" fred.a = do_something();\n"
|
||||
" if (fred.b == 0) { }\n"
|
||||
"}\n", "test.c", true);
|
||||
TODO_ASSERT_EQUALS("error", "", errout.str());
|
||||
ASSERT_EQUALS("[test.c:9]: (error) Uninitialized struct member: fred.b\n", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue