Fix #11595 FN useStlAlgorithm with complex condition (#4848)

This commit is contained in:
chrchr-github 2023-03-04 11:58:12 +01:00 committed by GitHub
parent b4c90f8b2a
commit 9291421840
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 33 deletions

View File

@ -6895,19 +6895,19 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
<use-retval/> <use-retval/>
<const/> <const/>
<leak-ignore/> <leak-ignore/>
<arg nr="1"> <arg nr="1" direction="in">
<not-uninit/> <not-uninit/>
</arg> </arg>
<arg nr="2" default="0"> <arg nr="2" default="0" direction="in">
<not-uninit/> <not-uninit/>
</arg> </arg>
<arg nr="3" default="0"> <arg nr="3" default="0" direction="in">
<not-uninit/> <not-uninit/>
</arg> </arg>
<arg nr="4" default="0"> <arg nr="4" default="0" direction="in">
<not-uninit/> <not-uninit/>
</arg> </arg>
<arg nr="5" default="0"> <arg nr="5" default="0" direction="in">
<not-uninit/> <not-uninit/>
</arg> </arg>
</function> </function>

View File

@ -114,11 +114,9 @@ void ThreadResult::setProject(const ImportProject &prj)
// Determine the total size of all of the files to check, so that we can // Determine the total size of all of the files to check, so that we can
// show an accurate progress estimate // show an accurate progress estimate
quint64 sizeOfFiles = 0; mMaxProgress = std::accumulate(prj.fileSettings.begin(), prj.fileSettings.end(), quint64{ 0 }, [](quint64 v, const ImportProject::FileSettings& fs) {
for (const ImportProject::FileSettings& fs : prj.fileSettings) { return v + QFile(QString::fromStdString(fs.filename)).size();
sizeOfFiles += QFile(QString::fromStdString(fs.filename)).size(); });
}
mMaxProgress = sizeOfFiles;
} }
void ThreadResult::clearFiles() void ThreadResult::clearFiles()

View File

