Fix #8619 FN memset on container containing structs with containers (#4491)

* Fix #1655 wrong usage of std::string in memcpy

* Fix memsetClass FP

* Fix #8619 FN memset on container containing structs with containers

* Token::Match

* Use AST

* simpleMatch
This commit is contained in:
chrchr-github 2022-09-21 17:33:48 +02:00 committed by GitHub
parent 3644d79162
commit 2aca275e0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 8 deletions

View File

@ -1319,14 +1319,21 @@ void CheckClass::checkMemset()
const Token *typeTok = nullptr; const Token *typeTok = nullptr;
const Scope *type = nullptr; const Scope *type = nullptr;
if (Token::Match(arg3, "sizeof ( %type% ) )")) const Token* sizeofTok = arg3->previous()->astOperand2(); // try to find sizeof() in argument expression
typeTok = arg3->tokAt(2); if (sizeofTok && sizeofTok->astOperand1() && Token::simpleMatch(sizeofTok->astOperand1()->previous(), "sizeof ("))
else if (Token::Match(arg3, "sizeof ( %type% :: %type% ) )")) sizeofTok = sizeofTok->astOperand1();
typeTok = arg3->tokAt(4); else if (sizeofTok && sizeofTok->astOperand2() && Token::simpleMatch(sizeofTok->astOperand2()->previous(), "sizeof ("))
else if (Token::Match(arg3, "sizeof ( struct %type% ) )")) sizeofTok = sizeofTok->astOperand2();
typeTok = arg3->tokAt(3); if (Token::simpleMatch(sizeofTok, "("))
else if (Token::simpleMatch(arg3, "sizeof ( * this ) )") || Token::simpleMatch(arg1, "this ,")) { sizeofTok = sizeofTok->previous();
type = findFunctionOf(arg3->scope()); if (Token::Match(sizeofTok, "sizeof ( %type% )"))
typeTok = sizeofTok->tokAt(2);
else if (Token::Match(sizeofTok, "sizeof ( %type% :: %type% )"))
typeTok = sizeofTok->tokAt(4);
else if (Token::Match(sizeofTok, "sizeof ( struct %type% )"))
typeTok = sizeofTok->tokAt(3);
else if (Token::simpleMatch(sizeofTok, "sizeof ( * this )") || Token::simpleMatch(arg1, "this ,")) {
type = findFunctionOf(sizeofTok->scope());
} else if (Token::Match(arg1, "&|*|%var%")) { } else if (Token::Match(arg1, "&|*|%var%")) {
int numIndirToVariableType = 0; // Offset to the actual type in terms of dereference/addressof int numIndirToVariableType = 0; // Offset to the actual type in terms of dereference/addressof
for (;; arg1 = arg1->next()) { for (;; arg1 = arg1->next()) {

View File

@ -3109,6 +3109,21 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #8619
checkNoMemset("struct S { std::vector<int> m; };\n"
"void f() {\n"
" std::vector<S> v(5);\n"
" memset(&v[0], 0, sizeof(S) * v.size());\n"
" memset(&v[0], 0, v.size() * sizeof(S));\n"
" memset(&v[0], 0, 5 * sizeof(S));\n"
" memset(&v[0], 0, sizeof(S) * 5);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Using 'memset' on struct that contains a 'std::vector'.\n"
"[test.cpp:5]: (error) Using 'memset' on struct that contains a 'std::vector'.\n"
"[test.cpp:6]: (error) Using 'memset' on struct that contains a 'std::vector'.\n"
"[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'.\n",
errout.str());
// #1655 // #1655
Settings s; Settings s;
LOAD_LIB_2(s.library, "std.cfg"); LOAD_LIB_2(s.library, "std.cfg");