Fixed #6766 (Improve check; struct member is assigned value that is never used)

This commit is contained in:
Daniel Marjamäki 2021-05-09 20:09:10 +02:00
parent 3b37c14b3c
commit 2e2d766e2b
2 changed files with 32 additions and 0 deletions

View File

@ -2680,6 +2680,26 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
if (mWhat == What::Reassign) if (mWhat == What::Reassign)
return Result(Result::Type::BAILOUT, parent->astParent()); return Result(Result::Type::BAILOUT, parent->astParent());
continue; continue;
} else if (mWhat == What::UnusedValue && Token::simpleMatch(parent, "&") && Token::Match(parent->astParent(), "[,(]")) {
// Pass variable to function the writes it
const Token *ftok = parent->astParent();
while (Token::simpleMatch(ftok, ","))
ftok = ftok->astParent();
if (ftok && Token::Match(ftok->previous(), "%name% (")) {
const std::vector<const Token *> args = getArguments(ftok);
int argnr = 0;
while (argnr < args.size() && args[argnr] != parent)
argnr++;
if (argnr < args.size()) {
const Library::Function* functionInfo = mLibrary.getFunction(ftok->astOperand1());
if (functionInfo) {
const auto it = functionInfo->argumentChecks.find(argnr + 1);
if (it != functionInfo->argumentChecks.end() && it->second.direction == Library::ArgumentChecks::Direction::DIR_OUT)
continue;
}
}
}
return Result(Result::Type::BAILOUT, parent->astParent());
} else { } else {
// TODO: this is a quick bailout // TODO: this is a quick bailout
return Result(Result::Type::BAILOUT, parent->astParent()); return Result(Result::Type::BAILOUT, parent->astParent());

View File

@ -172,6 +172,7 @@ private:
TEST_CASE(localvarStruct7); TEST_CASE(localvarStruct7);
TEST_CASE(localvarStruct8); TEST_CASE(localvarStruct8);
TEST_CASE(localvarStruct9); TEST_CASE(localvarStruct9);
TEST_CASE(localvarStruct10);
TEST_CASE(localvarStructArray); TEST_CASE(localvarStructArray);
TEST_CASE(localvarUnion1); TEST_CASE(localvarUnion1);
@ -4529,6 +4530,17 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void localvarStruct10() { // #6766
functionVariableUsage("struct S { int x; };\n"
"\n"
"void foo() {\n"
" struct S s;\n"
" s.x = 3;\n"
" memcpy (&s, &s2, sizeof (S));\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's.x' is assigned a value that is never used.\n", errout.str());
}
void localvarStructArray() { void localvarStructArray() {
// #3633 - detect that struct array is assigned a value // #3633 - detect that struct array is assigned a value
functionVariableUsage("void f() {\n" functionVariableUsage("void f() {\n"