33 static bool isUnchanged(
const Token *startToken, 
const Token *endToken, 
const std::set<nonneg int> &exprVarIds, 
bool local)
 
   35     for (
const Token *tok = startToken; tok != endToken; tok = tok->
next()) {
 
   39         if (tok->varId() == 0 || exprVarIds.find(tok->varId()) == exprVarIds.end())
 
   41         const Token *parent = tok;
 
   49             if (parent->
astParent()->tokType() == Token::Type::eIncDecOp)
 
   51             if (parent->
astParent()->isAssignmentOp() && parent == parent->
astParent()->astOperand1())
 
   86                   [&ret](
const Token *tok) {
 
  102     for (
const Token* tok = startToken; 
precedes(tok, endToken); tok = tok->next()) {
 
  115         if (!inInnerClass && tok->str() == 
"{" && tok->scope()->isClassOrStruct()) {
 
  123         if (tok->str() == 
"continue")
 
  128             tok = lambdaEndToken;
 
  129             const Result lambdaResult = 
checkRecursive(expr, lambdaEndToken->
link()->next(), lambdaEndToken, exprVarIds, local, inInnerClass, depth);
 
  143                 checkRecursive(expr, startEndTokens.first, startEndTokens.second->
next(), exprVarIds, local, 
true, depth);
 
  156         if (tok->str() == 
"}") {
 
  158             if (tok->scope() == expr->
scope())
 
  161             if (tok->scope()->isLoopScope()) {
 
  163                 const Token *conditionStart = 
nullptr;
 
  164                 const Token *conditionEnd = 
nullptr;
 
  166                     conditionEnd = tok->
link()->previous();
 
  167                     conditionStart = conditionEnd->
link();
 
  169                     conditionStart = tok->
tokAt(2);
 
  170                     conditionEnd = conditionStart->
link();
 
  172                 if (conditionStart && conditionEnd) {
 
  174                     for (
const Token *condTok = conditionStart; condTok != conditionEnd; condTok = condTok->
next()) {
 
  175                         if (exprVarIds.find(condTok->varId()) != exprVarIds.end()) {
 
  192             tok = tok->linkAt(1);
 
  198             const Token *bodyStart = 
nullptr;
 
  199             const Token *conditionStart = 
nullptr;
 
  201                 bodyStart = tok->
next();
 
  203                     conditionStart = bodyStart->
link()->tokAt(2);
 
  205                 conditionStart = tok->
next();
 
  207                     bodyStart = conditionStart->
link()->next();
 
  210             if (!bodyStart || !conditionStart)
 
  214             if (!
isUnchanged(conditionStart, conditionStart->
link(), exprVarIds, local))
 
  224             const Token *conditionStart = tok->
next();
 
  227                 const bool cond = condTok->
values().front().intvalue;
 
  233                     bodyStart = bodyStart->
link()->tokAt(2);
 
  239             tok = bodyStart->
link();
 
  243                 tok = tok->linkAt(2);
 
  248             if (!
isUnchanged(conditionStart, conditionStart->
link(), exprVarIds, local))
 
  266             !
isUnchanged(tok, tok->astParent()->astParent()->link(), exprVarIds, local))
 
  270         if (expr->
isName() && 
Token::Match(tok, 
"%name% (") && tok->str().find(
'<') != std::string::npos && tok->str().find(expr->
str()) != std::string::npos)
 
  273         if (exprVarIds.find(tok->varId()) != exprVarIds.end()) {
 
  274             const Token *parent = tok;
 
  279                 if (parent->
str() == 
"(" && !parent->
isCast())
 
  311                 const auto startEnd = parent->
astParent()->astOperand2()->findExpressionStartEndTokens();
 
  312                 for (
const Token* tok2 = startEnd.first; tok2 != startEnd.second; tok2 = tok2->
next()) {
 
  342                     const std::vector<const Token *> args = 
getArguments(ftok);
 
  344                     while (argnr < args.size() && args[argnr] != parent)
 
  346                     if (argnr < args.size()) {
 
  375                     const Result &result2 = 
checkRecursive(expr, scopeEndToken->
next(), endToken, exprVarIds, local, inInnerClass, depth);
 
  389                 tok = elseStart->
link();
 
  391                 tok = tok->linkAt(1);
 
  402     std::set<nonneg int> exprVarIds;
 
  404     bool unknownVarId = 
false;
 
  406                   [&](
const Token *tok) {
 
  412             return ChildrenToVisit::none;
 
  414         if (tok->
varId() > 0) {
 
  415             exprVarIds.insert(tok->varId());
 
  416             if (!Token::simpleMatch(tok->previous(), 
".")) {
 
  417                 const Variable *var = tok->variable();
 
  418                 if (var && var->isReference() && var->isLocal() && Token::Match(var->nameToken(), 
"%var% [=(]") && !isGlobalData(var->nameToken()->next()->astOperand2()))
 
  419                     return ChildrenToVisit::none;
 
  420                 const bool deref = tok->astParent() && (tok->astParent()->isUnaryOp(
"*") || (tok->astParent()->str() == 
"[" && tok == tok->astParent()->astOperand1()));
 
  421                 local &= !nonLocal(tok->variable(), deref);
 
  429         *unknownVarIdOut = unknownVarId;
 
  437     bool unknownVarId = 
false;
 
  438     std::set<nonneg int> exprVarIds = 
getExprVarIds(expr, &local, &unknownVarId);
 
  458         result = 
checkRecursive(expr, scopeEndToken->
next(), endToken, exprVarIds, local, 
false);
 
  504     const bool macro = 
false;
 
  505     const bool pure = 
false;
 
  506     const bool followVar = 
false;
 
  507     for (
const Token *tok = startToken; tok; tok = tok->
previous()) {
 
  511             const std::vector<const Token*> args = 
getArguments(tok);
 
  512             for (
int argnr = 0; argnr < args.size(); ++argnr) {
 
  515                 if (tok->function() && tok->function()->getArgumentVar(argnr) && !tok->function()->getArgumentVar(argnr)->isReference() && !tok->function()->isConst())
 
  517                 for (
const Token *subexpr = expr; subexpr; subexpr = subexpr->
astOperand1()) {
 
  528         const Token *addrOf = 
nullptr;
 
  531         else if (tok->isUnaryOp(
"&"))
 
  535         else if (tok->valueType() && tok->valueType()->pointer &&
 
  538             addrOf = tok->
tokAt(2);
 
  542         for (
const Token *subexpr = expr; subexpr; subexpr = subexpr->
astOperand1()) {
 
  552     for (
const Token *subexpr = expr; subexpr; subexpr = subexpr->
astOperand1()) {
 
  554             if (!val.isLocalLifetimeValue())
 
  556             const Variable* var = val.tokvalue->variable();
 
std::vector< const Token * > getArguments(const Token *ftok)
Get arguments (AST)
 
bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Settings &settings, bool pure, bool followVar, ErrorPath *errors)
 
bool astIsContainerView(const Token *tok)
 
bool precedes(const Token *tok1, const Token *tok2)
If tok2 comes after tok1.
 
bool isGlobalData(const Token *expr)
 
const Token * findNextTokenFromBreak(const Token *breakToken)
For a "break" token, locate the next token to execute.
 
const Token * findLambdaEndToken(const Token *first)
find lambda function end token
 
bool isReturnScope(const Token *const endToken, const Library &library, const Token **unknownFunc, bool functionScope)
Is scope a return scope (scope will unconditionally return)
 
void visitAstNodes(T *ast, const TFunc &visitor)
Visit AST nodes recursively.
 
const Settings & mSettings
 
bool possiblyAliased(const Token *expr, const Token *startToken) const
Is there some possible alias for given expression.
 
std::vector< KnownAndToken > mValueFlow
 
bool hasOperand(const Token *tok, const Token *lhs) const
 
enum FwdAnalysis::What mWhat
 
static bool isEscapedAlias(const Token *expr)
 
Result check(const Token *expr, const Token *startToken, const Token *endToken)
 
Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set< nonneg int > &exprVarIds, bool local, bool inInnerClass, int depth=0)
 
std::set< nonneg int > getExprVarIds(const Token *expr, bool *localOut=nullptr, bool *unknownVarIdOut=nullptr) const
 
const Token * reassign(const Token *expr, const Token *startToken, const Token *endToken)
Check if "expr" is reassigned.
 
bool unusedValue(const Token *expr, const Token *startToken, const Token *endToken)
Check if "expr" is used.
 
const Function * getFunction(const Token *ftok) const
 
std::list< Variable > varlist
 
The token list that the TokenList generates is a linked-list of this class.
 
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
 
bool hasKnownIntValue() const
 
const ValueType * valueType() const
 
void astOperand1(Token *tok)
 
std::pair< const Token *, const Token * > findExpressionStartEndTokens() const
 
bool isUnaryOp(const std::string &s) const
 
const Token * tokAt(int index) const
 
void astOperand2(Token *tok)
 
void scope(const Scope *s)
Associate this token with given scope.
 
void link(Token *linkToToken)
Create link to given token.
 
const Token * linkAt(int index) const
 
void variable(const Variable *v)
Associate this token with given variable.
 
const std::list< ValueFlow::Value > & values() const
 
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
 
void astParent(Token *tok)
 
Reference reference
Is the outermost indirection of this type a reference or rvalue.
 
nonneg int pointer
0=>not pointer, 1=>*, 2=>**, 3=>***, etc
 
Information about a member variable.
 
bool isArgument() const
Is variable a function argument.
 
bool isExtern() const
Is variable extern.
 
bool isReference() const
Is reference variable.
 
bool isLocal() const
Is variable local.
 
bool isPointer() const
Is pointer variable.
 
bool isStatic() const
Is variable static.
 
static bool hasFunctionCall(const Token *tok)
 
static bool hasVolatileCastOrVar(const Token *expr)
 
static bool nonLocal(const Variable *var, bool deref)
 
static bool isUnchanged(const Token *startToken, const Token *endToken, const std::set< nonneg int > &exprVarIds, bool local)
 
static bool hasGccCompoundStatement(const Token *tok)
 
Result of forward analysis.
 
enum FwdAnalysis::Result::Type type
 
@ DIR_OUT
Output to caller. Data is passed by reference or address and is potentially written.
 
std::map< int, ArgumentChecks > argumentChecks