Fix 11147: FP invalidContainer with substr() (#4333)

* Fix 11147: FP invalidContainer with substr()

* Format
This commit is contained in:
Paul Fultz II 2022-08-03 12:04:44 -05:00 committed by GitHub
parent dd927aab9b
commit 6cb3a79a64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 3 deletions

View File

@ -1068,6 +1068,21 @@ static const ValueFlow::Value* getInnerLifetime(const Token* tok,
return nullptr; return nullptr;
} }
static const Token* endOfExpression(const Token* tok)
{
if (!tok)
return nullptr;
const Token* parent = tok->astParent();
while (Token::simpleMatch(parent, "."))
parent = parent->astParent();
if (!parent)
return tok->next();
const Token* endToken = nextAfterAstRightmostLeaf(parent);
if (!endToken)
return parent->next();
return endToken;
}
void CheckStl::invalidContainer() void CheckStl::invalidContainer()
{ {
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1120,9 +1135,7 @@ void CheckStl::invalidContainer()
} }
if (Token::Match(assignExpr, "%assign%") && Token::Match(assignExpr->astOperand1(), "%var%")) if (Token::Match(assignExpr, "%assign%") && Token::Match(assignExpr->astOperand1(), "%var%"))
skipVarIds.insert(assignExpr->astOperand1()->varId()); skipVarIds.insert(assignExpr->astOperand1()->varId());
const Token* endToken = nextAfterAstRightmostLeaf(tok->next()->astParent()); const Token* endToken = endOfExpression(tok);
if (!endToken)
endToken = tok->next();
const ValueFlow::Value* v = nullptr; const ValueFlow::Value* v = nullptr;
ErrorPath errorPath; ErrorPath errorPath;
PathAnalysis::Info info = PathAnalysis::Info info =

View File

@ -5465,6 +5465,18 @@ private:
"}\n", "}\n",
true); true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #11147
check("void f(std::string& s) {\n"
" if (!s.empty()) {\n"
" std::string::iterator it = s.begin();\n"
" s = s.substr(it - s.begin());\n"
" }\n"
"}\n",
true);
ASSERT_EQUALS(
"[test.cpp:4]: (performance) Ineffective call of function 'substr' because a prefix of the string is assigned to itself. Use resize() or pop_back() instead.\n",
errout.str());
} }
void invalidContainerLoop() { void invalidContainerLoop() {