diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 65d2796b3..3e243a138 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2838,8 +2838,16 @@ void CheckOther::checkIncompleteArrayFill() for (const Scope * scope : symbolDatabase->functionScopes) { for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { - if (Token::Match(tok, "memset|memcpy|memmove ( %var% ,") && Token::Match(tok->linkAt(1)->tokAt(-2), ", %num% )")) { - const Variable *var = tok->tokAt(2)->variable(); + if (Token::Match(tok, "memset|memcpy|memmove (") && Token::Match(tok->linkAt(1)->tokAt(-2), ", %num% )")) { + const Token* tok2 = tok->tokAt(2); + if (tok2->str() == "::") + tok2 = tok2->next(); + while (Token::Match(tok2, "%name% ::|.")) + tok2 = tok2->tokAt(2); + if (!Token::Match(tok2, "%var% ,")) + continue; + + const Variable *var = tok2->variable(); if (!var || !var->isArray() || var->dimensions().empty() || !var->dimension(0)) continue; @@ -2849,11 +2857,12 @@ void CheckOther::checkIncompleteArrayFill() size = mSettings->sizeof_pointer; else if (size == 0 && var->type()) size = estimateSize(var->type(), mSettings, symbolDatabase); + const Token* tok3 = tok->next()->astOperand2()->astOperand1()->astOperand1(); if ((size != 1 && size != 100 && size != 0) || var->isPointer()) { if (printWarning) - incompleteArrayFillError(tok, var->name(), tok->str(), false); + incompleteArrayFillError(tok, tok3->expressionString(), tok->str(), false); } else if (var->valueType()->type == ValueType::Type::BOOL && printPortability) // sizeof(bool) is not 1 on all platforms - incompleteArrayFillError(tok, var->name(), tok->str(), true); + incompleteArrayFillError(tok, tok3->expressionString(), tok->str(), true); } } } diff --git a/test/testother.cpp b/test/testother.cpp index 50c3011c7..ce26e9c9d 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -7714,6 +7714,16 @@ private: "[test.cpp:4]: (warning, inconclusive) Array 'a' is filled incompletely. Did you forget to multiply the size given to 'memcpy()' with 'sizeof(*a)'?\n" "[test.cpp:5]: (warning, inconclusive) Array 'a' is filled incompletely. Did you forget to multiply the size given to 'memmove()' with 'sizeof(*a)'?\n", errout.str()); + check("int a[5];\n" + "namespace Z { struct B { int a[5]; } b; }\n" + "void f() {\n" + " memset(::a, 123, 5);\n" + " memset(Z::b.a, 123, 5);\n" + "}"); + TODO_ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) Array '::a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*::a)'?\n" + "[test.cpp:5]: (warning, inconclusive) Array 'Z::b.a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*Z::b.a)'?\n", + "[test.cpp:4]: (warning, inconclusive) Array '::a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*::a)'?\n", errout.str()); + check("void f() {\n" " Foo* a[5];\n" " memset(a, 'a', 5);\n"