Fix 10631: FP, Regression: error: Return value of allocation function 'makeThing' is not stored. (#3585)

This commit is contained in:
Paul Fultz II 2021-11-29 00:06:43 -06:00 committed by GitHub
parent c26e205e29
commit 853a1f6d54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 8 deletions

View File

@ -103,11 +103,14 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
const Token *typeTok = tok2->next(); const Token *typeTok = tok2->next();
while (Token::Match(typeTok, "%name% :: %name%")) while (Token::Match(typeTok, "%name% :: %name%"))
typeTok = typeTok->tokAt(2); typeTok = typeTok->tokAt(2);
const Scope* classScope = nullptr;
if (typeTok->type() && typeTok->type()->isClassType()) { if (typeTok->type() && typeTok->type()->isClassType()) {
const Scope *classScope = typeTok->type()->classScope; classScope = typeTok->type()->classScope;
} else if (typeTok->function() && typeTok->function()->isConstructor()) {
classScope = typeTok->function()->nestedIn;
}
if (classScope && classScope->numConstructors > 0) if (classScope && classScope->numConstructors > 0)
return No; return No;
}
return New; return New;
} }

View File

@ -69,8 +69,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
createSymbolDatabaseSetVariablePointers(); createSymbolDatabaseSetVariablePointers();
setValueTypeInTokenList(false); setValueTypeInTokenList(false);
createSymbolDatabaseSetTypePointers(); createSymbolDatabaseSetTypePointers();
createSymbolDatabaseSetSmartPointerType();
createSymbolDatabaseSetFunctionPointers(true); createSymbolDatabaseSetFunctionPointers(true);
createSymbolDatabaseSetSmartPointerType();
setValueTypeInTokenList(false); setValueTypeInTokenList(false);
createSymbolDatabaseEnums(); createSymbolDatabaseEnums();
createSymbolDatabaseEscapeFunctions(); createSymbolDatabaseEscapeFunctions();

View File

@ -1360,8 +1360,10 @@ private:
"public:\n" "public:\n"
" A() : b(new B()), c(new C(b)) { }\n" " A() : b(new B()), c(new C(b)) { }\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n" TODO_ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n"
"[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", errout.str()); "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n",
"[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n",
errout.str());
check("struct B { };\n" check("struct B { };\n"
"struct C\n" "struct C\n"
@ -1380,8 +1382,10 @@ private:
" c = new C(b);\n" " c = new C(b);\n"
" }\n" " }\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n" TODO_ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n"
"[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", errout.str()); "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n",
"[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n",
errout.str());
} }
void class22() { // ticket #3012 - false positive void class22() { // ticket #3012 - false positive
@ -2521,6 +2525,26 @@ private:
" makeThing();\n" " makeThing();\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #10631
check("struct Thing {\n"
" Thing();\n"
"};\n"
"std::vector<Thing*> g_things;\n"
"Thing* makeThing() {\n"
" Thing* n = new Thing();\n"
" return n;\n"
"}\n"
"Thing::Thing() {\n"
" g_things.push_back(this);\n"
"}\n"
"void f() {\n"
" makeThing();\n"
" for(Thing* t : g_things) {\n"
" delete t;\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
}; };
REGISTER_TEST(TestMemleakNoVar) REGISTER_TEST(TestMemleakNoVar)