Refactoring, use early continue

This commit is contained in:
Daniel Marjamäki 2018-04-05 08:21:43 +02:00
parent 67a71fa362
commit 3ad6c7ebce
4 changed files with 131 additions and 131 deletions

View File

@ -273,13 +273,13 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token
if (isSameExpression(cpp, true, cond1->astOperand2(), cond2->astOperand2(), library, pure)) if (isSameExpression(cpp, true, cond1->astOperand2(), cond2->astOperand2(), library, pure))
return isDifferentKnownValues(cond1->astOperand1(), cond2->astOperand1()); return isDifferentKnownValues(cond1->astOperand1(), cond2->astOperand1());
} }
if (Library::isContainerYield(cond1, Library::Container::EMPTY, "empty") && if (Library::isContainerYield(cond1, Library::Container::EMPTY, "empty") &&
Library::isContainerYield(cond2->astOperand1(), Library::Container::SIZE, "size") && Library::isContainerYield(cond2->astOperand1(), Library::Container::SIZE, "size") &&
cond1->astOperand1()->astOperand1()->varId() == cond2->astOperand1()->astOperand1()->astOperand1()->varId()) { cond1->astOperand1()->astOperand1()->varId() == cond2->astOperand1()->astOperand1()->astOperand1()->varId()) {
return !(cond2->str() == "==" && cond2->astOperand2()->getValue(0)); return !(cond2->str() == "==" && cond2->astOperand2()->getValue(0));
} }
if (Library::isContainerYield(cond2, Library::Container::EMPTY, "empty") && if (Library::isContainerYield(cond2, Library::Container::EMPTY, "empty") &&
Library::isContainerYield(cond1->astOperand1(), Library::Container::SIZE, "size") && Library::isContainerYield(cond1->astOperand1(), Library::Container::SIZE, "size") &&
cond2->astOperand1()->astOperand1()->varId() == cond1->astOperand1()->astOperand1()->astOperand1()->varId()) { cond2->astOperand1()->astOperand1()->varId() == cond1->astOperand1()->astOperand1()->astOperand1()->varId()) {
return !(cond1->str() == "==" && cond1->astOperand2()->getValue(0)); return !(cond1->str() == "==" && cond1->astOperand2()->getValue(0));

View File

@ -1324,150 +1324,150 @@ void CheckBufferOverrun::checkStructVariable()
const Scope * scope = symbolDatabase->classAndStructScopes[i]; const Scope * scope = symbolDatabase->classAndStructScopes[i];
for (std::list<Variable>::const_iterator var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { for (std::list<Variable>::const_iterator var = scope->varlist.begin(); var != scope->varlist.end(); ++var) {
if (var->isArray()) { if (!var->isArray())
// create ArrayInfo from the array variable continue;
ArrayInfo arrayInfo(&*var, symbolDatabase); // create ArrayInfo from the array variable
ArrayInfo arrayInfo(&*var, symbolDatabase);
// find every function // find every function
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t j = 0; j < functions; ++j) { for (std::size_t j = 0; j < functions; ++j) {
const Scope * func_scope = symbolDatabase->functionScopes[j]; const Scope * func_scope = symbolDatabase->functionScopes[j];
// If struct is declared in a function then check // If struct is declared in a function then check
// if scope_func matches // if scope_func matches
if (scope->nestedIn->type == Scope::eFunction && if (scope->nestedIn->type == Scope::eFunction &&
scope->nestedIn != func_scope) { scope->nestedIn != func_scope) {
continue; continue;
}
// check for member variables
if (func_scope->functionOf == scope) {
// only check non-empty function
if (func_scope->classStart->next() != func_scope->classEnd) {
// start checking after the {
const Token *tok = func_scope->classStart->next();
checkScope(tok, arrayInfo);
} }
}
// check for member variables // skip inner scopes..
if (func_scope->functionOf == scope) { /** @todo false negatives: handle inner scopes someday */
// only check non-empty function if (scope->nestedIn->isClassOrStruct())
if (func_scope->classStart->next() != func_scope->classEnd) { continue;
// start checking after the {
const Token *tok = func_scope->classStart->next();
checkScope(tok, arrayInfo);
}
}
// skip inner scopes.. std::vector<const std::string*> varname;
/** @todo false negatives: handle inner scopes someday */ varname.push_back(NULL);
if (scope->nestedIn->isClassOrStruct()) varname.push_back(&arrayInfo.varname());
// search the function and it's parameters
for (const Token *tok3 = func_scope->classDef; tok3 && tok3 != func_scope->classEnd; tok3 = tok3->next()) {
// search for the class/struct name
if (tok3->str() != scope->className)
continue; continue;
std::vector<const std::string*> varname; // find all array variables
varname.push_back(NULL); int posOfSemicolon = -1;
varname.push_back(&arrayInfo.varname());
// search the function and it's parameters // Declare variable: Fred fred1;
for (const Token *tok3 = func_scope->classDef; tok3 && tok3 != func_scope->classEnd; tok3 = tok3->next()) { if (Token::Match(tok3->next(), "%var% ;"))
// search for the class/struct name varname[0] = &tok3->strAt(1);
if (tok3->str() != scope->className)
continue;
// find all array variables else if (isArrayOfStruct(tok3,posOfSemicolon))
int posOfSemicolon = -1; varname[0] = &tok3->strAt(1);
// Declare variable: Fred fred1; // Declare pointer or reference: Fred *fred1
if (Token::Match(tok3->next(), "%var% ;")) else if (Token::Match(tok3->next(), "*|& %var% [,);=]"))
varname[0] = &tok3->strAt(1); varname[0] = &tok3->strAt(2);
else if (isArrayOfStruct(tok3,posOfSemicolon)) else
varname[0] = &tok3->strAt(1); continue;
// Declare pointer or reference: Fred *fred1 // check for variable sized structure
else if (Token::Match(tok3->next(), "*|& %var% [,);=]")) if (scope->type == Scope::eStruct && var->isPublic()) {
varname[0] = &tok3->strAt(2); // last member of a struct with array size of 0 or 1 could be a variable sized structure
if (var->dimensions().size() == 1 && var->dimension(0) < 2 &&
var->index() == (scope->varlist.size() - 1)) {
// dynamically allocated so could be variable sized structure
if (tok3->next()->str() == "*") {
// check for allocation
if ((Token::Match(tok3->tokAt(3), "; %name% = malloc ( %num% ) ;") ||
(Token::Match(tok3->tokAt(3), "; %name% = (") &&
Token::Match(tok3->linkAt(6), ") malloc ( %num% ) ;"))) &&
(tok3->strAt(4) == tok3->strAt(2))) {
MathLib::bigint size;
else // find size of allocation
continue; if (tok3->strAt(3) == "(") // has cast
size = MathLib::toLongNumber(tok3->linkAt(6)->strAt(3));
// check for variable sized structure
if (scope->type == Scope::eStruct && var->isPublic()) {
// last member of a struct with array size of 0 or 1 could be a variable sized structure
if (var->dimensions().size() == 1 && var->dimension(0) < 2 &&
var->index() == (scope->varlist.size() - 1)) {
// dynamically allocated so could be variable sized structure
if (tok3->next()->str() == "*") {
// check for allocation
if ((Token::Match(tok3->tokAt(3), "; %name% = malloc ( %num% ) ;") ||
(Token::Match(tok3->tokAt(3), "; %name% = (") &&
Token::Match(tok3->linkAt(6), ") malloc ( %num% ) ;"))) &&
(tok3->strAt(4) == tok3->strAt(2))) {
MathLib::bigint size;
// find size of allocation
if (tok3->strAt(3) == "(") // has cast
size = MathLib::toLongNumber(tok3->linkAt(6)->strAt(3));
else
size = MathLib::toLongNumber(tok3->strAt(8));
// We don't calculate the size of a structure even when we know
// the size of the members. We just assign a length of 100 for
// any struct. If the size is less than 100, we assume the
// programmer knew the size and specified it rather than using
// sizeof(struct). If the size is greater than 100, we assume
// the programmer specified the size as sizeof(struct) + number.
// Either way, this is just a guess and could be wrong. The
// information to make the right decision has been simplified
// away by the time we get here.
if (size != 100) { // magic number for size of struct
// check if a real size was specified and give up
// malloc(10) rather than malloc(sizeof(struct))
if (size < 100 || arrayInfo.element_size() == 0)
continue;
// calculate real array size based on allocated size
const MathLib::bigint elements = (size - 100) / arrayInfo.element_size();
arrayInfo.num(0, arrayInfo.num(0) + elements);
}
}
// size unknown so assume it is a variable sized structure
else else
continue; size = MathLib::toLongNumber(tok3->strAt(8));
// We don't calculate the size of a structure even when we know
// the size of the members. We just assign a length of 100 for
// any struct. If the size is less than 100, we assume the
// programmer knew the size and specified it rather than using
// sizeof(struct). If the size is greater than 100, we assume
// the programmer specified the size as sizeof(struct) + number.
// Either way, this is just a guess and could be wrong. The
// information to make the right decision has been simplified
// away by the time we get here.
if (size != 100) { // magic number for size of struct
// check if a real size was specified and give up
// malloc(10) rather than malloc(sizeof(struct))
if (size < 100 || arrayInfo.element_size() == 0)
continue;
// calculate real array size based on allocated size
const MathLib::bigint elements = (size - 100) / arrayInfo.element_size();
arrayInfo.num(0, arrayInfo.num(0) + elements);
}
} }
// size unknown so assume it is a variable sized structure
else
continue;
} }
} }
}
// Goto end of statement. // Goto end of statement.
const Token *checkTok = nullptr; const Token *checkTok = nullptr;
while (tok3 && tok3 != func_scope->classEnd) { while (tok3 && tok3 != func_scope->classEnd) {
// End of statement. // End of statement.
if (tok3->str() == ";") { if (tok3->str() == ";") {
checkTok = tok3; checkTok = tok3;
break; break;
}
// End of function declaration..
if (Token::simpleMatch(tok3, ") ;"))
break;
// Function implementation..
if (Token::simpleMatch(tok3, ") {")) {
checkTok = tok3->tokAt(2);
break;
}
tok3 = tok3->next();
} }
if (!tok3) // End of function declaration..
if (Token::simpleMatch(tok3, ") ;"))
break; break;
if (!checkTok) // Function implementation..
continue; if (Token::simpleMatch(tok3, ") {")) {
checkTok = tok3->tokAt(2);
break;
}
// Check variable usage.. tok3 = tok3->next();
ArrayInfo temp = arrayInfo;
temp.declarationId(0); // do variable lookup by variable and member names rather than varid
std::string varnames; // use class and member name for messages
for (std::size_t k = 0; k < varname.size(); ++k)
varnames += (k == 0 ? "" : ".") + *varname[k];
temp.varname(varnames);
checkScope(checkTok, varname, temp);
} }
if (!tok3)
break;
if (!checkTok)
continue;
// Check variable usage..
ArrayInfo temp = arrayInfo;
temp.declarationId(0); // do variable lookup by variable and member names rather than varid
std::string varnames; // use class and member name for messages
for (std::size_t k = 0; k < varname.size(); ++k)
varnames += (k == 0 ? "" : ".") + *varname[k];
temp.varname(varnames);
checkScope(checkTok, varname, temp);
} }
} }
} }

View File

@ -2701,8 +2701,8 @@ void CheckMemoryLeakNoVar::checkForUnusedReturnValue(const Scope *scope)
if (!parent) { if (!parent) {
// Check if we are in a C++11 constructor // Check if we are in a C++11 constructor
const Token * closingBrace = Token::findmatch(tok, "}|;"); const Token * closingBrace = Token::findmatch(tok, "}|;");
if(closingBrace->str() == "}" && Token::Match(closingBrace->link()->tokAt(-1), "%name%")) if (closingBrace->str() == "}" && Token::Match(closingBrace->link()->tokAt(-1), "%name%"))
continue; continue;
returnValueNotUsedError(tok, tok->str()); returnValueNotUsedError(tok, tok->str());
} else if (Token::Match(parent, "%comp%|!")) { } else if (Token::Match(parent, "%comp%|!")) {
returnValueNotUsedError(tok, tok->str()); returnValueNotUsedError(tok, tok->str());

View File

@ -2421,11 +2421,11 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol
continue; continue;
} }
if(numtok && !numtok->hasKnownIntValue()) if (numtok && !numtok->hasKnownIntValue())
continue; continue;
if(lowertok && !lowertok->hasKnownIntValue()) if (lowertok && !lowertok->hasKnownIntValue())
continue; continue;
if(uppertok && !uppertok->hasKnownIntValue()) if (uppertok && !uppertok->hasKnownIntValue())
continue; continue;
const unsigned int varid = vartok->varId(); const unsigned int varid = vartok->varId();
@ -2441,13 +2441,13 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol
} }
std::list<ValueFlow::Value> values; std::list<ValueFlow::Value> values;
// TODO: We should add all known values // TODO: We should add all known values
if(numtok) { if (numtok) {
values.push_back(ValueFlow::Value(tok, numtok->values().front().intvalue)); values.push_back(ValueFlow::Value(tok, numtok->values().front().intvalue));
} else if(lowertok) { } else if (lowertok) {
long long v = lowertok->values().front().intvalue; long long v = lowertok->values().front().intvalue;
values.push_back(ValueFlow::Value(tok, v+1)); values.push_back(ValueFlow::Value(tok, v+1));
} else if(uppertok) { } else if (uppertok) {
long long v = uppertok->values().front().intvalue; long long v = uppertok->values().front().intvalue;
values.push_back(ValueFlow::Value(tok, v-1)); values.push_back(ValueFlow::Value(tok, v-1));