Skip to content
23 changes: 15 additions & 8 deletions lib/checkclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1319,14 +1319,21 @@ void CheckClass::checkMemset()

const Token *typeTok = nullptr;
const Scope *type = nullptr;
if (Token::Match(arg3, "sizeof ( %type% ) )"))
typeTok = arg3->tokAt(2);
else if (Token::Match(arg3, "sizeof ( %type% :: %type% ) )"))
typeTok = arg3->tokAt(4);
else if (Token::Match(arg3, "sizeof ( struct %type% ) )"))
typeTok = arg3->tokAt(3);
else if (Token::simpleMatch(arg3, "sizeof ( * this ) )") || Token::simpleMatch(arg1, "this ,")) {
type = findFunctionOf(arg3->scope());
const Token* sizeofTok = arg3->previous()->astOperand2(); // try to find sizeof() in argument expression
if (sizeofTok && sizeofTok->astOperand1() && Token::simpleMatch(sizeofTok->astOperand1()->previous(), "sizeof ("))
sizeofTok = sizeofTok->astOperand1();
else if (sizeofTok && sizeofTok->astOperand2() && Token::simpleMatch(sizeofTok->astOperand2()->previous(), "sizeof ("))
sizeofTok = sizeofTok->astOperand2();
if (Token::simpleMatch(sizeofTok, "("))
sizeofTok = sizeofTok->previous();
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%")) {
int numIndirToVariableType = 0; // Offset to the actual type in terms of dereference/addressof
for (;; arg1 = arg1->next()) {
Expand Down
15 changes: 15 additions & 0 deletions test/testclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3109,6 +3109,21 @@ class TestClass : public TestFixture {
"}");
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
Settings s;
LOAD_LIB_2(s.library, "std.cfg");
Expand Down