Fix #7908 FN: redundant assignment in loop (#3650)

This commit is contained in:
chrchr-github 2022-02-22 09:51:44 +01:00 committed by GitHub
parent 1ac16413ea
commit 172aafdeb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 67 additions and 17 deletions

View File

@ -974,7 +974,6 @@ void CheckIO::checkFormatString(const Token * const tok,
bool done = false; bool done = false;
while (!done) { while (!done) {
if (i == formatString.end()) { if (i == formatString.end()) {
done = true;
break; break;
} }
switch (*i) { switch (*i) {

View File

@ -1278,7 +1278,8 @@ void CheckUnusedVar::checkFunctionVariableUsage()
continue; continue;
FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library); FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library);
if (fwdAnalysis.unusedValue(expr, start, scope->bodyEnd)) { const Token* scopeEnd = getEndOfExprScope(expr, scope, /*smallest*/ false);
if (fwdAnalysis.unusedValue(expr, start, scopeEnd)) {
if (!bailoutTypeName.empty() && bailoutTypeName != "auto") { if (!bailoutTypeName.empty() && bailoutTypeName != "auto") {
if (mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) { if (mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) {
reportError(tok, reportError(tok,

View File

@ -1646,7 +1646,6 @@ void CppCheck::analyseClangTidy(const ImportProject::FileSettings &fileSettings)
const std::string lineNumString = line.substr(endNamePos + 1, endLinePos - endNamePos - 1); const std::string lineNumString = line.substr(endNamePos + 1, endLinePos - endNamePos - 1);
const std::string columnNumString = line.substr(endLinePos + 1, endColumnPos - endLinePos - 1); const std::string columnNumString = line.substr(endLinePos + 1, endColumnPos - endLinePos - 1);
const std::string errorTypeString = line.substr(endColumnPos + 1, endMsgTypePos - endColumnPos - 1);
const std::string messageString = line.substr(endMsgTypePos + 1, endErrorPos - endMsgTypePos - 1); const std::string messageString = line.substr(endMsgTypePos + 1, endErrorPos - endMsgTypePos - 1);
const std::string errorString = line.substr(endErrorPos, line.length()); const std::string errorString = line.substr(endErrorPos, line.length());

View File

@ -941,7 +941,6 @@ void TemplateSimplifier::getTemplateInstantiations()
// Add outer template.. // Add outer template..
if (templateParameters(tok->next()) || tok->strAt(2) == ">") { if (templateParameters(tok->next()) || tok->strAt(2) == ">") {
const std::string scopeName1(scopeName);
while (true) { while (true) {
const std::string fullName = scopeName + (scopeName.empty()?"":" :: ") + const std::string fullName = scopeName + (scopeName.empty()?"":" :: ") +
qualification + (qualification.empty()?"":" :: ") + tok->str(); qualification + (qualification.empty()?"":" :: ") + tok->str();
@ -1141,6 +1140,8 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
"noparamend", "noparamend",
"TemplateSimplifier couldn't find end of template parameter.", "TemplateSimplifier couldn't find end of template parameter.",
Certainty::normal); Certainty::normal);
if (mErrorLogger && mSettings->severity.isEnabled(Severity::debug))
mErrorLogger->reportErr(errmsg);
} }
break; break;
} }
@ -1936,20 +1937,11 @@ void TemplateSimplifier::expandTemplate(
// replace type with given type.. // replace type with given type..
if (itype < typeParametersInDeclaration.size() && itype < mTypesUsedInTemplateInstantiation.size()) { if (itype < typeParametersInDeclaration.size() && itype < mTypesUsedInTemplateInstantiation.size()) {
unsigned int typeindentlevel = 0;
std::stack<Token *> brackets1; // holds "(" and "{" tokens std::stack<Token *> brackets1; // holds "(" and "{" tokens
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token(); for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token();
typetok && (typeindentlevel>0 || !Token::Match(typetok, ",|>")); typetok && !Token::Match(typetok, ",|>");
typetok = typetok->next()) { typetok = typetok->next()) {
if (!Token::simpleMatch(typetok, "...")) { if (!Token::simpleMatch(typetok, "...")) {
if (Token::Match(typetok, "%name% <") && (typetok->strAt(2) == ">" || templateParameters(typetok->next())))
++typeindentlevel;
else if (typeindentlevel > 0 && typetok->str() == ">")
--typeindentlevel;
else if (typetok->str() == "(")
++typeindentlevel;
else if (typetok->str() == ")")
--typeindentlevel;
mTokenList.addtoken(typetok, tok5); mTokenList.addtoken(typetok, tok5);
Token *back = mTokenList.back(); Token *back = mTokenList.back();
if (Token::Match(back, "{|(|[")) { if (Token::Match(back, "{|(|[")) {

View File

@ -3427,7 +3427,7 @@ static const Token* getEndOfVarScope(const Variable* var)
return innerScope->bodyEnd; return innerScope->bodyEnd;
} }
static const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope = nullptr) const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope, bool smallest)
{ {
const Token* end = nullptr; const Token* end = nullptr;
bool local = false; bool local = false;
@ -3436,7 +3436,7 @@ static const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScop
local |= var->isLocal(); local |= var->isLocal();
if (var->isLocal() || var->isArgument()) { if (var->isLocal() || var->isArgument()) {
const Token* varEnd = getEndOfVarScope(var); const Token* varEnd = getEndOfVarScope(var);
if (!end || precedes(varEnd, end)) if (!end || (smallest ? precedes(varEnd, end) : succeeds(varEnd, end)))
end = varEnd; end = varEnd;
} }
} }
@ -3477,9 +3477,10 @@ static const Token* getEndOfVarScope(const Token* tok, const std::vector<const V
varScope = varScope->nestedIn; varScope = varScope->nestedIn;
} }
} }
if (varScope && (!endOfVarScope || precedes(varScope->bodyEnd, endOfVarScope))) if (varScope && (!endOfVarScope || precedes(endOfVarScope, varScope->bodyEnd))) {
endOfVarScope = varScope->bodyEnd; endOfVarScope = varScope->bodyEnd;
} }
}
return endOfVarScope; return endOfVarScope;
} }

View File

@ -42,6 +42,7 @@ class Token;
class TokenList; class TokenList;
class ValueType; class ValueType;
class Variable; class Variable;
class Scope;
template<class T> template<class T>
class ValuePtr; class ValuePtr;
@ -518,4 +519,6 @@ CPPCHECKLIB std::vector<ValueFlow::Value> getLifetimeObjValues(const Token* tok,
bool inconclusive = false, bool inconclusive = false,
MathLib::bigint path = 0); MathLib::bigint path = 0);
const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope = nullptr, bool smallest = true);
#endif // valueflowH #endif // valueflowH

View File

@ -3362,6 +3362,61 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'sum' is assigned a value that is never used.\n" ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'sum' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Variable 'sum' is assigned a value that is never used.\n", errout.str()); "[test.cpp:5]: (style) Variable 'sum' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void f(int c) {\n" // #7908
" int b = 0;\n"
" while (g()) {\n"
" int a = c;\n"
" b = a;\n"
" if (a == 4)\n"
" a = 5;\n"
" }\n"
" h(b);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void f(const std::vector<int>& v) {\n"
" while (g()) {\n"
" const std::vector<int>& v2 = h();\n"
" if (std::vector<int>{ 1, 2, 3 }.size() > v2.size()) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(const std::vector<int>& v) {\n"
" while (g()) {\n"
" const std::vector<int>& v2 = h();\n"
" if (std::vector<int>({ 1, 2, 3 }).size() > v2.size()) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(const std::string &c) {\n"
" std::string s = str();\n"
" if (s[0] == '>')\n"
" s[0] = '<';\n"
" if (s == c) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(bool b) {\n"
" std::map<std::string, std::vector<std::string>> m;\n"
" if (b) {\n"
" const std::string n = g();\n"
" std::vector<std::string> c = h();\n"
" m[n] = c;\n"
" }\n"
" j(m);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct S { int i; };\n"
"S f(S s, bool b) {\n"
" if (b)\n"
" s.i = 1;\n"
" return s;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void localvaralias1() { void localvaralias1() {