Improvement: Support member variables in CheckOther::checkIncompleteArrayFill() (#4205)
Merged from LCppC.
This commit is contained in:
parent
1d9b6e1aac
commit
f3565e1056
|
@ -2838,8 +2838,16 @@ void CheckOther::checkIncompleteArrayFill()
|
||||||
|
|
||||||
for (const Scope * scope : symbolDatabase->functionScopes) {
|
for (const Scope * scope : symbolDatabase->functionScopes) {
|
||||||
for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
|
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% )")) {
|
if (Token::Match(tok, "memset|memcpy|memmove (") && Token::Match(tok->linkAt(1)->tokAt(-2), ", %num% )")) {
|
||||||
const Variable *var = tok->tokAt(2)->variable();
|
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))
|
if (!var || !var->isArray() || var->dimensions().empty() || !var->dimension(0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2849,11 +2857,12 @@ void CheckOther::checkIncompleteArrayFill()
|
||||||
size = mSettings->sizeof_pointer;
|
size = mSettings->sizeof_pointer;
|
||||||
else if (size == 0 && var->type())
|
else if (size == 0 && var->type())
|
||||||
size = estimateSize(var->type(), mSettings, symbolDatabase);
|
size = estimateSize(var->type(), mSettings, symbolDatabase);
|
||||||
|
const Token* tok3 = tok->next()->astOperand2()->astOperand1()->astOperand1();
|
||||||
if ((size != 1 && size != 100 && size != 0) || var->isPointer()) {
|
if ((size != 1 && size != 100 && size != 0) || var->isPointer()) {
|
||||||
if (printWarning)
|
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
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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: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());
|
"[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"
|
check("void f() {\n"
|
||||||
" Foo* a[5];\n"
|
" Foo* a[5];\n"
|
||||||
" memset(a, 'a', 5);\n"
|
" memset(a, 'a', 5);\n"
|
||||||
|
|
Loading…
Reference in New Issue