diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 07c914791..f43cceb60 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -681,9 +681,9 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const const Variable* var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok2->varId()); if (var && var->nameToken() == tok2) { // Declaration: Skip tok = tok2->next(); - if (tok && Token::Match(tok, "( %var% )")) // Simple initialization through copy ctor + if (Token::Match(tok, "( %var% )")) // Simple initialization through copy ctor tok = tok->next(); - else if (tok && Token::Match(tok, "= %var% ;")) // Simple initialization + else if (Token::Match(tok, "= %var% ;")) // Simple initialization tok = tok->next(); else if (var->typeEndToken()->str() == ">") // Be careful with types like std::vector tok = tok->previous(); @@ -885,7 +885,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const Token::Match(tok->next(), "%var%") && !Token::Match(tok->next(), "true|false|new") && tok->strAt(2) != "=") variables.readAll(tok->next()->varId()); - else if (Token::Match(tok, "%var%") && (tok->next()->str() == ")" || tok->next()->isExtendedOp())) + else if (Token::Match(tok, "%var%") && tok->next() && (tok->next()->str() == ")" || tok->next()->isExtendedOp())) variables.readAll(tok->varId()); else if (Token::Match(tok, "%var% ;") && Token::Match(tok->previous(), "[;{}:]")) @@ -908,9 +908,10 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const else if (tok->isAssignmentOp()) { for (const Token *tok2 = tok->next(); tok2 && tok2->str() != ";"; tok2 = tok2->next()) { if (tok2->varId()) { - variables.read(tok2->varId()); if (tok2->next()->isAssignmentOp()) variables.write(tok2->varId()); + else + variables.read(tok2->varId()); } } } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 7b449e4ea..158e4d334 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -142,6 +142,8 @@ private: TEST_CASE(localvarIfNOT); // #3104 - if ( NOT var ) TEST_CASE(localvarAnd); // #3672 TEST_CASE(localvarSwitch); // #3744 - false positive when localvar is used in switch + + TEST_CASE(crash1); } void checkStructMemberUsage(const char code[]) { @@ -3192,6 +3194,13 @@ private: // Don't write an error that "a" is not used ASSERT_EQUALS("", errout.str()); } + + void crash1() { + functionVariableUsage("SAL_WNODEPRECATED_DECLARATIONS_PUSH\n" + "void convertToTokenArray() {\n" + "}\n" + "SAL_WNODEPRECATED_DECLARATIONS_POP"); // #4033 + } }; REGISTER_TEST(TestUnusedVar)