Use information about pure/leak-ignore from library to improve accuracy of several bailouts
This commit is contained in:
parent
fd2346e4ec
commit
6f92557478
|
@ -220,7 +220,7 @@ void CheckIO::checkFileUsage()
|
|||
if ((tok->str() == "ungetc" || tok->str() == "ungetwc") && fileTok)
|
||||
fileTok = fileTok->nextArgument();
|
||||
operation = Filepointer::UNIMPORTANT;
|
||||
} else if (!Token::Match(tok, "if|for|while|catch|switch")) {
|
||||
} else if (!Token::Match(tok, "if|for|while|catch|switch") && _settings->library.functionpure.find(tok->str()) == _settings->library.functionpure.end()) {
|
||||
const Token* const end2 = tok->linkAt(1);
|
||||
for (const Token* tok2 = tok->tokAt(2); tok2 != end2; tok2 = tok2->next()) {
|
||||
if (tok2->varId() && filepointers.find(tok2->varId()) != filepointers.end()) {
|
||||
|
|
|
@ -673,7 +673,7 @@ void CheckOther::checkRedundantAssignment()
|
|||
if (!writtenArgumentsEnd) // Indicates that we are in the first argument of strcpy/memcpy/... function
|
||||
memAssignments.erase(tok->varId());
|
||||
}
|
||||
} else if (Token::Match(tok, "%var% (")) { // Function call. Global variables might be used. Reset their status
|
||||
} else if (Token::Match(tok, "%var% (") && _settings->library.functionpure.find(tok->str()) == _settings->library.functionpure.end()) { // Function call. Global variables might be used. Reset their status
|
||||
const bool memfunc = Token::Match(tok, "memcpy|memmove|memset|strcpy|strncpy|sprintf|snprintf|strcat|strncat|wcscpy|wcsncpy|swprintf|wcscat|wcsncat");
|
||||
if (tok->varId()) // operator() or function pointer
|
||||
varAssignments.erase(tok->varId());
|
||||
|
@ -2131,7 +2131,7 @@ void CheckOther::checkInvalidFree()
|
|||
// If the previously-allocated variable is passed in to another function
|
||||
// as a parameter, it might be modified, so we shouldn't report an error
|
||||
// if it is later used to free memory
|
||||
else if (Token::Match(tok, "%var% (")) {
|
||||
else if (Token::Match(tok, "%var% (") && _settings->library.functionpure.find(tok->str()) == _settings->library.functionpure.end()) {
|
||||
const Token* tok2 = Token::findmatch(tok->next(), "%var%", tok->linkAt(1));
|
||||
while (tok2 != nullptr) {
|
||||
allocatedVariables.erase(tok2->varId());
|
||||
|
@ -2209,7 +2209,7 @@ void CheckOther::checkDoubleFree()
|
|||
}
|
||||
|
||||
// If a variable is passed to a function, remove it from the set of previously freed variables
|
||||
else if (Token::Match(tok, "%var% (") && !Token::Match(tok, "printf|sprintf|snprintf|fprintf|wprintf|swprintf|fwprintf")) {
|
||||
else if (Token::Match(tok, "%var% (") && _settings->library.leakignore.find(tok->str()) == _settings->library.leakignore.end()) {
|
||||
|
||||
// If this is a new function definition, clear all variables
|
||||
if (Token::simpleMatch(tok->next()->link(), ") {")) {
|
||||
|
|
|
@ -4776,12 +4776,14 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());
|
||||
|
||||
Settings settings;
|
||||
LOAD_LIB_2(settings.library, "std.cfg");
|
||||
check(
|
||||
"void foo(char *p) {\n"
|
||||
" free(p);\n"
|
||||
" printf(\"Freed memory at location %x\", p);\n"
|
||||
" free(p);\n"
|
||||
"}");
|
||||
"}", nullptr, false, false, false, true, &settings);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());
|
||||
|
||||
check(
|
||||
|
|
Loading…
Reference in New Issue