Use information about pure/leak-ignore from library to improve accuracy of several bailouts

This commit is contained in:
PKEuS 2014-09-11 17:01:08 +02:00
parent fd2346e4ec
commit 6f92557478
3 changed files with 7 additions and 5 deletions

View File

@ -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()) {

View File

@ -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(), ") {")) {

View File

@ -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(