Refactorized checkautovariables.cpp. Removed indendation counters.

Fixed #3478
This commit is contained in:
PKEuS 2012-01-08 15:32:22 +01:00
parent e09b0330e4
commit c273d6d31d
2 changed files with 30 additions and 68 deletions

View File

@ -51,7 +51,7 @@ bool CheckAutoVariables::isAutoVar(unsigned int varId)
{
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varId);
if (!var || !var->isLocal() || var->isStatic() || var->isArray() || var->typeEndToken()->str() == "*")
if (!var || !var->isLocal() || var->isStatic() || var->isArray() || var->isPointer())
return false;
if (Token::simpleMatch(var->nameToken()->previous(), "&")) {
@ -85,17 +85,7 @@ void CheckAutoVariables::autoVariables()
if (scope->type != Scope::eFunction)
continue;
unsigned int indentlevel = 0;
for (const Token *tok = scope->classDef->next()->link(); tok; tok = tok->next()) {
// indentlevel..
if (tok->str() == "{")
++indentlevel;
else if (tok->str() == "}") {
if (indentlevel <= 1)
break;
--indentlevel;
}
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
//Critical assignment
if (Token::Match(tok, "[;{}] * %var% = & %var%") && errorAv(tok->tokAt(2), tok->tokAt(5))) {
const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(5)->varId());
@ -174,24 +164,8 @@ void CheckAutoVariables::returnPointerToLocalArray()
tok = tok->tokAt(-2);
// have we reached a function that returns a pointer
if (Token::Match(tok->tokAt(-2), "%type% *")) {
// go to the '('
const Token *tok2 = scope->classDef->next();
// go to the ')'
tok2 = tok2->next()->link();
unsigned int indentlevel = 0;
for (; tok2; tok2 = tok2->next()) {
// indentlevel..
if (tok2->str() == "{")
++indentlevel;
else if (tok2->str() == "}") {
if (indentlevel <= 1)
break;
--indentlevel;
}
if (tok->previous() && tok->previous()->str() == "*") {
for (const Token *tok2 = scope->classStart; tok2 && tok2 != scope->classEnd; tok2 = tok2->next()) {
// Return pointer to local array variable..
if (Token::Match(tok2, "return %var% ;")) {
const unsigned int varid = tok2->next()->varId();
@ -273,25 +247,8 @@ void CheckAutoVariables::returnReference()
tok = tok->tokAt(-2);
// have we reached a function that returns a reference?
if (Token::Match(tok->tokAt(-2), "%type% &") ||
Token::simpleMatch(tok->tokAt(-2), "> &")) {
// go to the '('
const Token *tok2 = scope->classDef->next();
// go to the ')'
tok2 = tok2->link();
unsigned int indentlevel = 0;
for (; tok2; tok2 = tok2->next()) {
// indentlevel..
if (tok2->str() == "{")
++indentlevel;
else if (tok2->str() == "}") {
if (indentlevel <= 1)
break;
--indentlevel;
}
if (tok->previous() && tok->previous()->str() == "&") {
for (const Token *tok2 = scope->classStart; tok2 && tok2 != scope->classEnd; tok2 = tok2->next()) {
// return..
if (Token::Match(tok2, "return %var% ;")) {
// is the returned variable a local variable?
@ -300,7 +257,7 @@ void CheckAutoVariables::returnReference()
if (var1 && var1->isLocal() && !var1->isStatic()) {
// If reference variable is used, check what it references
if (Token::Match(var1->nameToken()->previous(), "& %var% =")) {
if (Token::Match(var1->nameToken(), "%var% =")) {
const Token *tok3 = var1->nameToken()->tokAt(2);
if (!Token::Match(tok3, "%var% [;.]"))
continue;
@ -308,7 +265,7 @@ void CheckAutoVariables::returnReference()
// Only report error if variable that is referenced is
// a auto variable
const Variable *var2 = symbolDatabase->getVariableFromVarId(tok3->varId());
if (!var2 || !var2->isLocal() || var2->isStatic())
if (!var2 || !var2->isLocal() || var2->isStatic() || (var2->isPointer() && tok3->strAt(1) == "."))
continue;
}
@ -371,23 +328,7 @@ void CheckAutoVariables::returncstr()
// have we reached a function that returns a const char *
if (Token::simpleMatch(tok->tokAt(-3), "const char *")) {
// go to the '('
const Token *tok2 = scope->classDef->next();
// go to the ')'
tok2 = tok2->next()->link();
unsigned int indentlevel = 0;
for (; tok2; tok2 = tok2->next()) {
// indentlevel..
if (tok2->str() == "{")
++indentlevel;
else if (tok2->str() == "}") {
if (indentlevel <= 1)
break;
--indentlevel;
}
for (const Token *tok2 = scope->classStart; tok2 && tok2 != scope->classEnd; tok2 = tok2->next()) {
// return..
if (Token::Match(tok2, "return %var% . c_str ( ) ;")) {
// is the returned variable a local variable?

View File

@ -84,6 +84,7 @@ private:
TEST_CASE(returnReference2);
TEST_CASE(returnReference3);
TEST_CASE(returnReference4);
TEST_CASE(returnReference5);
// return c_str()..
TEST_CASE(returncstr1);
@ -477,6 +478,26 @@ private:
ASSERT_EQUALS("", errout.str());
}
void returnReference5() {
check("struct A {\n"
" int i;\n"
"};\n"
"struct B {\n"
" A a;\n"
"};\n"
"struct C {\n"
" B *b;\n"
" const A& a() const {\n"
" const B *pb = b;\n"
" const A &ra = pb->a;\n"
" return ra;\n"
" }\n"
"};");
ASSERT_EQUALS("", errout.str());
}
void returncstr1() {
check("const char *foo()\n"
"{\n"