Fixed #4237 (False positive: (error) Memory Leak: data (assign reference variable value to a shadow variable in inner scope))
This commit is contained in:
parent
ca073bdaad
commit
38213f1f2f
|
@ -250,6 +250,8 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
|||
} else if (Token::simpleMatch(tok->previous(), "=")) {
|
||||
varInfo->erase(tok->varId());
|
||||
}
|
||||
} else if (Token::Match(tok->previous(), "& %var% = %var% ;")) {
|
||||
varInfo->referenced.insert(tok->tokAt(2)->varId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,6 +559,10 @@ void CheckLeakAutoVar::ret(const Token *tok, const VarInfo &varInfo)
|
|||
if (it->second != "dealloc" && varInfo.conditionalAlloc.find(it->first) != varInfo.conditionalAlloc.end())
|
||||
continue;
|
||||
|
||||
// don't warn if there is a reference of the variable
|
||||
if (varInfo.referenced.find(it->first) != varInfo.referenced.end())
|
||||
continue;
|
||||
|
||||
const unsigned int varid = it->first;
|
||||
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
||||
if (var) {
|
||||
|
|
|
@ -31,11 +31,13 @@ public:
|
|||
std::map<unsigned int, std::string> alloctype;
|
||||
std::map<unsigned int, std::string> possibleUsage;
|
||||
std::set<unsigned int> conditionalAlloc;
|
||||
std::set<unsigned int> referenced;
|
||||
|
||||
void clear() {
|
||||
alloctype.clear();
|
||||
possibleUsage.clear();
|
||||
conditionalAlloc.clear();
|
||||
referenced.clear();
|
||||
}
|
||||
|
||||
void erase(unsigned int varid) {
|
||||
|
@ -48,6 +50,7 @@ public:
|
|||
alloctype.swap(other.alloctype);
|
||||
possibleUsage.swap(other.possibleUsage);
|
||||
conditionalAlloc.swap(other.conditionalAlloc);
|
||||
referenced.swap(other.referenced);
|
||||
}
|
||||
|
||||
/** set possible usage for all variables */
|
||||
|
|
|
@ -1246,6 +1246,11 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
|
|||
}
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "& %var% = %varid% ;", varid)) {
|
||||
while (rethead->next())
|
||||
rethead->deleteNext();
|
||||
return rethead;
|
||||
}
|
||||
if (Token::Match(tok, "[)=] %varid% [+;)]", varid) ||
|
||||
Token::Match(tok, "%var% + %varid%", varid) ||
|
||||
Token::Match(tok, "%varid% +=|-=", varid) ||
|
||||
|
|
|
@ -45,6 +45,7 @@ private:
|
|||
TEST_CASE(assign10);
|
||||
TEST_CASE(assign11); // #3942: x = a(b(p));
|
||||
TEST_CASE(assign12); // #4236: FP. bar(&x);
|
||||
TEST_CASE(assign13); // #4237: FP. char*&ref=p; p=malloc(10); free(ref);
|
||||
|
||||
TEST_CASE(deallocuse1);
|
||||
TEST_CASE(deallocuse2);
|
||||
|
@ -228,6 +229,16 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void assign13() { // #4237: FP. char *&ref=p; p=malloc(10); free(ref);
|
||||
check("void f() {\n"
|
||||
" char *p;\n"
|
||||
" char * &ref = p;\n"
|
||||
" p = malloc(10);\n"
|
||||
" free(ref);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void deallocuse1() {
|
||||
check("void f(char *p) {\n"
|
||||
" free(p);\n"
|
||||
|
|
|
@ -506,6 +506,9 @@ private:
|
|||
// non-use..
|
||||
ASSERT_EQUALS(";;", getcode("char *s; s = s + 1;", "s"));
|
||||
|
||||
// reference
|
||||
ASSERT_EQUALS(";", getcode("char *p; char * & ref = p; p = malloc(10);", "p"));
|
||||
|
||||
// return..
|
||||
ASSERT_EQUALS(";;return;", getcode("char *s; return;", "s"));
|
||||
ASSERT_EQUALS(";;returnuse;", getcode("char *s; return s;", "s"));
|
||||
|
|
Loading…
Reference in New Issue