ValueFlow: some interface and namespace cleanups (#4746)
This commit is contained in:
parent
464fbe8d53
commit
afd13ea11d
|
@ -879,7 +879,7 @@ bool extractForLoopValues(const Token *forToken,
|
|||
const Token *incExpr = forToken->next()->astOperand2()->astOperand2()->astOperand2();
|
||||
if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%"))
|
||||
return false;
|
||||
std::vector<MathLib::bigint> minInitValue = getMinValue(makeIntegralInferModel(), initExpr->astOperand2()->values());
|
||||
std::vector<MathLib::bigint> minInitValue = getMinValue(ValueFlow::makeIntegralInferModel(), initExpr->astOperand2()->values());
|
||||
*varid = initExpr->astOperand1()->varId();
|
||||
*knownInitValue = initExpr->astOperand2()->hasKnownIntValue();
|
||||
*initValue = minInitValue.empty() ? 0 : minInitValue.front();
|
||||
|
@ -1289,10 +1289,10 @@ const Token* followReferences(const Token* tok, ErrorPath* errors)
|
|||
|
||||
static bool isSameLifetime(const Token * const tok1, const Token * const tok2)
|
||||
{
|
||||
ValueFlow::Value v1 = getLifetimeObjValue(tok1);
|
||||
ValueFlow::Value v1 = ValueFlow::getLifetimeObjValue(tok1);
|
||||
if (!v1.isLifetimeValue())
|
||||
return false;
|
||||
ValueFlow::Value v2 = getLifetimeObjValue(tok2);
|
||||
ValueFlow::Value v2 = ValueFlow::getLifetimeObjValue(tok2);
|
||||
if (!v2.isLifetimeValue())
|
||||
return false;
|
||||
return v1.tokvalue == v2.tokvalue;
|
||||
|
|
|
@ -518,7 +518,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
|
|||
for (const Token *tok = start; tok && tok != end; tok = tok->next()) {
|
||||
// Return reference from function
|
||||
if (returnRef && Token::simpleMatch(tok->astParent(), "return")) {
|
||||
for (const LifetimeToken& lt : getLifetimeTokens(tok, true)) {
|
||||
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok, true)) {
|
||||
if (!printInconclusive && lt.inconclusive)
|
||||
continue;
|
||||
const Variable* var = lt.token->variable();
|
||||
|
@ -537,14 +537,14 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
|
|||
tok->variable()->declarationId() == tok->varId() && tok->variable()->isStatic() &&
|
||||
!tok->variable()->isArgument()) {
|
||||
ErrorPath errorPath;
|
||||
const Variable *var = getLifetimeVariable(tok, errorPath);
|
||||
const Variable *var = ValueFlow::getLifetimeVariable(tok, errorPath);
|
||||
if (var && isInScope(var->nameToken(), tok->scope())) {
|
||||
errorDanglingReference(tok, var, errorPath);
|
||||
continue;
|
||||
}
|
||||
// Reference to temporary
|
||||
} else if (tok->variable() && (tok->variable()->isReference() || tok->variable()->isRValueReference())) {
|
||||
for (const LifetimeToken& lt : getLifetimeTokens(getParentLifetime(tok))) {
|
||||
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(getParentLifetime(tok))) {
|
||||
if (!printInconclusive && lt.inconclusive)
|
||||
continue;
|
||||
const Token * tokvalue = lt.token;
|
||||
|
@ -565,13 +565,13 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
|
|||
const Token* parent = getParentLifetime(mTokenizer->isCPP(), val.tokvalue, &mSettings->library);
|
||||
if (!exprs.insert(parent).second)
|
||||
continue;
|
||||
for (const LifetimeToken& lt : getLifetimeTokens(parent, escape || isAssignedToNonLocal(tok))) {
|
||||
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(parent, escape || isAssignedToNonLocal(tok))) {
|
||||
const Token * tokvalue = lt.token;
|
||||
if (val.isLocalLifetimeValue()) {
|
||||
if (escape) {
|
||||
if (getPointerDepth(tok) < getPointerDepth(tokvalue))
|
||||
continue;
|
||||
if (!isLifetimeBorrowed(tok, mSettings))
|
||||
if (!ValueFlow::isLifetimeBorrowed(tok, mSettings))
|
||||
continue;
|
||||
if (tokvalue->exprId() == tok->exprId() && !(tok->variable() && tok->variable()->isArray()) &&
|
||||
!astIsContainerView(tok->astParent()))
|
||||
|
@ -604,7 +604,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
|
|||
} else if (tok->variable() && tok->variable()->declarationId() == tok->varId()) {
|
||||
var = tok->variable();
|
||||
}
|
||||
if (!isLifetimeBorrowed(tok, mSettings))
|
||||
if (!ValueFlow::isLifetimeBorrowed(tok, mSettings))
|
||||
continue;
|
||||
const Token* nextTok = nextAfterAstRightmostLeaf(tok->astTop());
|
||||
if (!nextTok)
|
||||
|
|
|
@ -1030,7 +1030,7 @@ void CheckBufferOverrun::objectIndex()
|
|||
if (idx->hasKnownIntValue() && idx->getKnownIntValue() == 0)
|
||||
continue;
|
||||
|
||||
std::vector<ValueFlow::Value> values = getLifetimeObjValues(obj, false, -1);
|
||||
std::vector<ValueFlow::Value> values = ValueFlow::getLifetimeObjValues(obj, false, -1);
|
||||
for (const ValueFlow::Value& v:values) {
|
||||
if (v.lifetimeKind != ValueFlow::Value::LifetimeKind::Address)
|
||||
continue;
|
||||
|
|
|
@ -1446,7 +1446,7 @@ void CheckOther::checkConstVariable()
|
|||
retTok = retTok->astOperand2();
|
||||
while (Token::simpleMatch(retTok, "."))
|
||||
retTok = retTok->astOperand2();
|
||||
return hasLifetimeToken(getParentLifetime(retTok), var->nameToken());
|
||||
return ValueFlow::hasLifetimeToken(getParentLifetime(retTok), var->nameToken());
|
||||
}))
|
||||
continue;
|
||||
}
|
||||
|
@ -3671,8 +3671,8 @@ void CheckOther::checkComparePointers()
|
|||
const Token *tok2 = tok->astOperand2();
|
||||
if (!astIsPointer(tok1) || !astIsPointer(tok2))
|
||||
continue;
|
||||
ValueFlow::Value v1 = getLifetimeObjValue(tok1);
|
||||
ValueFlow::Value v2 = getLifetimeObjValue(tok2);
|
||||
ValueFlow::Value v1 = ValueFlow::getLifetimeObjValue(tok1);
|
||||
ValueFlow::Value v2 = ValueFlow::getLifetimeObjValue(tok2);
|
||||
if (!v1.isLocalLifetimeValue() || !v2.isLocalLifetimeValue())
|
||||
continue;
|
||||
const Variable *var1 = v1.tokvalue->variable();
|
||||
|
|
|
@ -727,7 +727,7 @@ static bool isSameIteratorContainerExpression(const Token* tok1,
|
|||
|
||||
static ValueFlow::Value getLifetimeIteratorValue(const Token* tok, MathLib::bigint path = 0)
|
||||
{
|
||||
std::vector<ValueFlow::Value> values = getLifetimeObjValues(tok, false, path);
|
||||
std::vector<ValueFlow::Value> values = ValueFlow::getLifetimeObjValues(tok, false, path);
|
||||
auto it = std::find_if(values.cbegin(), values.cend(), [](const ValueFlow::Value& v) {
|
||||
return v.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator;
|
||||
});
|
||||
|
@ -1155,7 +1155,7 @@ void CheckStl::invalidContainer()
|
|||
|
||||
ErrorPath ep;
|
||||
bool addressOf = false;
|
||||
const Variable* var = getLifetimeVariable(info.tok, ep, &addressOf);
|
||||
const Variable* var = ValueFlow::getLifetimeVariable(info.tok, ep, &addressOf);
|
||||
// Check the reference is created before the change
|
||||
if (var && var->declarationId() == r.tok->varId() && !addressOf) {
|
||||
// An argument always reaches
|
||||
|
|
|
@ -1287,7 +1287,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
|
|||
continue;
|
||||
|
||||
FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library);
|
||||
const Token* scopeEnd = getEndOfExprScope(expr, scope, /*smallest*/ false);
|
||||
const Token* scopeEnd = ValueFlow::getEndOfExprScope(expr, scope, /*smallest*/ false);
|
||||
if (fwdAnalysis.unusedValue(expr, start, scopeEnd)) {
|
||||
if (!bailoutTypeName.empty()) {
|
||||
if (bailoutTypeName != "auto")
|
||||
|
|
|
@ -1274,13 +1274,13 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
if (expr->isComparisonOp()) {
|
||||
if (rhs.isIntValue()) {
|
||||
std::vector<ValueFlow::Value> result =
|
||||
infer(makeIntegralInferModel(), expr->str(), expr->astOperand1()->values(), {rhs});
|
||||
infer(ValueFlow::makeIntegralInferModel(), expr->str(), expr->astOperand1()->values(), {rhs});
|
||||
if (result.empty() || !result.front().isKnown())
|
||||
return unknown;
|
||||
return result.front();
|
||||
} else if (lhs.isIntValue()) {
|
||||
std::vector<ValueFlow::Value> result =
|
||||
infer(makeIntegralInferModel(), expr->str(), {lhs}, expr->astOperand2()->values());
|
||||
infer(ValueFlow::makeIntegralInferModel(), expr->str(), {lhs}, expr->astOperand2()->values());
|
||||
if (result.empty() || !result.front().isKnown())
|
||||
return unknown;
|
||||
return result.front();
|
||||
|
@ -1353,7 +1353,7 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
if (child->exprId() > 0 && pm.hasValue(child->exprId())) {
|
||||
ValueFlow::Value& v = pm.at(child->exprId());
|
||||
if (v.valueType == ValueFlow::Value::ValueType::CONTAINER_SIZE) {
|
||||
if (isContainerSizeChanged(child, v.indirect, settings))
|
||||
if (ValueFlow::isContainerSizeChanged(child, v.indirect, settings))
|
||||
v = unknown;
|
||||
} else if (v.valueType != ValueFlow::Value::ValueType::UNINIT) {
|
||||
if (isVariableChanged(child, v.indirect, settings, true))
|
||||
|
|
|
@ -343,10 +343,10 @@ static void parseCompareEachInt(
|
|||
});
|
||||
}
|
||||
|
||||
const Token* parseCompareInt(const Token* tok,
|
||||
ValueFlow::Value& true_value,
|
||||
ValueFlow::Value& false_value,
|
||||
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate)
|
||||
const Token* ValueFlow::parseCompareInt(const Token* tok,
|
||||
ValueFlow::Value& true_value,
|
||||
ValueFlow::Value& false_value,
|
||||
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate)
|
||||
{
|
||||
const Token* result = nullptr;
|
||||
parseCompareEachInt(
|
||||
|
@ -370,7 +370,7 @@ const Token* parseCompareInt(const Token* tok,
|
|||
return result;
|
||||
}
|
||||
|
||||
const Token *parseCompareInt(const Token *tok, ValueFlow::Value &true_value, ValueFlow::Value &false_value)
|
||||
const Token *ValueFlow::parseCompareInt(const Token *tok, ValueFlow::Value &true_value, ValueFlow::Value &false_value)
|
||||
{
|
||||
return parseCompareInt(tok, true_value, false_value, [](const Token* t) -> std::vector<MathLib::bigint> {
|
||||
if (t->hasKnownIntValue())
|
||||
|
@ -417,7 +417,7 @@ static bool isNumeric(const ValueFlow::Value& value) {
|
|||
return value.isIntValue() || value.isFloatValue();
|
||||
}
|
||||
|
||||
void combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value *result)
|
||||
void ValueFlow::combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value *result)
|
||||
{
|
||||
if (value1.isKnown() && value2.isKnown())
|
||||
result->setKnown();
|
||||
|
@ -688,7 +688,7 @@ static void setTokenValue(Token* tok,
|
|||
}
|
||||
|
||||
if (value.isLifetimeValue()) {
|
||||
if (!isLifetimeBorrowed(parent, settings))
|
||||
if (!ValueFlow::isLifetimeBorrowed(parent, settings))
|
||||
return;
|
||||
if (value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator && astIsIterator(parent)) {
|
||||
setTokenValue(parent,value,settings);
|
||||
|
@ -1288,7 +1288,6 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
|
|||
return tok->next();
|
||||
}
|
||||
|
||||
|
||||
static void valueFlowNumber(TokenList *tokenlist)
|
||||
{
|
||||
for (Token *tok = tokenlist->front(); tok;) {
|
||||
|
@ -1973,8 +1972,8 @@ static void valueFlowGlobalStaticVar(TokenList *tokenList, const Settings *setti
|
|||
}
|
||||
}
|
||||
|
||||
ValuePtr<Analyzer> makeAnalyzer(const Token* exprTok, ValueFlow::Value value, const TokenList* tokenlist);
|
||||
ValuePtr<Analyzer> makeReverseAnalyzer(const Token* exprTok, const ValueFlow::Value& value, const TokenList* tokenlist);
|
||||
static ValuePtr<Analyzer> makeAnalyzer(const Token* exprTok, ValueFlow::Value value, const TokenList* tokenlist);
|
||||
static ValuePtr<Analyzer> makeReverseAnalyzer(const Token* exprTok, const ValueFlow::Value& value, const TokenList* tokenlist);
|
||||
|
||||
static Analyzer::Result valueFlowForward(Token* startToken,
|
||||
const Token* endToken,
|
||||
|
@ -3229,7 +3228,7 @@ struct MemberExpressionAnalyzer : SubExpressionAnalyzer {
|
|||
|
||||
enum class LifetimeCapture { Undefined, ByValue, ByReference };
|
||||
|
||||
std::string lifetimeType(const Token *tok, const ValueFlow::Value *val)
|
||||
static std::string lifetimeType(const Token *tok, const ValueFlow::Value *val)
|
||||
{
|
||||
std::string result;
|
||||
if (!val)
|
||||
|
@ -3253,7 +3252,7 @@ std::string lifetimeType(const Token *tok, const ValueFlow::Value *val)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string lifetimeMessage(const Token *tok, const ValueFlow::Value *val, ErrorPath &errorPath)
|
||||
std::string ValueFlow::lifetimeMessage(const Token *tok, const ValueFlow::Value *val, ErrorPath &errorPath)
|
||||
{
|
||||
const Token *tokvalue = val ? val->tokvalue : nullptr;
|
||||
const Variable *tokvar = tokvalue ? tokvalue->variable() : nullptr;
|
||||
|
@ -3291,7 +3290,7 @@ std::string lifetimeMessage(const Token *tok, const ValueFlow::Value *val, Error
|
|||
return msg;
|
||||
}
|
||||
|
||||
std::vector<ValueFlow::Value> getLifetimeObjValues(const Token* tok, bool inconclusive, MathLib::bigint path)
|
||||
std::vector<ValueFlow::Value> ValueFlow::getLifetimeObjValues(const Token* tok, bool inconclusive, MathLib::bigint path)
|
||||
{
|
||||
std::vector<ValueFlow::Value> result;
|
||||
auto pred = [&](const ValueFlow::Value& v) {
|
||||
|
@ -3338,9 +3337,9 @@ static bool derefShared(const Token* tok)
|
|||
return !hasUniqueOwnership(ptrTok);
|
||||
}
|
||||
|
||||
ValueFlow::Value getLifetimeObjValue(const Token *tok, bool inconclusive)
|
||||
ValueFlow::Value ValueFlow::getLifetimeObjValue(const Token *tok, bool inconclusive)
|
||||
{
|
||||
std::vector<ValueFlow::Value> values = getLifetimeObjValues(tok, inconclusive);
|
||||
std::vector<ValueFlow::Value> values = ValueFlow::getLifetimeObjValues(tok, inconclusive);
|
||||
// There should only be one lifetime
|
||||
if (values.size() != 1)
|
||||
return ValueFlow::Value{};
|
||||
|
@ -3348,16 +3347,16 @@ ValueFlow::Value getLifetimeObjValue(const Token *tok, bool inconclusive)
|
|||
}
|
||||
|
||||
template<class Predicate>
|
||||
static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
||||
bool escape,
|
||||
ValueFlow::Value::ErrorPath errorPath,
|
||||
Predicate pred,
|
||||
int depth = 20)
|
||||
static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
|
||||
bool escape,
|
||||
ValueFlow::Value::ErrorPath errorPath,
|
||||
Predicate pred,
|
||||
int depth = 20)
|
||||
{
|
||||
if (!tok)
|
||||
return std::vector<LifetimeToken> {};
|
||||
return std::vector<ValueFlow::LifetimeToken> {};
|
||||
if (Token::simpleMatch(tok, "..."))
|
||||
return std::vector<LifetimeToken>{};
|
||||
return std::vector<ValueFlow::LifetimeToken>{};
|
||||
const Variable *var = tok->variable();
|
||||
if (pred(tok))
|
||||
return {{tok, std::move(errorPath)}};
|
||||
|
@ -3392,9 +3391,9 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
if (astIsContainer(contok))
|
||||
return getLifetimeTokens(contok, escape, std::move(errorPath), pred, depth - 1);
|
||||
else
|
||||
return std::vector<LifetimeToken>{};
|
||||
return std::vector<ValueFlow::LifetimeToken>{};
|
||||
} else {
|
||||
return std::vector<LifetimeToken> {};
|
||||
return std::vector<ValueFlow::LifetimeToken> {};
|
||||
}
|
||||
}
|
||||
} else if (Token::Match(tok->previous(), "%name% (")) {
|
||||
|
@ -3402,12 +3401,12 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
if (f) {
|
||||
if (!Function::returnsReference(f))
|
||||
return {{tok, std::move(errorPath)}};
|
||||
std::vector<LifetimeToken> result;
|
||||
std::vector<ValueFlow::LifetimeToken> result;
|
||||
std::vector<const Token*> returns = Function::findReturns(f);
|
||||
for (const Token* returnTok : returns) {
|
||||
if (returnTok == tok)
|
||||
continue;
|
||||
for (LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, pred, depth - returns.size())) {
|
||||
for (ValueFlow::LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, pred, depth - returns.size())) {
|
||||
const Token* argvarTok = lt.token;
|
||||
const Variable* argvar = argvarTok->variable();
|
||||
if (!argvar)
|
||||
|
@ -3416,11 +3415,11 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
if (argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) {
|
||||
const int n = getArgumentPos(argvar, f);
|
||||
if (n < 0)
|
||||
return std::vector<LifetimeToken> {};
|
||||
return std::vector<ValueFlow::LifetimeToken> {};
|
||||
std::vector<const Token*> args = getArguments(tok->previous());
|
||||
// TODO: Track lifetimes of default parameters
|
||||
if (n >= args.size())
|
||||
return std::vector<LifetimeToken> {};
|
||||
return std::vector<ValueFlow::LifetimeToken> {};
|
||||
argTok = args[n];
|
||||
lt.errorPath.emplace_back(returnTok, "Return reference.");
|
||||
lt.errorPath.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
|
||||
|
@ -3432,7 +3431,7 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
"Calling member function on '" + argTok->expressionString() + "'.");
|
||||
}
|
||||
if (argTok) {
|
||||
std::vector<LifetimeToken> arglts = LifetimeToken::setInconclusive(
|
||||
std::vector<ValueFlow::LifetimeToken> arglts = ValueFlow::LifetimeToken::setInconclusive(
|
||||
getLifetimeTokens(argTok, escape, std::move(lt.errorPath), pred, depth - returns.size()),
|
||||
returns.size() > 1);
|
||||
result.insert(result.end(), arglts.cbegin(), arglts.cend());
|
||||
|
@ -3445,7 +3444,7 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
const Library::Container::Yield y = library->getYield(tok->previous()->str());
|
||||
if (y == Library::Container::Yield::AT_INDEX || y == Library::Container::Yield::ITEM) {
|
||||
errorPath.emplace_back(tok->previous(), "Accessing container.");
|
||||
return LifetimeToken::setAddressOf(
|
||||
return ValueFlow::LifetimeToken::setAddressOf(
|
||||
getLifetimeTokens(tok->tokAt(-2)->astOperand1(), escape, std::move(errorPath), pred, depth - 1),
|
||||
false);
|
||||
}
|
||||
|
@ -3474,8 +3473,8 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
return getLifetimeTokens(v.tokvalue, escape, std::move(errorPath), pred, depth - 1);
|
||||
}
|
||||
} else {
|
||||
return LifetimeToken::setAddressOf(getLifetimeTokens(vartok, escape, std::move(errorPath), pred, depth - 1),
|
||||
!(astIsContainer(vartok) && Token::simpleMatch(vartok->astParent(), "[")));
|
||||
return ValueFlow::LifetimeToken::setAddressOf(getLifetimeTokens(vartok, escape, std::move(errorPath), pred, depth - 1),
|
||||
!(astIsContainer(vartok) && Token::simpleMatch(vartok->astParent(), "[")));
|
||||
}
|
||||
} else if (Token::simpleMatch(tok, "{") && getArgumentStart(tok) &&
|
||||
!Token::simpleMatch(getArgumentStart(tok), ",") && getArgumentStart(tok)->valueType()) {
|
||||
|
@ -3490,14 +3489,14 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
return {{tok, std::move(errorPath)}};
|
||||
}
|
||||
|
||||
std::vector<LifetimeToken> getLifetimeTokens(const Token* tok, bool escape, ValueFlow::Value::ErrorPath errorPath)
|
||||
std::vector<ValueFlow::LifetimeToken> ValueFlow::getLifetimeTokens(const Token* tok, bool escape, ValueFlow::Value::ErrorPath errorPath)
|
||||
{
|
||||
return getLifetimeTokens(tok, escape, std::move(errorPath), [](const Token*) {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
bool hasLifetimeToken(const Token* tok, const Token* lifetime)
|
||||
bool ValueFlow::hasLifetimeToken(const Token* tok, const Token* lifetime)
|
||||
{
|
||||
bool result = false;
|
||||
getLifetimeTokens(tok, false, ValueFlow::Value::ErrorPath{}, [&](const Token* tok2) {
|
||||
|
@ -3509,7 +3508,7 @@ bool hasLifetimeToken(const Token* tok, const Token* lifetime)
|
|||
|
||||
static const Token* getLifetimeToken(const Token* tok, ValueFlow::Value::ErrorPath& errorPath, bool* addressOf = nullptr)
|
||||
{
|
||||
std::vector<LifetimeToken> lts = getLifetimeTokens(tok);
|
||||
std::vector<ValueFlow::LifetimeToken> lts = ValueFlow::getLifetimeTokens(tok);
|
||||
if (lts.size() != 1)
|
||||
return nullptr;
|
||||
if (lts.front().inconclusive)
|
||||
|
@ -3520,7 +3519,7 @@ static const Token* getLifetimeToken(const Token* tok, ValueFlow::Value::ErrorPa
|
|||
return lts.front().token;
|
||||
}
|
||||
|
||||
const Variable* getLifetimeVariable(const Token* tok, ValueFlow::Value::ErrorPath& errorPath, bool* addressOf)
|
||||
const Variable* ValueFlow::getLifetimeVariable(const Token* tok, ValueFlow::Value::ErrorPath& errorPath, bool* addressOf)
|
||||
{
|
||||
const Token* tok2 = getLifetimeToken(tok, errorPath, addressOf);
|
||||
if (tok2 && tok2->variable())
|
||||
|
@ -3528,7 +3527,7 @@ const Variable* getLifetimeVariable(const Token* tok, ValueFlow::Value::ErrorPat
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const Variable* getLifetimeVariable(const Token* tok)
|
||||
const Variable* ValueFlow::getLifetimeVariable(const Token* tok)
|
||||
{
|
||||
ValueFlow::Value::ErrorPath errorPath;
|
||||
return getLifetimeVariable(tok, errorPath, nullptr);
|
||||
|
@ -3662,7 +3661,7 @@ static bool isDifferentType(const Token* src, const Token* dst)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool isLifetimeBorrowed(const Token *tok, const Settings *settings)
|
||||
bool ValueFlow::isLifetimeBorrowed(const Token *tok, const Settings *settings)
|
||||
{
|
||||
if (!tok)
|
||||
return true;
|
||||
|
@ -3729,7 +3728,7 @@ static const Token* getEndOfVarScope(const Variable* var)
|
|||
return innerScope->bodyEnd;
|
||||
}
|
||||
|
||||
const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope, bool smallest)
|
||||
const Token* ValueFlow::getEndOfExprScope(const Token* tok, const Scope* defaultScope, bool smallest)
|
||||
{
|
||||
const Token* end = nullptr;
|
||||
bool local = false;
|
||||
|
@ -3767,7 +3766,7 @@ static void valueFlowForwardLifetime(Token * tok, TokenList *tokenlist, ErrorLog
|
|||
if (Token::Match(tok->previous(), "%var% {|(") && isVariableDecl(tok->previous())) {
|
||||
std::list<ValueFlow::Value> values = tok->values();
|
||||
values.remove_if(&isNotLifetimeValue);
|
||||
valueFlowForward(nextAfterAstRightmostLeaf(tok), getEndOfExprScope(tok), tok->previous(), values, tokenlist);
|
||||
valueFlowForward(nextAfterAstRightmostLeaf(tok), ValueFlow::getEndOfExprScope(tok), tok->previous(), values, tokenlist);
|
||||
return;
|
||||
}
|
||||
Token *parent = tok->astParent();
|
||||
|
@ -3781,7 +3780,7 @@ static void valueFlowForwardLifetime(Token * tok, TokenList *tokenlist, ErrorLog
|
|||
if (!parent->astOperand2() || parent->astOperand2()->values().empty())
|
||||
return;
|
||||
|
||||
if (!isLifetimeBorrowed(parent->astOperand2(), settings))
|
||||
if (!ValueFlow::isLifetimeBorrowed(parent->astOperand2(), settings))
|
||||
return;
|
||||
|
||||
const Token* expr = getLHSVariableToken(parent);
|
||||
|
@ -3791,7 +3790,7 @@ static void valueFlowForwardLifetime(Token * tok, TokenList *tokenlist, ErrorLog
|
|||
if (expr->exprId() == 0)
|
||||
return;
|
||||
|
||||
const Token* endOfVarScope = getEndOfExprScope(expr);
|
||||
const Token* endOfVarScope = ValueFlow::getEndOfExprScope(expr);
|
||||
|
||||
// Only forward lifetime values
|
||||
std::list<ValueFlow::Value> values = parent->astOperand2()->values();
|
||||
|
@ -3938,7 +3937,7 @@ struct LifetimeStore {
|
|||
if (!argtok)
|
||||
return false;
|
||||
bool update = false;
|
||||
for (const LifetimeToken& lt : getLifetimeTokens(argtok)) {
|
||||
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(argtok)) {
|
||||
if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
|
||||
continue;
|
||||
ErrorPath er = errorPath;
|
||||
|
@ -4000,7 +3999,7 @@ struct LifetimeStore {
|
|||
if (argtok->values().empty()) {
|
||||
ErrorPath er;
|
||||
er.emplace_back(argtok, message);
|
||||
for (const LifetimeToken& lt : getLifetimeTokens(argtok)) {
|
||||
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(argtok)) {
|
||||
if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
|
||||
continue;
|
||||
ValueFlow::Value value;
|
||||
|
@ -4029,7 +4028,7 @@ struct LifetimeStore {
|
|||
if (!v.isLifetimeValue())
|
||||
continue;
|
||||
const Token *tok3 = v.tokvalue;
|
||||
for (const LifetimeToken& lt : getLifetimeTokens(tok3)) {
|
||||
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok3)) {
|
||||
if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
|
||||
continue;
|
||||
ErrorPath er = v.errorPath;
|
||||
|
@ -4101,7 +4100,7 @@ struct LifetimeStore {
|
|||
continue;
|
||||
const Token *tok2 = v.tokvalue;
|
||||
ErrorPath er = v.errorPath;
|
||||
const Variable *var = getLifetimeVariable(tok2, er);
|
||||
const Variable *var = ValueFlow::getLifetimeVariable(tok2, er);
|
||||
// TODO: the inserted data is never used
|
||||
er.insert(er.end(), errorPath.cbegin(), errorPath.cend());
|
||||
if (!var)
|
||||
|
@ -4199,9 +4198,9 @@ static void valueFlowLifetimeUserConstructor(Token* tok,
|
|||
const Token* expr = tok2->astOperand2();
|
||||
if (!var)
|
||||
continue;
|
||||
if (!isLifetimeBorrowed(expr, settings))
|
||||
if (!ValueFlow::isLifetimeBorrowed(expr, settings))
|
||||
continue;
|
||||
const Variable* argvar = getLifetimeVariable(expr);
|
||||
const Variable* argvar = ValueFlow::getLifetimeVariable(expr);
|
||||
if (var->isReference() || var->isRValueReference()) {
|
||||
if (argvar && argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) {
|
||||
paramCapture[argvar] = LifetimeCapture::ByReference;
|
||||
|
@ -4312,7 +4311,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog
|
|||
LifetimeStore{
|
||||
args.back(), "Added to container '" + memtok->str() + "'.", ValueFlow::Value::LifetimeKind::Object}
|
||||
.byDerefCopy(memtok, tokenlist, errorLogger, settings);
|
||||
} else if (!args.empty() && isLifetimeBorrowed(args.back(), settings)) {
|
||||
} else if (!args.empty() && ValueFlow::isLifetimeBorrowed(args.back(), settings)) {
|
||||
LifetimeStore{
|
||||
args.back(), "Added to container '" + memtok->str() + "'.", ValueFlow::Value::LifetimeKind::Object}
|
||||
.byVal(memtok, tokenlist, errorLogger, settings);
|
||||
|
@ -4331,7 +4330,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog
|
|||
for (const Token* returnTok : returns) {
|
||||
if (returnTok == tok)
|
||||
continue;
|
||||
const Variable *returnVar = getLifetimeVariable(returnTok);
|
||||
const Variable *returnVar = ValueFlow::getLifetimeVariable(returnTok);
|
||||
if (returnVar && returnVar->isArgument() && (returnVar->isConst() || !isVariableChanged(returnVar, settings, tokenlist->isCPP()))) {
|
||||
LifetimeStore ls = LifetimeStore::fromFunctionArg(f, tok, returnVar, tokenlist, errorLogger);
|
||||
ls.inconclusive = inconclusive;
|
||||
|
@ -4750,7 +4749,7 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase* /*db*/, Erro
|
|||
}
|
||||
// address of
|
||||
else if (tok->isUnaryOp("&")) {
|
||||
for (const LifetimeToken& lt : getLifetimeTokens(tok->astOperand1())) {
|
||||
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok->astOperand1())) {
|
||||
if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
|
||||
continue;
|
||||
ErrorPath errorPath = lt.errorPath;
|
||||
|
@ -4869,7 +4868,7 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase* /*db*/, Erro
|
|||
// Check variables
|
||||
else if (tok->variable()) {
|
||||
ErrorPath errorPath;
|
||||
const Variable * var = getLifetimeVariable(tok, errorPath);
|
||||
const Variable * var = ValueFlow::getLifetimeVariable(tok, errorPath);
|
||||
if (!var)
|
||||
continue;
|
||||
if (var->nameToken() == tok)
|
||||
|
@ -5002,7 +5001,7 @@ static void valueFlowAfterMove(TokenList* tokenlist, SymbolDatabase* symboldatab
|
|||
continue;
|
||||
if (parent && parent->astOperand1() && parent->astOperand1()->varId() == varId)
|
||||
continue;
|
||||
const Token* const endOfVarScope = getEndOfExprScope(varTok);
|
||||
const Token* const endOfVarScope = ValueFlow::getEndOfExprScope(varTok);
|
||||
|
||||
const Token * openParentesisOfMove = findOpenParentesisOfMove(varTok);
|
||||
const Token * endOfFunctionCall = findEndOfFunctionCallForParameter(openParentesisOfMove);
|
||||
|
@ -5261,7 +5260,7 @@ static void valueFlowSymbolic(TokenList* tokenlist, SymbolDatabase* symboldataba
|
|||
continue;
|
||||
|
||||
Token* start = nextAfterAstRightmostLeaf(tok);
|
||||
const Token* end = getEndOfExprScope(tok->astOperand1(), scope);
|
||||
const Token* end = ValueFlow::getEndOfExprScope(tok->astOperand1(), scope);
|
||||
|
||||
ValueFlow::Value rhs = makeSymbolic(tok->astOperand2());
|
||||
rhs.errorPath.emplace_back(tok,
|
||||
|
@ -5306,6 +5305,8 @@ static const Token* isStrlenOf(const Token* tok, const Token* expr, int depth =
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val);
|
||||
|
||||
static void valueFlowSymbolicOperators(TokenList* tokenlist, SymbolDatabase* symboldatabase)
|
||||
{
|
||||
for (const Scope* scope : symboldatabase->functionScopes) {
|
||||
|
@ -5530,7 +5531,7 @@ static void valueFlowForwardAssign(Token* const tok,
|
|||
{
|
||||
if (Token::simpleMatch(tok->astParent(), "return"))
|
||||
return;
|
||||
const Token* endOfVarScope = getEndOfExprScope(expr);
|
||||
const Token* endOfVarScope = ValueFlow::getEndOfExprScope(expr);
|
||||
if (std::any_of(values.cbegin(), values.cend(), std::mem_fn(&ValueFlow::Value::isLifetimeValue))) {
|
||||
valueFlowForwardLifetime(tok, tokenlist, errorLogger, settings);
|
||||
values.remove_if(std::mem_fn(&ValueFlow::Value::isLifetimeValue));
|
||||
|
@ -5872,7 +5873,7 @@ static bool isBreakScope(const Token* const endToken)
|
|||
return Token::findmatch(endToken->link(), "break|goto", endToken);
|
||||
}
|
||||
|
||||
ValueFlow::Value asImpossible(ValueFlow::Value v)
|
||||
ValueFlow::Value ValueFlow::asImpossible(ValueFlow::Value v)
|
||||
{
|
||||
v.invertRange();
|
||||
v.setImpossible();
|
||||
|
@ -5881,7 +5882,7 @@ ValueFlow::Value asImpossible(ValueFlow::Value v)
|
|||
|
||||
static void insertImpossible(std::list<ValueFlow::Value>& values, const std::list<ValueFlow::Value>& input)
|
||||
{
|
||||
std::transform(input.cbegin(), input.cend(), std::back_inserter(values), &asImpossible);
|
||||
std::transform(input.cbegin(), input.cend(), std::back_inserter(values), &ValueFlow::asImpossible);
|
||||
}
|
||||
|
||||
static void insertNegateKnown(std::list<ValueFlow::Value>& values, const std::list<ValueFlow::Value>& input)
|
||||
|
@ -6476,7 +6477,7 @@ struct ConditionHandler {
|
|||
changeKnownToPossible(values);
|
||||
}
|
||||
}
|
||||
forward(after, getEndOfExprScope(cond.vartok, scope), cond.vartok, values, tokenlist);
|
||||
forward(after, ValueFlow::getEndOfExprScope(cond.vartok, scope), cond.vartok, values, tokenlist);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -6548,7 +6549,7 @@ struct IntegralInferModel : InferModel {
|
|||
}
|
||||
};
|
||||
|
||||
ValuePtr<InferModel> makeIntegralInferModel() {
|
||||
ValuePtr<InferModel> ValueFlow::makeIntegralInferModel() {
|
||||
return IntegralInferModel{};
|
||||
}
|
||||
|
||||
|
@ -6564,18 +6565,6 @@ ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, Math
|
|||
return ValueFlow::Value{};
|
||||
}
|
||||
|
||||
ValueFlow::Value inferCondition(const std::string &op, MathLib::bigint val, const Token* varTok)
|
||||
{
|
||||
if (!varTok)
|
||||
return ValueFlow::Value{};
|
||||
if (varTok->hasKnownIntValue())
|
||||
return ValueFlow::Value{};
|
||||
std::vector<ValueFlow::Value> r = infer(IntegralInferModel{}, op, val, varTok->values());
|
||||
if (r.size() == 1 && r.front().isKnown())
|
||||
return r.front();
|
||||
return ValueFlow::Value{};
|
||||
}
|
||||
|
||||
struct IteratorInferModel : InferModel {
|
||||
virtual ValueFlow::Value::ValueType getType() const = 0;
|
||||
bool match(const ValueFlow::Value& value) const override {
|
||||
|
@ -6944,14 +6933,14 @@ static void valueFlowForLoop(TokenList *tokenlist, SymbolDatabase* symboldatabas
|
|||
if (executeBody && vartok) {
|
||||
std::list<ValueFlow::Value> initValues;
|
||||
initValues.emplace_back(initValue, ValueFlow::Value::Bound::Lower);
|
||||
initValues.push_back(asImpossible(initValues.back()));
|
||||
initValues.push_back(ValueFlow::asImpossible(initValues.back()));
|
||||
Analyzer::Result result = valueFlowForward(bodyStart, bodyStart->link(), vartok, initValues, tokenlist);
|
||||
|
||||
if (!result.action.isModified()) {
|
||||
std::list<ValueFlow::Value> lastValues;
|
||||
lastValues.emplace_back(lastValue, ValueFlow::Value::Bound::Upper);
|
||||
lastValues.back().conditional = true;
|
||||
lastValues.push_back(asImpossible(lastValues.back()));
|
||||
lastValues.push_back(ValueFlow::asImpossible(lastValues.back()));
|
||||
if (stepValue != 1)
|
||||
lastValues.pop_front();
|
||||
valueFlowForward(bodyStart, bodyStart->link(), vartok, lastValues, tokenlist);
|
||||
|
@ -7838,7 +7827,7 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer {
|
|||
return Action::Invalid;
|
||||
if (isLikelyStreamRead(isCPP(), tok->astParent()))
|
||||
return Action::Invalid;
|
||||
if (astIsContainer(tok) && isContainerSizeChanged(tok, getIndirect(tok), getSettings()))
|
||||
if (astIsContainer(tok) && ValueFlow::isContainerSizeChanged(tok, getIndirect(tok), getSettings()))
|
||||
return read | Action::Invalid;
|
||||
return read;
|
||||
}
|
||||
|
@ -7871,9 +7860,9 @@ static const Token* parseBinaryIntOp(const Token* expr,
|
|||
return varTok;
|
||||
}
|
||||
|
||||
const Token* solveExprValue(const Token* expr,
|
||||
const std::function<std::vector<MathLib::bigint>(const Token*)>& eval,
|
||||
ValueFlow::Value& value)
|
||||
const Token* ValueFlow::solveExprValue(const Token* expr,
|
||||
const std::function<std::vector<MathLib::bigint>(const Token*)>& eval,
|
||||
ValueFlow::Value& value)
|
||||
{
|
||||
if (!value.isIntValue() && !value.isIteratorValue() && !value.isSymbolicValue())
|
||||
return expr;
|
||||
|
@ -7889,24 +7878,24 @@ const Token* solveExprValue(const Token* expr,
|
|||
switch (expr->str()[0]) {
|
||||
case '+': {
|
||||
value.intvalue -= intval;
|
||||
return solveExprValue(binaryTok, eval, value);
|
||||
return ValueFlow::solveExprValue(binaryTok, eval, value);
|
||||
}
|
||||
case '-': {
|
||||
if (rhs)
|
||||
value.intvalue = intval - value.intvalue;
|
||||
else
|
||||
value.intvalue += intval;
|
||||
return solveExprValue(binaryTok, eval, value);
|
||||
return ValueFlow::solveExprValue(binaryTok, eval, value);
|
||||
}
|
||||
case '*': {
|
||||
if (intval == 0)
|
||||
break;
|
||||
value.intvalue /= intval;
|
||||
return solveExprValue(binaryTok, eval, value);
|
||||
return ValueFlow::solveExprValue(binaryTok, eval, value);
|
||||
}
|
||||
case '^': {
|
||||
value.intvalue ^= intval;
|
||||
return solveExprValue(binaryTok, eval, value);
|
||||
return ValueFlow::solveExprValue(binaryTok, eval, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7915,7 +7904,7 @@ const Token* solveExprValue(const Token* expr,
|
|||
|
||||
static const Token* solveExprValue(const Token* expr, ValueFlow::Value& value)
|
||||
{
|
||||
return solveExprValue(
|
||||
return ValueFlow::solveExprValue(
|
||||
expr,
|
||||
[](const Token* tok) -> std::vector<MathLib::bigint> {
|
||||
if (tok->hasKnownIntValue())
|
||||
|
@ -7940,7 +7929,7 @@ ValuePtr<Analyzer> makeReverseAnalyzer(const Token* exprTok, const ValueFlow::Va
|
|||
return ExpressionAnalyzer(exprTok, value, tokenlist);
|
||||
}
|
||||
|
||||
bool isContainerSizeChanged(const Token* tok, int indirect, const Settings* settings, int depth)
|
||||
bool ValueFlow::isContainerSizeChanged(const Token* tok, int indirect, const Settings* settings, int depth)
|
||||
{
|
||||
if (!tok)
|
||||
return false;
|
||||
|
@ -7991,7 +7980,7 @@ static bool isContainerSizeChanged(nonneg int varId,
|
|||
for (const Token *tok = start; tok != end; tok = tok->next()) {
|
||||
if (tok->varId() != varId)
|
||||
continue;
|
||||
if (isContainerSizeChanged(tok, indirect, settings, depth))
|
||||
if (ValueFlow::isContainerSizeChanged(tok, indirect, settings, depth))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
147
lib/valueflow.h
147
lib/valueflow.h
|
@ -47,7 +47,7 @@ class ValuePtr;
|
|||
|
||||
namespace ValueFlow {
|
||||
/// Constant folding of expression. This can be used before the full ValueFlow has been executed (ValueFlow::setValues).
|
||||
const ValueFlow::Value * valueFlowConstantFoldAST(Token *expr, const Settings *settings);
|
||||
const Value * valueFlowConstantFoldAST(Token *expr, const Settings *settings);
|
||||
|
||||
/// Perform valueflow analysis.
|
||||
void setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings);
|
||||
|
@ -56,82 +56,77 @@ namespace ValueFlow {
|
|||
|
||||
size_t getSizeOf(const ValueType &vt, const Settings *settings);
|
||||
|
||||
const ValueFlow::Value* findValue(const std::list<ValueFlow::Value>& values,
|
||||
const Settings* settings,
|
||||
const std::function<bool(const ValueFlow::Value&)> &pred);
|
||||
const Value* findValue(const std::list<Value>& values,
|
||||
const Settings* settings,
|
||||
const std::function<bool(const Value&)> &pred);
|
||||
|
||||
std::vector<ValueFlow::Value> isOutOfBounds(const Value& size, const Token* indexTok, bool possible = true);
|
||||
std::vector<Value> isOutOfBounds(const Value& size, const Token* indexTok, bool possible = true);
|
||||
|
||||
Value asImpossible(Value v);
|
||||
|
||||
bool isContainerSizeChanged(const Token* tok, int indirect, const Settings* settings = nullptr, int depth = 20);
|
||||
|
||||
struct LifetimeToken {
|
||||
const Token* token;
|
||||
Value::ErrorPath errorPath;
|
||||
bool addressOf;
|
||||
bool inconclusive;
|
||||
|
||||
LifetimeToken() : token(nullptr), errorPath(), addressOf(false), inconclusive(false) {}
|
||||
|
||||
LifetimeToken(const Token* token, Value::ErrorPath errorPath)
|
||||
: token(token), errorPath(std::move(errorPath)), addressOf(false), inconclusive(false)
|
||||
{}
|
||||
|
||||
LifetimeToken(const Token* token, bool addressOf, Value::ErrorPath errorPath)
|
||||
: token(token), errorPath(std::move(errorPath)), addressOf(addressOf), inconclusive(false)
|
||||
{}
|
||||
|
||||
static std::vector<LifetimeToken> setAddressOf(std::vector<LifetimeToken> v, bool b) {
|
||||
for (LifetimeToken& x : v)
|
||||
x.addressOf = b;
|
||||
return v;
|
||||
}
|
||||
|
||||
static std::vector<LifetimeToken> setInconclusive(std::vector<LifetimeToken> v, bool b) {
|
||||
for (LifetimeToken& x : v)
|
||||
x.inconclusive = b;
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
const Token *parseCompareInt(const Token *tok, Value &true_value, Value &false_value, const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate);
|
||||
const Token *parseCompareInt(const Token *tok, Value &true_value, Value &false_value);
|
||||
|
||||
CPPCHECKLIB ValuePtr<InferModel> makeIntegralInferModel();
|
||||
|
||||
const Token* solveExprValue(const Token* expr,
|
||||
const std::function<std::vector<MathLib::bigint>(const Token*)>& eval,
|
||||
Value& value);
|
||||
|
||||
std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
||||
bool escape = false,
|
||||
Value::ErrorPath errorPath = Value::ErrorPath{});
|
||||
|
||||
bool hasLifetimeToken(const Token* tok, const Token* lifetime);
|
||||
|
||||
const Variable* getLifetimeVariable(const Token* tok, Value::ErrorPath& errorPath, bool* addressOf = nullptr);
|
||||
|
||||
const Variable* getLifetimeVariable(const Token* tok);
|
||||
|
||||
bool isLifetimeBorrowed(const Token *tok, const Settings *settings);
|
||||
|
||||
std::string lifetimeMessage(const Token *tok, const Value *val, Value::ErrorPath &errorPath);
|
||||
|
||||
CPPCHECKLIB Value getLifetimeObjValue(const Token *tok, bool inconclusive = false);
|
||||
|
||||
CPPCHECKLIB std::vector<Value> getLifetimeObjValues(const Token* tok,
|
||||
bool inconclusive = false,
|
||||
MathLib::bigint path = 0);
|
||||
|
||||
const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope = nullptr, bool smallest = true);
|
||||
|
||||
void combineValueProperties(const Value& value1, const Value& value2, Value* result);
|
||||
}
|
||||
|
||||
ValueFlow::Value asImpossible(ValueFlow::Value v);
|
||||
|
||||
bool isContainerSizeChanged(const Token* tok, int indirect, const Settings* settings = nullptr, int depth = 20);
|
||||
|
||||
struct LifetimeToken {
|
||||
const Token* token;
|
||||
ValueFlow::Value::ErrorPath errorPath;
|
||||
bool addressOf;
|
||||
bool inconclusive;
|
||||
|
||||
LifetimeToken() : token(nullptr), errorPath(), addressOf(false), inconclusive(false) {}
|
||||
|
||||
LifetimeToken(const Token* token, ValueFlow::Value::ErrorPath errorPath)
|
||||
: token(token), errorPath(std::move(errorPath)), addressOf(false), inconclusive(false)
|
||||
{}
|
||||
|
||||
LifetimeToken(const Token* token, bool addressOf, ValueFlow::Value::ErrorPath errorPath)
|
||||
: token(token), errorPath(std::move(errorPath)), addressOf(addressOf), inconclusive(false)
|
||||
{}
|
||||
|
||||
static std::vector<LifetimeToken> setAddressOf(std::vector<LifetimeToken> v, bool b) {
|
||||
for (LifetimeToken& x : v)
|
||||
x.addressOf = b;
|
||||
return v;
|
||||
}
|
||||
|
||||
static std::vector<LifetimeToken> setInconclusive(std::vector<LifetimeToken> v, bool b) {
|
||||
for (LifetimeToken& x : v)
|
||||
x.inconclusive = b;
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
const Token *parseCompareInt(const Token *tok, ValueFlow::Value &true_value, ValueFlow::Value &false_value, const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate);
|
||||
const Token *parseCompareInt(const Token *tok, ValueFlow::Value &true_value, ValueFlow::Value &false_value);
|
||||
|
||||
ValueFlow::Value inferCondition(const std::string& op, MathLib::bigint val, const Token* varTok);
|
||||
ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val);
|
||||
|
||||
CPPCHECKLIB ValuePtr<InferModel> makeIntegralInferModel();
|
||||
|
||||
const Token* solveExprValue(const Token* expr,
|
||||
const std::function<std::vector<MathLib::bigint>(const Token*)>& eval,
|
||||
ValueFlow::Value& value);
|
||||
|
||||
std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
|
||||
bool escape = false,
|
||||
ValueFlow::Value::ErrorPath errorPath = ValueFlow::Value::ErrorPath{});
|
||||
|
||||
bool hasLifetimeToken(const Token* tok, const Token* lifetime);
|
||||
|
||||
const Variable* getLifetimeVariable(const Token* tok, ValueFlow::Value::ErrorPath& errorPath, bool* addressOf = nullptr);
|
||||
|
||||
const Variable* getLifetimeVariable(const Token* tok);
|
||||
|
||||
bool isLifetimeBorrowed(const Token *tok, const Settings *settings);
|
||||
|
||||
std::string lifetimeType(const Token *tok, const ValueFlow::Value *val);
|
||||
|
||||
std::string lifetimeMessage(const Token *tok, const ValueFlow::Value *val, ValueFlow::Value::ErrorPath &errorPath);
|
||||
|
||||
CPPCHECKLIB ValueFlow::Value getLifetimeObjValue(const Token *tok, bool inconclusive = false);
|
||||
|
||||
CPPCHECKLIB std::vector<ValueFlow::Value> getLifetimeObjValues(const Token* tok,
|
||||
bool inconclusive = false,
|
||||
MathLib::bigint path = 0);
|
||||
|
||||
const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope = nullptr, bool smallest = true);
|
||||
|
||||
void combineValueProperties(const ValueFlow::Value& value1, const ValueFlow::Value& value2, ValueFlow::Value* result);
|
||||
|
||||
#endif // valueflowH
|
||||
|
|
Loading…
Reference in New Issue