Skip to content

Commit 6f92557

Browse files
committed
Use information about pure/leak-ignore from library to improve accuracy of several bailouts
1 parent fd2346e commit 6f92557

3 files changed

Lines changed: 7 additions & 5 deletions

File tree

lib/checkio.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ void CheckIO::checkFileUsage()
220220
if ((tok->str() == "ungetc" || tok->str() == "ungetwc") && fileTok)
221221
fileTok = fileTok->nextArgument();
222222
operation = Filepointer::UNIMPORTANT;
223-
} else if (!Token::Match(tok, "if|for|while|catch|switch")) {
223+
} else if (!Token::Match(tok, "if|for|while|catch|switch") && _settings->library.functionpure.find(tok->str()) == _settings->library.functionpure.end()) {
224224
const Token* const end2 = tok->linkAt(1);
225225
for (const Token* tok2 = tok->tokAt(2); tok2 != end2; tok2 = tok2->next()) {
226226
if (tok2->varId() && filepointers.find(tok2->varId()) != filepointers.end()) {

lib/checkother.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ void CheckOther::checkRedundantAssignment()
673673
if (!writtenArgumentsEnd) // Indicates that we are in the first argument of strcpy/memcpy/... function
674674
memAssignments.erase(tok->varId());
675675
}
676-
} else if (Token::Match(tok, "%var% (")) { // Function call. Global variables might be used. Reset their status
676+
} 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
677677
const bool memfunc = Token::Match(tok, "memcpy|memmove|memset|strcpy|strncpy|sprintf|snprintf|strcat|strncat|wcscpy|wcsncpy|swprintf|wcscat|wcsncat");
678678
if (tok->varId()) // operator() or function pointer
679679
varAssignments.erase(tok->varId());
@@ -2131,7 +2131,7 @@ void CheckOther::checkInvalidFree()
21312131
// If the previously-allocated variable is passed in to another function
21322132
// as a parameter, it might be modified, so we shouldn't report an error
21332133
// if it is later used to free memory
2134-
else if (Token::Match(tok, "%var% (")) {
2134+
else if (Token::Match(tok, "%var% (") && _settings->library.functionpure.find(tok->str()) == _settings->library.functionpure.end()) {
21352135
const Token* tok2 = Token::findmatch(tok->next(), "%var%", tok->linkAt(1));
21362136
while (tok2 != nullptr) {
21372137
allocatedVariables.erase(tok2->varId());
@@ -2209,7 +2209,7 @@ void CheckOther::checkDoubleFree()
22092209
}
22102210

22112211
// If a variable is passed to a function, remove it from the set of previously freed variables
2212-
else if (Token::Match(tok, "%var% (") && !Token::Match(tok, "printf|sprintf|snprintf|fprintf|wprintf|swprintf|fwprintf")) {
2212+
else if (Token::Match(tok, "%var% (") && _settings->library.leakignore.find(tok->str()) == _settings->library.leakignore.end()) {
22132213

22142214
// If this is a new function definition, clear all variables
22152215
if (Token::simpleMatch(tok->next()->link(), ") {")) {

test/testother.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4776,12 +4776,14 @@ class TestOther : public TestFixture {
47764776
"}");
47774777
ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());
47784778

4779+
Settings settings;
4780+
LOAD_LIB_2(settings.library, "std.cfg");
47794781
check(
47804782
"void foo(char *p) {\n"
47814783
" free(p);\n"
47824784
" printf(\"Freed memory at location %x\", p);\n"
47834785
" free(p);\n"
4784-
"}");
4786+
"}", nullptr, false, false, false, true, &settings);
47854787
ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());
47864788

47874789
check(

0 commit comments

Comments
 (0)