diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index fb5996181..a0138a3c9 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -579,6 +579,21 @@ static const Token * skipBrackets(const Token *tok) } +// Skip [ .. ] . x +static const Token * skipBracketsAndMembers(const Token *tok) +{ + while (tok) { + if (tok->str() == "[") + tok = tok->link()->next(); + else if (Token::Match(tok, ". %var%")) + tok = tok->tokAt(2); + else + break; + } + return tok; +} + + //--------------------------------------------------------------------------- // Usage of function variables //--------------------------------------------------------------------------- @@ -804,7 +819,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const } } - const Token *equal = skipBrackets(tok->next()); + const Token * const equal = skipBracketsAndMembers(tok->next()); // checked for chained assignments if (tok != start && equal && equal->str() == "=") { @@ -818,7 +833,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const } // assignment - else if (Token::Match(tok, "%var% [") && Token::simpleMatch(skipBrackets(tok->next()), "=")) { + else if (Token::Match(tok, "%var% [") && Token::simpleMatch(skipBracketsAndMembers(tok->next()), "=")) { unsigned int varid = tok->varId(); const Variables::VariableUsage *var = variables.find(varid); diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 433dbbfc3..bc311078c 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -117,6 +117,7 @@ private: TEST_CASE(localvarStruct4); // Ticket #31: sigsegv on incomplete struct TEST_CASE(localvarStruct5); TEST_CASE(localvarStruct6); + TEST_CASE(localvarStructArray); TEST_CASE(localvarOp); // Usage with arithmetic operators TEST_CASE(localvarInvert); // Usage with inverted variable @@ -2462,6 +2463,15 @@ private: ASSERT_EQUALS("", errout.str()); } + void localvarStructArray() { + // #3633 - detect that struct array is assigned a value + functionVariableUsage("void f() {\n" + " struct X x[10];\n" + " x[0].a = 0;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used\n", errout.str()); + } + void localvarOp() { const char op[] = "+-*/%&|^"; for (const char *p = op; *p; ++p) {