MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / followVariableExpression

Function followVariableExpression

lib/astutils.cpp:1189–1246  ·  view source on GitHub ↗

This takes a token that refers to a variable and it will return the token to the expression that the variable is assigned to. If its not valid to make such substitution then it will return the original token.

Source from the content-addressed store, hash-verified

1187/// to the expression that the variable is assigned to. If its not valid to
1188/// make such substitution then it will return the original token.
1189static const Token * followVariableExpression(const Settings& settings, const Token * tok, const Token * end = nullptr)
1190{
1191 if (!tok)
1192 return tok;
1193 // Skip following variables that is across multiple files
1194 if (end && end->fileIndex() != tok->fileIndex())
1195 return tok;
1196 // Skip array access
1197 if (Token::Match(tok, "%var% ["))
1198 return tok;
1199 // Skip pointer indirection
1200 if (tok->astParent() && tok->isUnaryOp("*"))
1201 return tok;
1202 // Skip following variables if it is used in an assignment
1203 if (Token::Match(tok->next(), "%assign%"))
1204 return tok;
1205 const Variable * var = tok->variable();
1206 const Token * varTok = getVariableInitExpression(var);
1207 if (!varTok)
1208 return tok;
1209 if (hasUnknownVars(varTok))
1210 return tok;
1211 if (astIsRangeBasedForDecl(var->nameToken()))
1212 return tok;
1213 if (var->isVolatile())
1214 return tok;
1215 if (!var->isLocal() && !var->isConst())
1216 return tok;
1217 if (var->isStatic() && !var->isConst())
1218 return tok;
1219 if (var->isArgument())
1220 return tok;
1221 if (isStructuredBindingVariable(var))
1222 return tok;
1223 // assigning a floating point value to an integer does not preserve the value
1224 if (var->valueType() && var->valueType()->isIntegral() && varTok->valueType() && varTok->valueType()->isFloat())
1225 return tok;
1226 const Token * lastTok = precedes(tok, end) ? end : tok;
1227 // If this is in a loop then check if variables are modified in the entire scope
1228 const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok;
1229 const int indirect = var->isArray() ? var->dimensions().size() : 0;
1230 if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, indirect, tok->varId(), false, settings)))
1231 return tok;
1232 if (precedes(varTok, endToken) && isAliased(varTok, endToken, tok->varId()))
1233 return tok;
1234 const Token* startToken = nextAfterAstRightmostLeaf(varTok);
1235 if (!startToken)
1236 startToken = varTok;
1237 if (varTok->exprId() == 0) {
1238 if (!varTok->isLiteral())
1239 return tok;
1240 } else if (!precedes(startToken, endToken)) {
1241 return tok;
1242 } else if (findExpressionChanged(varTok, startToken, endToken, settings)) {
1243 return tok;
1244 }
1245 return varTok;
1246}

Callers 1

isSameExpressionFunction · 0.85

Calls 15

hasUnknownVarsFunction · 0.85
astIsRangeBasedForDeclFunction · 0.85
precedesFunction · 0.85
isInLoopConditionFunction · 0.85
isVariableChangedFunction · 0.85
isAliasedFunction · 0.85
findExpressionChangedFunction · 0.85
fileIndexMethod · 0.80
astParentMethod · 0.80

Tested by

no test coverage detected