@ -2518,7 +2518,7 @@ static const Token *singleStatement(const Token *start)
return endStatement; return endStatement;
} }
static const Token *singleAssignInScope(const Token *start, nonneg int varid, bool &input) static const Token *singleAssignInScope(const Token *start, nonneg int varid, bool &input, const Settings* settings)
{ {
const Token *endStatement = singleStatement(start); const Token *endStatement = singleStatement(start);
if (!endStatement) if (!endStatement)
@ -2526,15 +2526,15 @@ static const Token *singleAssignInScope(const Token *start, nonneg int varid, bo
if (!Token::Match(start->next(), "%var% %assign%")) if (!Token::Match(start->next(), "%var% %assign%"))
return nullptr; return nullptr;
const Token *assignTok = start->tokAt(2); const Token *assignTok = start->tokAt(2);
if (isVariableChanged(assignTok->next(), endStatement, assignTok->astOperand1()->varId(), false, nullptr, true)) if (isVariableChanged(assignTok->next(), endStatement, assignTok->astOperand1()->varId(), /*globalvar*/ false, settings, /*cpp*/ true))
return nullptr; return nullptr;
if (isVariableChanged(assignTok->next(), endStatement, varid, false, nullptr, true)) if (isVariableChanged(assignTok->next(), endStatement, varid, /*globalvar*/ false, settings, /*cpp*/ true))
return nullptr; return nullptr;
input = Token::findmatch(assignTok->next(), "%varid%", endStatement, varid) || !Token::Match(start->next(), "%var% ="); input = Token::findmatch(assignTok->next(), "%varid%", endStatement, varid) || !Token::Match(start->next(), "%var% =");
return assignTok; return assignTok;
} }
static const Token *singleMemberCallInScope(const Token *start, nonneg int varid, bool &input) static const Token *singleMemberCallInScope(const Token *start, nonneg int varid, bool &input, const Settings* settings)
{ {
if (start->str() != "{") if (start->str() != "{")
return nullptr; return nullptr;
@ -2551,7 +2551,7 @@ static const Token *singleMemberCallInScope(const Token *start, nonneg int varid
if (!Token::findmatch(dotTok->tokAt(2), "%varid%", endStatement, varid)) if (!Token::findmatch(dotTok->tokAt(2), "%varid%", endStatement, varid))
return nullptr; return nullptr;
input = Token::Match(start->next(), "%var% . %name% ( %varid% )", varid); input = Token::Match(start->next(), "%var% . %name% ( %varid% )", varid);
if (isVariableChanged(dotTok->next(), endStatement, dotTok->astOperand1()->varId(), false, nullptr, true)) if (isVariableChanged(dotTok->next(), endStatement, dotTok->astOperand1()->varId(), /*globalvar*/ false, settings, /*cpp*/ true))
return nullptr; return nullptr;
return dotTok; return dotTok;
} }
@ -2571,7 +2571,7 @@ static const Token *singleIncrementInScope(const Token *start, nonneg int varid,
return varTok; return varTok;
} }
static const Token *singleConditionalInScope(const Token *start, nonneg int varid) static const Token *singleConditionalInScope(const Token *start, nonneg int varid, const Settings* settings)
{ {
if (start->str() != "{") if (start->str() != "{")
return nullptr; return nullptr;
@ -2588,7 +2588,7 @@ static const Token *singleConditionalInScope(const Token *start, nonneg int vari
return nullptr; return nullptr;
if (!Token::findmatch(start, "%varid%", bodyTok, varid)) if (!Token::findmatch(start, "%varid%", bodyTok, varid))
return nullptr; return nullptr;
if (isVariableChanged(start, bodyTok, varid, false, nullptr, true)) if (isVariableChanged(start, bodyTok, varid, /*globalvar*/ false, settings, /*cpp*/ true))
return nullptr; return nullptr;
return bodyTok; return bodyTok;
} }
@ -2721,7 +2721,7 @@ void CheckStl::useStlAlgorithm()
// Check for single assignment // Check for single assignment
bool useLoopVarInAssign; bool useLoopVarInAssign;
const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign); const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign, mSettings);
if (assignTok) { if (assignTok) {
if (!checkAssignee(assignTok->astOperand1())) if (!checkAssignee(assignTok->astOperand1()))
continue; continue;
@ -2751,7 +2751,7 @@ void CheckStl::useStlAlgorithm()
} }
// Check for container calls // Check for container calls
bool useLoopVarInMemCall; bool useLoopVarInMemCall;
const Token *memberAccessTok = singleMemberCallInScope(bodyTok, loopVar->varId(), useLoopVarInMemCall); const Token *memberAccessTok = singleMemberCallInScope(bodyTok, loopVar->varId(), useLoopVarInMemCall, mSettings);
if (memberAccessTok && !isIteratorLoop) { if (memberAccessTok && !isIteratorLoop) {
const Token *memberCallTok = memberAccessTok->astOperand2(); const Token *memberCallTok = memberAccessTok->astOperand2();
const int contVarId = memberAccessTok->astOperand1()->varId(); const int contVarId = memberAccessTok->astOperand1()->varId();
@ -2784,10 +2784,10 @@ void CheckStl::useStlAlgorithm()
} }
// Check for conditionals // Check for conditionals
const Token *condBodyTok = singleConditionalInScope(bodyTok, loopVar->varId()); const Token *condBodyTok = singleConditionalInScope(bodyTok, loopVar->varId(), mSettings);
if (condBodyTok) { if (condBodyTok) {
// Check for single assign // Check for single assign
assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign); assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign, mSettings);
if (assignTok) { if (assignTok) {
if (!checkAssignee(assignTok->astOperand1())) if (!checkAssignee(assignTok->astOperand1()))
continue; continue;
@ -2815,7 +2815,7 @@ void CheckStl::useStlAlgorithm()
} }
// Check for container call // Check for container call
memberAccessTok = singleMemberCallInScope(condBodyTok, loopVar->varId(), useLoopVarInMemCall); memberAccessTok = singleMemberCallInScope(condBodyTok, loopVar->varId(), useLoopVarInMemCall, mSettings);
if (memberAccessTok) { if (memberAccessTok) {
const Token *memberCallTok = memberAccessTok->astOperand2(); const Token *memberCallTok = memberAccessTok->astOperand2();
const int contVarId = memberAccessTok->astOperand1()->varId(); const int contVarId = memberAccessTok->astOperand1()->varId();

View File

@ -390,12 +390,9 @@ public:
* @return true for the file to be excluded. * @return true for the file to be excluded.
*/ */
bool configurationExcluded(const std::string &file) const { bool configurationExcluded(const std::string &file) const {
for (const std::string & configExcludePath : configExcludePaths) { return std::any_of(configExcludePaths.begin(), configExcludePaths.end(), [&file](const std::string& path) {
if (file.length()>=configExcludePath.length() && file.compare(0,configExcludePath.length(),configExcludePath)==0) { return file.length() >= path.length() && file.compare(0, path.length(), path) == 0;
return true; });
}
}
return false;
} }
/** /**

View File

@ -232,11 +232,9 @@ bool Token::isUpperCaseName() const
{ {
if (!isName()) if (!isName())
return false; return false;
for (const char i : mStr) { return std::none_of(mStr.begin(), mStr.end(), [](char c) {
if (std::islower(i)) return std::islower(c);
return false; });
}
return true;
} }
void Token::concatStr(std::string const& b) void Token::concatStr(std::string const& b)

View File

@ -5284,6 +5284,16 @@ private:
" }\n" " }\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:9]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str()); ASSERT_EQUALS("[test.cpp:9]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str());
check("bool f(const std::set<std::string>& set, const std::string& f) {\n" // #11595
" for (const std::string& s : set) {\n"
" if (f.length() >= s.length() && f.compare(0, s.length(), s) == 0) {\n"
" return true;\n"
" }\n"
" }\n"
" return false;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (style) Consider using std::any_of algorithm instead of a raw loop.\n", errout.str());
} }
void loopAlgoMinMax() { void loopAlgoMinMax() {