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/>
<const/>
<leak-ignore/>
<arg nr="1">
<arg nr="1" direction="in">
<not-uninit/>
</arg>
<arg nr="2" default="0">
<arg nr="2" default="0" direction="in">
<not-uninit/>
</arg>
<arg nr="3" default="0">
<arg nr="3" default="0" direction="in">
<not-uninit/>
</arg>
<arg nr="4" default="0">
<arg nr="4" default="0" direction="in">
<not-uninit/>
</arg>
<arg nr="5" default="0">
<arg nr="5" default="0" direction="in">
<not-uninit/>
</arg>
</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
// show an accurate progress estimate
quint64 sizeOfFiles = 0;
for (const ImportProject::FileSettings& fs : prj.fileSettings) {
sizeOfFiles += QFile(QString::fromStdString(fs.filename)).size();
}
mMaxProgress = sizeOfFiles;
mMaxProgress = std::accumulate(prj.fileSettings.begin(), prj.fileSettings.end(), quint64{ 0 }, [](quint64 v, const ImportProject::FileSettings& fs) {
return v + QFile(QString::fromStdString(fs.filename)).size();
});
}
void ThreadResult::clearFiles()

View File

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

View File

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

View File

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

View File

@ -5284,6 +5284,16 @@ private:
" }\n"
"}\n");
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() {