Skip to content
Draft
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
26 changes: 13 additions & 13 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2338,14 +2338,14 @@ bool isWithinScope(const Token* tok, const Variable* var, ScopeType type)
return false;
}

bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings &settings, bool *inconclusive)
bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Library &library, bool *inconclusive)
{
if (!tok)
return false;
if (tok->varId() == varid)
return isVariableChangedByFunctionCall(tok, indirect, settings, inconclusive);
return isVariableChangedByFunctionCall(tok->astOperand1(), indirect, varid, settings, inconclusive) ||
isVariableChangedByFunctionCall(tok->astOperand2(), indirect, varid, settings, inconclusive);
return isVariableChangedByFunctionCall(tok, indirect, library, inconclusive);
return isVariableChangedByFunctionCall(tok->astOperand1(), indirect, varid, library, inconclusive) ||
isVariableChangedByFunctionCall(tok->astOperand2(), indirect, varid, library, inconclusive);
}

bool isScopeBracket(const Token* tok)
Expand Down Expand Up @@ -2526,7 +2526,7 @@ bool isMutableExpression(const Token* tok)
return true;
}

bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings &settings, bool *inconclusive)
bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Library &library, bool *inconclusive)
{
if (!tok)
return false;
Expand Down Expand Up @@ -2566,13 +2566,13 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti

if (!tok->function() && !tok->variable() && tok->isName()) {
// Check if direction (in, out, inout) is specified in the library configuration and use that
const Library::ArgumentChecks::Direction argDirection = settings.library.getArgDirection(tok, 1 + argnr, indirect);
const Library::ArgumentChecks::Direction argDirection = library.getArgDirection(tok, 1 + argnr, indirect);
if (argDirection == Library::ArgumentChecks::Direction::DIR_IN)
return false;
if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT || argDirection == Library::ArgumentChecks::Direction::DIR_INOUT)
return true;

const bool requireNonNull = settings.library.isnullargbad(tok, 1 + argnr);
const bool requireNonNull = library.isnullargbad(tok, 1 + argnr);
if (Token::simpleMatch(tok->tokAt(-2), "std :: tie"))
return true;
// if the library says 0 is invalid
Expand Down Expand Up @@ -2798,7 +2798,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings &settings,
if (indirect == 0 && astIsLHS(tok2) && Token::Match(ptok, ". %var%") && astIsPointer(ptok->next()))
pindirect = 1;
bool inconclusive = false;
bool isChanged = isVariableChangedByFunctionCall(ptok, pindirect, settings, &inconclusive);
bool isChanged = isVariableChangedByFunctionCall(ptok, pindirect, settings.library, &inconclusive);
isChanged |= inconclusive;
if (isChanged)
return true;
Expand Down Expand Up @@ -3423,7 +3423,7 @@ bool isConstVarExpression(const Token *tok, const std::function<bool(const Token
return false;
}

static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings& settings)
static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Library& library)
{
const bool addressOf = tok->astParent() && tok->astParent()->isUnaryOp("&");

Expand Down Expand Up @@ -3485,14 +3485,14 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings
} else if (ftok->str() == "{") {
return indirect == 0 ? ExprUsage::Used : ExprUsage::Inconclusive;
} else {
const bool isnullbad = settings.library.isnullargbad(ftok, argnr + 1);
const bool isnullbad = library.isnullargbad(ftok, argnr + 1);
if (indirect == 0 && astIsPointer(tok) && !addressOf && isnullbad)
return ExprUsage::Used;
bool hasIndirect = false;
const bool isuninitbad = settings.library.isuninitargbad(ftok, argnr + 1, indirect, &hasIndirect);
const bool isuninitbad = library.isuninitargbad(ftok, argnr + 1, indirect, &hasIndirect);
if (isuninitbad && (!addressOf || isnullbad))
return ExprUsage::Used;
const Library::ArgumentChecks::Direction argDirection = settings.library.getArgDirection(ftok, argnr + 1, indirect);
const Library::ArgumentChecks::Direction argDirection = library.getArgDirection(ftok, argnr + 1, indirect);
if (argDirection == Library::ArgumentChecks::Direction::DIR_IN) // TODO: DIR_INOUT?
return ExprUsage::Used;
if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT)
Expand Down Expand Up @@ -3562,7 +3562,7 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings& settings)
(astIsLHS(tok) || Token::simpleMatch(parent, "( )")))
return ExprUsage::Used;
}
return getFunctionUsage(tok, indirect, settings);
return getFunctionUsage(tok, indirect, settings.library);
}

