Set functions for calls through iterators (#4763)
This commit is contained in:
parent
20ff2d7172
commit
8af1026696
|
@ -2865,13 +2865,9 @@ void CheckClass::checkCopyCtorAndEqOperator()
|
||||||
|
|
||||||
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
|
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
|
||||||
|
|
||||||
bool hasNonStaticVars = false;
|
const bool hasNonStaticVars = std::any_of(scope->varlist.begin(), scope->varlist.end(), [](const Variable& var) {
|
||||||
for (std::list<Variable>::const_iterator var = scope->varlist.cbegin(); var != scope->varlist.cend(); ++var) {
|
return !var.isStatic();
|
||||||
if (!var->isStatic()) {
|
});
|
||||||
hasNonStaticVars = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hasNonStaticVars)
|
if (!hasNonStaticVars)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -2860,7 +2860,8 @@ void CheckStl::useStlAlgorithm()
|
||||||
if (isEarlyExit(condBodyTok)) {
|
if (isEarlyExit(condBodyTok)) {
|
||||||
const Token *loopVar2 = Token::findmatch(condBodyTok, "%varid%", condBodyTok->link(), loopVar->varId());
|
const Token *loopVar2 = Token::findmatch(condBodyTok, "%varid%", condBodyTok->link(), loopVar->varId());
|
||||||
std::string algo;
|
std::string algo;
|
||||||
if (loopVar2)
|
if (loopVar2 ||
|
||||||
|
(isIteratorLoop && loopVar->variable() && precedes(loopVar->variable()->nameToken(), tok))) // iterator declared outside the loop
|
||||||
algo = "std::find_if";
|
algo = "std::find_if";
|
||||||
else
|
else
|
||||||
algo = "std::any_of";
|
algo = "std::any_of";
|
||||||
|
|
|
@ -4409,15 +4409,9 @@ Scope::Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *
|
||||||
|
|
||||||
bool Scope::hasDefaultConstructor() const
|
bool Scope::hasDefaultConstructor() const
|
||||||
{
|
{
|
||||||
if (numConstructors) {
|
return numConstructors > 0 && std::any_of(functionList.begin(), functionList.end(), [](const Function& func) {
|
||||||
std::list<Function>::const_iterator func;
|
return func.type == Function::eConstructor && func.argCount() == 0;
|
||||||
|
});
|
||||||
for (func = functionList.cbegin(); func != functionList.cend(); ++func) {
|
|
||||||
if (func->type == Function::eConstructor && func->argCount() == 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessControl Scope::defaultAccess() const
|
AccessControl Scope::defaultAccess() const
|
||||||
|
@ -5584,6 +5578,8 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const
|
||||||
return var->typeScope()->findFunction(tok, var->valueType()->constness == 1);
|
return var->typeScope()->findFunction(tok, var->valueType()->constness == 1);
|
||||||
if (var && var->smartPointerType() && var->smartPointerType()->classScope && tok1->next()->originalName() == "->")
|
if (var && var->smartPointerType() && var->smartPointerType()->classScope && tok1->next()->originalName() == "->")
|
||||||
return var->smartPointerType()->classScope->findFunction(tok, var->valueType()->constness == 1);
|
return var->smartPointerType()->classScope->findFunction(tok, var->valueType()->constness == 1);
|
||||||
|
if (var && var->iteratorType() && var->iteratorType()->classScope && tok1->next()->originalName() == "->")
|
||||||
|
return var->iteratorType()->classScope->findFunction(tok, var->valueType()->constness == 1);
|
||||||
} else if (Token::simpleMatch(tok->previous()->astOperand1(), "(")) {
|
} else if (Token::simpleMatch(tok->previous()->astOperand1(), "(")) {
|
||||||
const Token *castTok = tok->previous()->astOperand1();
|
const Token *castTok = tok->previous()->astOperand1();
|
||||||
if (castTok->isCast()) {
|
if (castTok->isCast()) {
|
||||||
|
@ -6280,12 +6276,11 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
|
||||||
const Scope *typeScope = vt1->typeScope;
|
const Scope *typeScope = vt1->typeScope;
|
||||||
if (!typeScope)
|
if (!typeScope)
|
||||||
return;
|
return;
|
||||||
for (std::list<Variable>::const_iterator it = typeScope->varlist.cbegin(); it != typeScope->varlist.cend(); ++it) {
|
auto it = std::find_if(typeScope->varlist.begin(), typeScope->varlist.end(), [&name](const Variable& v) {
|
||||||
if (it->nameToken()->str() == name) {
|
return v.nameToken()->str() == name;
|
||||||
|
});
|
||||||
|
if (it != typeScope->varlist.end())
|
||||||
var = &*it;
|
var = &*it;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (var)
|
if (var)
|
||||||
setValueType(parent, *var);
|
setValueType(parent, *var);
|
||||||
|
|
|
@ -3809,11 +3809,9 @@ void TemplateSimplifier::simplifyTemplates(
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::list<TokenAndName>::const_iterator it = mInstantiatedTemplates.cbegin(); it != mInstantiatedTemplates.cend(); ++it) {
|
for (std::list<TokenAndName>::const_iterator it = mInstantiatedTemplates.cbegin(); it != mInstantiatedTemplates.cend(); ++it) {
|
||||||
std::list<TokenAndName>::iterator decl;
|
auto decl = std::find_if(mTemplateDeclarations.begin(), mTemplateDeclarations.end(), [&it](const TokenAndName& decl) {
|
||||||
for (decl = mTemplateDeclarations.begin(); decl != mTemplateDeclarations.end(); ++decl) {
|
return decl.token() == it->token();
|
||||||
if (decl->token() == it->token())
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (decl != mTemplateDeclarations.end()) {
|
if (decl != mTemplateDeclarations.end()) {
|
||||||
if (it->isSpecialization()) {
|
if (it->isSpecialization()) {
|
||||||
// delete the "template < >"
|
// delete the "template < >"
|
||||||
|
|
|
@ -1955,9 +1955,7 @@ private:
|
||||||
" for (it = l.begin(); it != l.end(); ++it)\n"
|
" for (it = l.begin(); it != l.end(); ++it)\n"
|
||||||
" it->g(0);\n"
|
" it->g(0);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
TODO_ASSERT_EQUALS("",
|
ASSERT_EQUALS("", errout.str());
|
||||||
"[test.cpp:5]: (information) --check-library: There is no matching configuration for function F::g()\n",
|
|
||||||
errout.str());
|
|
||||||
|
|
||||||
settings = settings_old;
|
settings = settings_old;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5241,6 +5241,22 @@ private:
|
||||||
" return ret;\n"
|
" return ret;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (style) Consider using std::any_of, std::all_of, std::none_of algorithm instead of a raw loop.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (style) Consider using std::any_of, std::all_of, std::none_of algorithm instead of a raw loop.\n", errout.str());
|
||||||
|
|
||||||
|
check("struct T {\n"
|
||||||
|
" std::vector<int> v0, v1;\n"
|
||||||
|
" void g();\n"
|
||||||
|
"};\n"
|
||||||
|
"void T::g() {\n"
|
||||||
|
" for (std::vector<int>::const_iterator it0 = v0.cbegin(); it0 != v0.cend(); ++it0) {\n"
|
||||||
|
" std::vector<int>::iterator it1;\n"
|
||||||
|
" for (it1 = v1.begin(); it1 != v1.end(); ++it1)\n"
|
||||||
|
" if (*it0 == *it1)\n"
|
||||||
|
" break;\n"
|
||||||
|
" if (it1 != v1.end())\n"
|
||||||
|
" v1.erase(it1);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:9]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void loopAlgoMinMax() {
|
void loopAlgoMinMax() {
|
||||||
|
|
|
@ -438,6 +438,7 @@ private:
|
||||||
TEST_CASE(findFunction42);
|
TEST_CASE(findFunction42);
|
||||||
TEST_CASE(findFunction43); // #10087
|
TEST_CASE(findFunction43); // #10087
|
||||||
TEST_CASE(findFunction44); // #11182
|
TEST_CASE(findFunction44); // #11182
|
||||||
|
TEST_CASE(findFunction45);
|
||||||
TEST_CASE(findFunctionContainer);
|
TEST_CASE(findFunctionContainer);
|
||||||
TEST_CASE(findFunctionExternC);
|
TEST_CASE(findFunctionExternC);
|
||||||
TEST_CASE(findFunctionGlobalScope); // ::foo
|
TEST_CASE(findFunctionGlobalScope); // ::foo
|
||||||
|
@ -6959,6 +6960,19 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void findFunction45() {
|
||||||
|
GET_SYMBOL_DB("struct S { void g(int); };\n"
|
||||||
|
"void f(std::vector<S>& v) {\n"
|
||||||
|
" std::vector<S>::iterator it = v.begin();\n"
|
||||||
|
" it->g(1);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "g ( 1");
|
||||||
|
ASSERT(functok);
|
||||||
|
ASSERT(functok->function());
|
||||||
|
ASSERT(functok->function()->name() == "g");
|
||||||
|
ASSERT_EQUALS(1, functok->function()->tokenDef->linenr());
|
||||||
|
}
|
||||||
|
|
||||||
void findFunctionContainer() {
|
void findFunctionContainer() {
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue