Fix false positive when constructing with curly brace (#1148)

This commit is contained in:
Paul Fultz II 2018-04-04 23:47:59 -05:00 committed by Daniel Marjamäki
parent 06133fa3ba
commit 54de7b48c9
2 changed files with 75 additions and 1 deletions

View File

@ -2698,8 +2698,15 @@ void CheckMemoryLeakNoVar::checkForUnusedReturnValue(const Scope *scope)
while (parent && parent->str() == "(" && !parent->astOperand2()) while (parent && parent->str() == "(" && !parent->astOperand2())
parent = parent->astParent(); parent = parent->astParent();
if (!parent || Token::Match(parent, "%comp%|!")) if (!parent) {
// Check if we are in a C++11 constructor
const Token * closingBrace = Token::findmatch(tok, "}|;");
if(closingBrace->str() == "}" && Token::Match(closingBrace->link()->tokAt(-1), "%name%"))
continue;
returnValueNotUsedError(tok, tok->str()); returnValueNotUsedError(tok, tok->str());
} else if (Token::Match(parent, "%comp%|!")) {
returnValueNotUsedError(tok, tok->str());
}
} }
} }

View File

@ -5747,6 +5747,7 @@ private:
// pass allocated memory to function using a smart pointer // pass allocated memory to function using a smart pointer
TEST_CASE(smartPointerFunctionParam); TEST_CASE(smartPointerFunctionParam);
TEST_CASE(resourceLeak);
} }
void functionParameter() { void functionParameter() {
@ -5954,6 +5955,72 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void resourceLeak() {
check("void foo() {\n"
" fopen(\"file.txt\", \"r\");\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (error) Return value of allocation function 'fopen' is not stored.\n", errout.str());
check("struct Holder {\n"
" Holder(FILE* f) : file(f) {}\n"
" ~Holder() { fclose(file); }\n"
" FILE* file;\n"
"};\n"
"void foo() {\n"
" Holder h ( fopen(\"file.txt\", \"r\"));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct Holder {\n"
" Holder(FILE* f) : file(f) {}\n"
" ~Holder() { fclose(file); }\n"
" FILE* file;\n"
"};\n"
"void foo() {\n"
" Holder ( fopen(\"file.txt\", \"r\"));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct Holder {\n"
" Holder(FILE* f) : file(f) {}\n"
" ~Holder() { fclose(file); }\n"
" FILE* file;\n"
"};\n"
"void foo() {\n"
" Holder h { fopen(\"file.txt\", \"r\")};\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct Holder {\n"
" Holder(FILE* f) : file(f) {}\n"
" ~Holder() { fclose(file); }\n"
" FILE* file;\n"
"};\n"
"void foo() {\n"
" Holder h = fopen(\"file.txt\", \"r\");\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct Holder {\n"
" Holder(FILE* f) : file(f) {}\n"
" ~Holder() { fclose(file); }\n"
" FILE* file;\n"
"};\n"
"void foo() {\n"
" Holder { fopen(\"file.txt\", \"r\")};\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct Holder {\n"
" Holder(int i, FILE* f) : file(f) {}\n"
" ~Holder() { fclose(file); }\n"
" FILE* file;\n"
"};\n"
"void foo() {\n"
" Holder { 0, fopen(\"file.txt\", \"r\")};\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
}; };
REGISTER_TEST(TestMemleakNoVar) REGISTER_TEST(TestMemleakNoVar)