Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,10 @@ bool astIsContainerString(const Token* tok)
return container->stdStringLike;
}

static std::pair<const Token*, const Library::Container*> getContainerFunction(const Token* tok, const Settings* settings)
static std::pair<const Token*, const Library::Container*> getContainerFunction(const Token* tok, const Library& library)
{
const Library::Container* cont{};
if (!tok || !tok->valueType() || (!tok->valueType()->container && (!settings || !(cont = settings->library.detectContainerOrIterator(tok->valueType()->smartPointerTypeToken)))))
if (!tok || !tok->valueType() || (!tok->valueType()->container && (!(cont = library.detectContainerOrIterator(tok->valueType()->smartPointerTypeToken)))))
return {};
const Token* parent = tok->astParent();
if (Token::Match(parent, ". %name% (") && astIsLHS(tok)) {
Expand All @@ -301,19 +301,19 @@ static std::pair<const Token*, const Library::Container*> getContainerFunction(c
return {};
}

Library::Container::Action astContainerAction(const Token* tok, const Token** ftok, const Settings* settings)
Library::Container::Action astContainerAction(const Token* tok, const Library& library, const Token** ftok)
{
const auto ftokCont = getContainerFunction(tok, settings);
const auto ftokCont = getContainerFunction(tok, library);
if (ftok)
*ftok = ftokCont.first;
if (!ftokCont.first)
return Library::Container::Action::NO_ACTION;
return ftokCont.second->getAction(ftokCont.first->str());
}

Library::Container::Yield astContainerYield(const Token* tok, const Token** ftok, const Settings* settings)
Library::Container::Yield astContainerYield(const Token* tok, const Library& library, const Token** ftok)
{
const auto ftokCont = getContainerFunction(tok, settings);
const auto ftokCont = getContainerFunction(tok, library);
if (ftok)
*ftok = ftokCont.first;
if (!ftokCont.first)
Expand Down Expand Up @@ -2895,7 +2895,7 @@ static bool isExpressionChangedAt(const F& getExprTok,
(!(tok->function() && (tok->function()->isAttributePure() || tok->function()->isAttributeConst())))) {
if (!Token::simpleMatch(tok->astParent(), "."))
return true;
const auto yield = astContainerYield(tok->astParent()->astOperand1());
const auto yield = astContainerYield(tok->astParent()->astOperand1(), settings.library);
if (yield != Library::Container::Yield::SIZE && yield != Library::Container::Yield::EMPTY &&
yield != Library::Container::Yield::BUFFER && yield != Library::Container::Yield::BUFFER_NT)
// TODO: Is global variable really changed by function call?
Expand Down
4 changes: 2 additions & 2 deletions lib/astutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ bool astIsContainerView(const Token* tok);
bool astIsContainerOwned(const Token* tok);
bool astIsContainerString(const Token* tok);

Library::Container::Action astContainerAction(const Token* tok, const Token** ftok = nullptr, const Settings* settings = nullptr);
Library::Container::Yield astContainerYield(const Token* tok, const Token** ftok = nullptr, const Settings* settings = nullptr);
Library::Container::Action astContainerAction(const Token* tok, const Library& library, const Token** ftok = nullptr);
Library::Container::Yield astContainerYield(const Token* tok, const Library& library, const Token** ftok = nullptr);

Library::Container::Yield astFunctionYield(const Token* tok, const Settings& settings, const Token** ftok = nullptr);

Expand Down
18 changes: 9 additions & 9 deletions lib/checkautovariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,14 @@ static bool isAutoVarArray(const Token *tok)
return false;
}

static bool isLocalContainerBuffer(const Token* tok)
static bool isLocalContainerBuffer(const Token* tok, const Settings& settings)
{
if (!tok)
return false;

// x+y
if (tok->str() == "+")
return isLocalContainerBuffer(tok->astOperand1()) || isLocalContainerBuffer(tok->astOperand2());
return isLocalContainerBuffer(tok->astOperand1(), settings) || isLocalContainerBuffer(tok->astOperand2(), settings);

if (tok->str() != "(" || !Token::simpleMatch(tok->astOperand1(), "."))
return false;
Expand All @@ -161,7 +161,7 @@ static bool isLocalContainerBuffer(const Token* tok)
if (!var || !var->isLocal() || var->isStatic())
return false;

const Library::Container::Yield yield = astContainerYield(tok);
const Library::Container::Yield yield = astContainerYield(tok, settings.library);

return yield == Library::Container::Yield::BUFFER || yield == Library::Container::Yield::BUFFER_NT;
}
Expand Down Expand Up @@ -237,8 +237,8 @@ void CheckAutoVariables::assignFunctionArg()
}
}

static bool isAutoVariableRHS(const Token* tok) {
return isAddressOfLocalVariable(tok) || isAutoVarArray(tok) || isLocalContainerBuffer(tok);
static bool isAutoVariableRHS(const Token* tok, const Settings& settings) {
return isAddressOfLocalVariable(tok) || isAutoVarArray(tok) || isLocalContainerBuffer(tok, settings);
}

static bool hasOverloadedAssignment(const Token* tok, bool& inconclusive)
Expand Down Expand Up @@ -275,23 +275,23 @@ void CheckAutoVariables::autoVariables()
continue;
}
// Critical assignment
if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2())) {
if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2(), *mSettings)) {
checkAutoVariableAssignment(tok->next(), false);
} else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2())) {
} else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2(), *mSettings)) {
const Token* lhs = tok->tokAt(2);
bool inconclusive = false;
if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive))
checkAutoVariableAssignment(tok->next(), inconclusive);
tok = tok->tokAt(4);
} else if (Token::Match(tok, "[;{}] %var% . %var% =") && isPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(4)->astOperand2())) {
} else if (Token::Match(tok, "[;{}] %var% . %var% =") && isPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(4)->astOperand2(), *mSettings)) {
const Token* lhs = tok->tokAt(3);
bool inconclusive = false;
if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive))
checkAutoVariableAssignment(tok->next(), inconclusive);
tok = tok->tokAt(5);
} else if (Token::Match(tok, "[;{}] %var% [") && Token::simpleMatch(tok->linkAt(2), "] =") &&
(isPtrArg(tok->next()) || isArrayArg(tok->next(), *mSettings)) &&
isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2())) {
isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2(), *mSettings)) {
errorAutoVariableAssignment(tok->next(), false);
}
// Invalid pointer deallocation
Expand Down
4 changes: 2 additions & 2 deletions lib/checkfunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,9 +646,9 @@ void CheckFunctions::checkLibraryMatchFunctions()

