void CheckAutoVariables::returnPointerToLocalArray() { const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); std::list<Scope>::const_iterator scope; for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) { // only check functions if (scope->type != Scope::eFunction || !scope->function) continue; const Token *tok = scope->function->tokenDef; // have we reached a function that returns a pointer 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(); if (isAutoVarArray(varid)) { errorReturnPointerToLocalArray(tok2); } } } } } }
void CheckAutoVariables::returnPointerToLocalArray() { const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const std::size_t functions = symbolDatabase->functionScopes.size(); for (std::size_t i = 0; i < functions; ++i) { const Scope * scope = symbolDatabase->functionScopes[i]; if (!scope->function) continue; const Token *tok = scope->function->tokenDef; // have we reached a function that returns a pointer if (tok->previous() && tok->previous()->str() == "*") { for (const Token *tok2 = scope->classStart->next(); tok2 && tok2 != scope->classEnd; tok2 = tok2->next()) { // Return pointer to local array variable.. if (Token::Match(tok2, "return %var% ;")) { if (isAutoVarArray(tok2->next())) { errorReturnPointerToLocalArray(tok2); } } } } } }
void CheckAutoVariables::returnPointerToLocalArray() { const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); std::list<Scope>::const_iterator scope; for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) { // only check functions if (scope->type != Scope::eFunction) continue; const Token *tok = scope->classDef; // skip any qualification while (Token::Match(tok->tokAt(-2), "%type% ::")) tok = tok->tokAt(-2); // have we reached a function that returns a pointer 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(); const Variable *var = symbolDatabase->getVariableFromVarId(varid); if (var && var->isLocal() && !var->isStatic() && var->isArray()) { errorReturnPointerToLocalArray(tok2); } } } } } }
void CheckAutoVariables::returnPointerToLocalArray() { const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); std::list<Scope>::const_iterator scope; for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) { // only check functions if (scope->type != Scope::eFunction) continue; const Token *tok = scope->classDef; // skip any qualification while (Token::Match(tok->tokAt(-2), "%type% ::")) 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; } // Return pointer to local array variable.. if (Token::Match(tok2, "return %var% ;")) { const unsigned int varid = tok2->next()->varId(); const Variable *var = symbolDatabase->getVariableFromVarId(varid); if (var && var->isLocal() && !var->isStatic() && var->isArray()) { errorReturnPointerToLocalArray(tok2); } } } } } }
void CheckAutoVariables::returnPointerToLocalArray() { bool infunc = false; int indentlevel = 0; std::set<unsigned int> arrayVar; for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { // Is there a function declaration for a function that returns a pointer? if (!infunc && (Token::Match(tok, "%type% * %var% (") || Token::Match(tok, "%type% * %var% :: %var% ("))) { for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { if (tok2->str() == ")") { tok = tok2; break; } } if (Token::simpleMatch(tok, ") {")) { infunc = true; indentlevel = 0; arrayVar.clear(); } } // Parsing a function that returns a pointer.. if (infunc) { if (tok->str() == "{") { ++indentlevel; } else if (tok->str() == "}") { --indentlevel; if (indentlevel <= 0) { infunc = false; } continue; } // Declaring a local array.. if (Token::Match(tok, "[;{}] %type% %var% [")) { const unsigned int varid = tok->tokAt(2)->varId(); if (varid > 0) { arrayVar.insert(varid); } } // Return pointer to local array variable.. if (Token::Match(tok, "return %var% ;")) { const unsigned int varid = tok->next()->varId(); if (varid > 0 && arrayVar.find(varid) != arrayVar.end()) { errorReturnPointerToLocalArray(tok); } } } // Declaring array variable.. } }