static void getLHSVariablesRecursive(std::vector<const Variable*>& vars, const Token* tok)
Expand Down
10 changes: 5 additions & 5 deletions lib/astutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,20 +327,20 @@ bool isMutableExpression(const Token* tok);
*
* @param tok ast tree
* @param varid Variable Id
* @param settings program settings
* @param library library configurations
* @param inconclusive pointer to output variable which indicates that the answer of the question is inconclusive
*/
bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings &settings, bool *inconclusive);
bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Library &library, bool *inconclusive);

/** Is variable changed by function call?
* In case the answer of the question is inconclusive, e.g. because the function declaration is not known
* the return value is false and the output parameter inconclusive is set to true
*
* @param tok token of variable in function call
* @param settings program settings
* @param tok token of variable in function call
* @param library library configurations
* @param inconclusive pointer to output variable which indicates that the answer of the question is inconclusive
*/
CPPCHECKLIB bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings &settings, bool *inconclusive);
CPPCHECKLIB bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Library &library, bool *inconclusive);

/** Is variable changed in block of code? */
CPPCHECKLIB bool isVariableChanged(const Token *start, const Token *end, nonneg int exprid, bool globalvar, const Settings &settings, int depth = 20);
Expand Down
22 changes: 11 additions & 11 deletions lib/checkautovariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,14 @@ static bool isAutoVarArray(const Token *tok)
return false;
}

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

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

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

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

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

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

static bool hasOverloadedAssignment(const Token* tok, bool& inconclusive)
Expand All @@ -257,7 +257,7 @@ static bool hasOverloadedAssignment(const Token* tok, bool& inconclusive)
return true;
}

