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)
|
if ((tok->str() == "ungetc" || tok->str() == "ungetwc") && fileTok)
|
||||||
fileTok = fileTok->nextArgument();
|
fileTok = fileTok->nextArgument();
|
||||||
operation = Filepointer::UNIMPORTANT;
|
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);
|
const Token* const end2 = tok->linkAt(1);
|
||||||
for (const Token* tok2 = tok->tokAt(2); tok2 != end2; tok2 = tok2->next()) {
|
for (const Token* tok2 = tok->tokAt(2); tok2 != end2; tok2 = tok2->next()) {
|
||||||
if (tok2->varId() && filepointers.find(tok2->varId()) != filepointers.end()) {
|
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
|
if (!writtenArgumentsEnd) // Indicates that we are in the first argument of strcpy/memcpy/... function
|
||||||
memAssignments.erase(tok->varId());
|
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");
|
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
|
if (tok->varId()) // operator() or function pointer
|
||||||
varAssignments.erase(tok->varId());
|
varAssignments.erase(tok->varId());
|
||||||
|
@ -2131,7 +2131,7 @@ void CheckOther::checkInvalidFree()
|
||||||
// If the previously-allocated variable is passed in to another function
|
// 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
|
// as a parameter, it might be modified, so we shouldn't report an error
|
||||||
// if it is later used to free memory
|
// 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));
|
const Token* tok2 = Token::findmatch(tok->next(), "%var%", tok->linkAt(1));
|
||||||
while (tok2 != nullptr) {
|
while (tok2 != nullptr) {
|
||||||
allocatedVariables.erase(tok2->varId());
|
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
|
// 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 this is a new function definition, clear all variables
|
||||||
if (Token::simpleMatch(tok->next()->link(), ") {")) {
|
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());
|
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(
|
check(
|
||||||
"void foo(char *p) {\n"
|
"void foo(char *p) {\n"
|
||||||
" free(p);\n"
|
" free(p);\n"
|
||||||
" printf(\"Freed memory at location %x\", p);\n"
|
" printf(\"Freed memory at location %x\", p);\n"
|
||||||
" free(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());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());
|
||||||
|
|
||||||
check(
|
check(
|
||||||
|
|
Loading…
Reference in New Issue