if (Token::simpleMatch(tok->astParent(), ".")) {
const Token* contTok = tok->astParent()->astOperand1();
if (astContainerAction(contTok, nullptr, mSettings) != Library::Container::Action::NO_ACTION)
if (astContainerAction(contTok, mSettings->library) != Library::Container::Action::NO_ACTION)
continue;
if (astContainerYield(contTok, nullptr, mSettings) != Library::Container::Yield::NO_YIELD)
if (astContainerYield(contTok, mSettings->library) != Library::Container::Yield::NO_YIELD)
continue;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/checkother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,7 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us
}
}
}
const auto yield = astContainerYield(tok);
const auto yield = astContainerYield(tok, mSettings->library);
if (yield == Library::Container::Yield::BUFFER || yield == Library::Container::Yield::BUFFER_NT)
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/checkstl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ static bool isSameIteratorContainerExpression(const Token* tok1,
if (isSameExpression(false, tok1, tok2, settings, false, false)) {
return !astIsContainerOwned(tok1) || !isTemporary(tok1, &settings.library);
}
if (astContainerYield(tok2) == Library::Container::Yield::ITEM)
if (astContainerYield(tok2, settings.library) == Library::Container::Yield::ITEM)
return true;
if (kind == ValueFlow::Value::LifetimeKind::Address || kind == ValueFlow::Value::LifetimeKind::Iterator) {
const auto address1 = getAddressContainer(tok1);
Expand Down
2 changes: 1 addition & 1 deletion lib/checkuninitvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1660,7 +1660,7 @@ void CheckUninitVar::valueFlowUninit()
if (isarray && tok->variable()->isMember())
continue; // Todo: this is a bailout
if (isarray && tok->variable()->isStlType() && Token::simpleMatch(tok->astParent(), ".")) {
const auto yield = astContainerYield(tok);
const auto yield = astContainerYield(tok, mSettings->library);
if (yield != Library::Container::Yield::AT_INDEX && yield != Library::Container::Yield::ITEM)
continue;
}
Expand Down
10 changes: 5 additions & 5 deletions lib/library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1576,10 +1576,10 @@ Library::UseRetValType Library::getUseRetValType(const Token *ftok) const
if (Token::simpleMatch(ftok->astParent(), ".")) {
const Token* contTok = ftok->astParent()->astOperand1();
using Yield = Library::Container::Yield;
const Yield yield = astContainerYield(contTok);
const Yield yield = astContainerYield(contTok, *this);
if (yield == Yield::START_ITERATOR || yield == Yield::END_ITERATOR || yield == Yield::AT_INDEX ||
yield == Yield::SIZE || yield == Yield::EMPTY || yield == Yield::BUFFER || yield == Yield::BUFFER_NT ||
((yield == Yield::ITEM || yield == Yield::ITERATOR) && astContainerAction(contTok) == Library::Container::Action::NO_ACTION))
((yield == Yield::ITEM || yield == Yield::ITERATOR) && astContainerAction(contTok, *this) == Library::Container::Action::NO_ACTION))
return Library::UseRetValType::DEFAULT;
}
return Library::UseRetValType::NONE;
Expand Down Expand Up @@ -1713,7 +1713,7 @@ bool Library::isFunctionConst(const Token *ftok) const
if (isNotLibraryFunction(ftok)) {
if (Token::simpleMatch(ftok->astParent(), ".")) {
using Yield = Library::Container::Yield;
const Yield yield = astContainerYield(ftok->astParent()->astOperand1());
const Yield yield = astContainerYield(ftok->astParent()->astOperand1(), *this);
if (yield == Yield::EMPTY || yield == Yield::SIZE || yield == Yield::BUFFER_NT)
return true;
}
Expand All @@ -1732,8 +1732,8 @@ bool Library::isnoreturn(const Token *ftok) const
if (isNotLibraryFunction(ftok)) {
if (Token::simpleMatch(ftok->astParent(), ".")) {
const Token* contTok = ftok->astParent()->astOperand1();
if (astContainerAction(contTok) != Library::Container::Action::NO_ACTION ||
astContainerYield(contTok) != Library::Container::Yield::NO_YIELD)
if (astContainerAction(contTok, *this) != Library::Container::Action::NO_ACTION ||
astContainerYield(contTok, *this) != Library::Container::Yield::NO_YIELD)
return false;
}
return false;
Expand Down
6 changes: 3 additions & 3 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6113,7 +6113,7 @@ bool ValueFlow::isContainerSizeChanged(const Token* tok, int indirect, const Set
return true;
if (astIsLHS(tok) && Token::simpleMatch(tok->astParent(), "["))
return tok->valueType()->container->stdAssociativeLike;
const Library::Container::Action action = astContainerAction(tok);
const Library::Container::Action action = astContainerAction(tok, settings.library);
switch (action) {
case Library::Container::Action::RESIZE:
case Library::Container::Action::CLEAR:
Expand All @@ -6127,7 +6127,7 @@ bool ValueFlow::isContainerSizeChanged(const Token* tok, int indirect, const Set
case Library::Container::Action::NO_ACTION:
// Is this an unknown member function call?
if (astIsLHS(tok) && Token::Match(tok->astParent(), ". %name% (")) {
const Library::Container::Yield yield = astContainerYield(tok);
const Library::Container::Yield yield = astContainerYield(tok, settings.library);
return yield == Library::Container::Yield::NO_YIELD;
}
break;
Expand Down Expand Up @@ -6233,7 +6233,7 @@ static void valueFlowSmartPointer(TokenList &tokenlist, ErrorLogger & errorLogge

static Library::Container::Yield findIteratorYield(Token* tok, const Token*& ftok, const Settings& settings)
{
auto yield = astContainerYield(tok, &ftok);
auto yield = astContainerYield(tok, settings.library, &ftok);
if (ftok)
return yield;

Expand Down
2 changes: 1 addition & 1 deletion lib/vf_analyzers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ struct ValueFlowAnalyzer : Analyzer {
Library::Container::Action::INSERT,
Library::Container::Action::APPEND,
Library::Container::Action::CHANGE_INTERNAL},
astContainerAction(tok)))
astContainerAction(tok, getSettings().library)))
return read;
}
bool inconclusive = false;
Expand Down
Loading