static bool isMemberAssignment(const Token* tok, const Token*& rhs, const Settings& settings)
static bool isMemberAssignment(const Token* tok, const Token*& rhs, const Library& library)
{
const Token *endBracket = nullptr;
if (!Token::Match(tok, "[;{}] %var% . %var%")) {
Expand All @@ -274,7 +274,7 @@ static bool isMemberAssignment(const Token* tok, const Token*& rhs, const Settin
assign = assign->astParent();
if (!Token::simpleMatch(assign, "="))
return false;
if (!isAutoVariableRHS(assign->astOperand2(), settings))
if (!isAutoVariableRHS(assign->astOperand2(), library))
return false;
rhs = assign->astOperand2();
return true;
Expand All @@ -295,23 +295,23 @@ void CheckAutoVariablesImpl::autoVariables()
}
// Critical assignment
const Token* rhs{};
if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2(), mSettings)) {
if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2(), mSettings.library)) {
checkAutoVariableAssignment(tok->next(), false);
} else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2(), mSettings)) {
} else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2(), mSettings.library)) {
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 (isMemberAssignment(tok, rhs, mSettings)) {
} else if (isMemberAssignment(tok, rhs, mSettings.library)) {
const Token* lhs = tok->tokAt(3);
bool inconclusive = false;
if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive))
checkAutoVariableAssignment(tok->next(), inconclusive);
tok = rhs;
} else if (Token::Match(tok, "[;{}] %var% [") && Token::simpleMatch(tok->linkAt(2), "] =") &&
(isPtrArg(tok->next()) || isArrayArg(tok->next(), mSettings)) &&
isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2(), mSettings)) {
isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2(), mSettings.library)) {
errorAutoVariableAssignment(tok->next(), false);
}
// Invalid pointer deallocation
Expand Down
2 changes: 1 addition & 1 deletion lib/checkbufferoverrun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static int getMinFormatStringOutputLength(const std::vector<const Token*> &param
case 's':
parameterLength = 0;
if (inputArgNr < parameters.size())
parameterLength = ValueFlow::valueFlowGetStrLength(parameters[inputArgNr], settings);
parameterLength = ValueFlow::valueFlowGetStrLength(parameters[inputArgNr], settings.library);

handleNextParameter = true;
break;
Expand Down
2 changes: 1 addition & 1 deletion lib/checkclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ void CheckClassImpl::initializeVarList(const Function &func, std::list<const Fun
tok2 = tok2->next();
if (tok2->str() == "&")
tok2 = tok2->next();
if (isVariableChangedByFunctionCall(tok2, tok2->strAt(-1) == "&", tok2->varId(), mSettings, nullptr))
if (isVariableChangedByFunctionCall(tok2, tok2->strAt(-1) == "&", tok2->varId(), mSettings.library, nullptr))
assignVar(usage, tok2->varId());
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/checkio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ void CheckIOImpl::checkFormatString(const Token * const tok,
// Perform type checks
ArgumentInfo argInfo(argListTok, mSettings, mTokenizer->isCPP());

if ((argInfo.typeToken && !argInfo.isLibraryType(mSettings)) || *i == ']') {
if ((argInfo.typeToken && !argInfo.isLibraryType(mSettings.library)) || *i == ']') {
if (scan) {
std::string specifier;
bool done = false;
Expand Down Expand Up @@ -1857,9 +1857,9 @@ bool CheckIOImpl::ArgumentInfo::isKnownType() const
return typeToken->isStandardType() || Token::Match(typeToken, "std :: string|wstring");
}

bool CheckIOImpl::ArgumentInfo::isLibraryType(const Settings &settings) const
bool CheckIOImpl::ArgumentInfo::isLibraryType(const Library &library) const
{
return typeToken && typeToken->isStandardType() && settings.library.podtype(typeToken->str());
return typeToken && typeToken->isStandardType() && library.podtype(typeToken->str());
}

void CheckIOImpl::wrongPrintfScanfArgumentsError(const Token* tok,
Expand Down
3 changes: 2 additions & 1 deletion lib/checkio.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Token;
class Variable;
class ErrorLogger;
class Tokenizer;
class Library;
enum class Severity : std::uint8_t;

/// @addtogroup Checks
Expand Down Expand Up @@ -101,7 +102,7 @@ class CPPCHECKLIB CheckIOImpl : public CheckImpl {
bool isKnownType() const;
bool isStdVectorOrString();
bool isStdContainer(const Token *tok);
bool isLibraryType(const Settings &settings) const;
bool isLibraryType(const Library &library) const;

const Variable* variableInfo{};
const Token* typeToken{};
Expand Down
14 changes: 7 additions & 7 deletions lib/checkleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,24 +267,24 @@ static const Token * isFunctionCall(const Token * nameToken)
return nullptr;
}

static const Token* getOutparamAllocation(const Token* tok, const Settings& settings)
static const Token* getOutparamAllocation(const Token* tok, const Library& library)
{
if (!tok)
return nullptr;
int argn{};
const Token* ftok = getTokenArgumentFunction(tok, argn);
if (!ftok)
return nullptr;
if (const Library::AllocFunc* allocFunc = settings.library.getAllocFuncInfo(ftok)) {
if (const Library::AllocFunc* allocFunc = library.getAllocFuncInfo(ftok)) {
if (allocFunc->arg == argn + 1)
return ftok;
}
return nullptr;
}

static const Token* getReturnValueFromOutparamAlloc(const Token* alloc, const Settings& settings)
static const Token* getReturnValueFromOutparamAlloc(const Token* alloc, const Library& library)
{
if (const Token* ftok = getOutparamAllocation(alloc, settings)) {
if (const Token* ftok = getOutparamAllocation(alloc, library)) {
if (Token::simpleMatch(ftok->astParent()->astParent(), "="))
return ftok->next()->astParent()->astOperand1();
}
Expand Down Expand Up @@ -623,7 +623,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken,
if (std::any_of(varInfo1.alloctype.begin(), varInfo1.alloctype.end(), [&](const std::pair<int, VarInfo::AllocInfo>& info) {
if (info.second.status != VarInfo::ALLOC)
return false;
const Token* ret = getReturnValueFromOutparamAlloc(info.second.allocTok, mSettings);
const Token* ret = getReturnValueFromOutparamAlloc(info.second.allocTok, mSettings.library);
return ret && vartok && ret->varId() && ret->varId() == vartok->varId();
})) {
varInfo1.clear();
Expand Down Expand Up @@ -896,7 +896,7 @@ const Token * CheckLeakAutoVarImpl::checkTokenInsideExpression(const Token * con
if (var != varInfo.alloctype.end()) {
bool unknown = false;
if (var->second.status == VarInfo::DEALLOC && tok->valueType() && tok->valueType()->pointer &&
CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings, /*checkNullArg*/ false) && !unknown) {
CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings.library, /*checkNullArg*/ false) && !unknown) {
deallocUseError(tok, tok->str());
} else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
varInfo.erase(tok->varId());
Expand Down Expand Up @@ -1232,7 +1232,7 @@ void CheckLeakAutoVarImpl::ret(const Token *tok, VarInfo &varInfo, const bool is
// don't warn when returning after checking return value of outparam allocation
const Token* outparamFunc{};
if ((tok->scope()->type == ScopeType::eIf || tok->scope()->type== ScopeType::eElse) &&
(outparamFunc = getOutparamAllocation(it->second.allocTok, mSettings))) {
(outparamFunc = getOutparamAllocation(it->second.allocTok, mSettings.library))) {
const Scope* scope = tok->scope();
if (scope->type == ScopeType::eElse) {
scope = scope->bodyStart->tokAt(-2)->scope();
Expand Down
12 changes: 6 additions & 6 deletions lib/checknullpointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ namespace {

bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown) const
{
return isPointerDeRef(tok, unknown, mSettings);
return isPointerDeRef(tok, unknown, mSettings.library);
}

bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings, bool checkNullArg)
bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const Library &library, bool checkNullArg)
{
unknown = false;

Expand All @@ -146,7 +146,7 @@ bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const
ftok = ftok->previous();
}
if (ftok && ftok->previous()) {
const std::list<const Token *> varlist = CheckNullPointerImpl::parseFunctionCall(*ftok->previous(), settings.library, checkNullArg);
const std::list<const Token *> varlist = CheckNullPointerImpl::parseFunctionCall(*ftok->previous(), library, checkNullArg);
if (std::find(varlist.cbegin(), varlist.cend(), tok) != varlist.cend()) {
return true;
}
Expand All @@ -161,7 +161,7 @@ bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const
return false;
const bool addressOf = parent->astParent() && parent->astParent()->str() == "&";
if (parent->str() == "." && astIsRHS(tok))
return isPointerDeRef(parent, unknown, settings);
return isPointerDeRef(parent, unknown, library);
const bool firstOperand = parent->astOperand1() == tok;
parent = astParentSkipParens(tok);
if (!parent)
Expand Down Expand Up @@ -298,7 +298,7 @@ void CheckNullPointerImpl::nullPointerByDeRefAndCheck()

// Pointer dereference.
bool unknown = false;
if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings)) {
if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings.library)) {
if (unknown)
nullPointerError(tok, tok->expressionString(), value, true);
continue;
Expand Down Expand Up @@ -578,7 +578,7 @@ static bool isUnsafeUsage(const Settings &settings, const Token *vartok, CTU::Fi
{
(void)value;
bool unknown = false;
return CheckNullPointerImpl::isPointerDeRef(vartok, unknown, settings);
return CheckNullPointerImpl::isPointerDeRef(vartok, unknown, settings.library);
}

// a Clang-built executable will crash when using the anonymous MyFileInfo later on - so put it in a unique namespace for now
Expand Down
Loading