From c8d688607a619f7dbc10b23dc98702b5d33d11f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Dec 2018 19:01:05 +0100 Subject: [PATCH] Fixed #8901 (Unused value: const variable initialization) --- lib/astutils.cpp | 5 ++++- lib/checkunusedvar.cpp | 16 +++++++++++----- test/testunusedvar.cpp | 5 +++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index bab173fc7..ecd372d7d 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1138,9 +1138,12 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const if (exprVarIds.find(tok->varId()) != exprVarIds.end()) { const Token *parent = tok; bool other = false; + bool same = false; while (Token::Match(parent->astParent(), ".|::|[")) { parent = parent->astParent(); - if (Token::Match(parent, ". %var%") && parent->next()->varId() && exprVarIds.find(parent->next()->varId()) == exprVarIds.end()) { + if (parent && isSameExpression(mCpp, false, expr, parent->astOperand1(), mLibrary, false, false, nullptr)) + same = true; + if (!same && Token::Match(parent, ". %var%") && parent->next()->varId() && exprVarIds.find(parent->next()->varId()) == exprVarIds.end()) { other = true; break; } diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 984a7fb42..f85b789a5 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1236,6 +1236,16 @@ void CheckUnusedVar::checkFunctionVariableUsage() if (Token::simpleMatch(tok, "try {")) // todo: check try blocks tok = tok->linkAt(1); + const Token *varDecl = nullptr; + if (tok->variable() && tok->variable()->nameToken() == tok) { + const Token * eq = tok->next(); + while (Token::simpleMatch(eq, "[")) + eq = eq->link()->next(); + if (Token::simpleMatch(eq, "=")) { + varDecl = tok; + tok = eq; + } + } // not assignment/initialization => continue if ((!tok->isAssignmentOp() || !tok->astOperand1()) && !(Token::Match(tok, "%var% (") && tok->variable() && tok->variable()->nameToken() == tok)) continue; @@ -1271,11 +1281,7 @@ void CheckUnusedVar::checkFunctionVariableUsage() // Is there a redundant assignment? const Token *start = tok->findExpressionStartEndTokens().second->next(); - const Token *expr = tok->astOperand1(); - if (Token::Match(expr->previous(), "%var% [") && expr->previous()->variable() && expr->previous()->variable()->nameToken() == expr->previous()) - expr = expr->previous(); - else if (Token::Match(expr, "& %var% =")) - expr = expr->next(); + const Token *expr = varDecl ? varDecl : tok->astOperand1(); FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library); if (fwdAnalysis.unusedValue(expr, start, scope->bodyEnd)) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 415e403b7..ee1df38ff 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -3966,6 +3966,11 @@ private: "}"); ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's' is assigned a value that is never used.\n", errout.str()); + functionVariableUsage("void foo() {\n" // #8901 + " const std::string s = \"foo\";\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's' is assigned a value that is never used.\n", errout.str()); + functionVariableUsage("std::string foo() {\n" " std::string s;\n" // Class instances are initialized. Assignment is not necessary " return s;\n"