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

Method traverse

lib/reverseanalyzer.cpp:204–386  ·  view source on GitHub ↗

* @throws InternalError thrown on cyclic analysis */

Source from the content-addressed store, hash-verified

202 * @throws InternalError thrown on cyclic analysis
203 */
204 void traverse(Token* start, const Token* end = nullptr) {
205 if (start == end)
206 return;
207 std::size_t i = start->index();
208 for (Token* tok = start->previous(); succeeds(tok, end); tok = tok->previous()) {
209 if (tok->index() >= i)
210 throw InternalError(tok, "Cyclic reverse analysis.");
211 i = tok->index();
212 if (tok == start || (tok->str() == "{" && (tok->scope()->type == ScopeType::eFunction ||
213 tok->scope()->type == ScopeType::eLambda))) {
214 const Function* f = tok->scope()->function;
215 if (f && f->isConstructor()) {
216 if (const Token* initList = f->constructorMemberInitialization())
217 traverse(tok->previous(), tok->tokAt(initList->index() - tok->index()));
218 }
219 break;
220 }
221 if (Token::Match(tok, "return|break|continue"))
222 break;
223 if (Token::Match(tok, "%name% :"))
224 break;
225 if (Token::simpleMatch(tok, ":"))
226 continue;
227 // Evaluate LHS of assignment before RHS
228 if (Token* assignTok = assignExpr(tok)) {
229 // If assignTok has broken ast then stop
230 if (!assignTok->astOperand1() || !assignTok->astOperand2())
231 break;
232 Token* assignTop = assignTok;
233 bool continueB = true;
234 while (assignTop->isAssignmentOp()) {
235 if (!Token::Match(assignTop->astOperand1(), "%assign%")) {
236 continueB &= updateRecursive(assignTop->astOperand1());
237 }
238 if (!assignTop->astParent() || Token::simpleMatch(assignTop->astParent(), ";"))
239 break;
240 assignTop = assignTop->astParent();
241 }
242 // Is assignment in dead code
243 if (Token* parent = isDeadCode(assignTok)) {
244 tok = parent;
245 continue;
246 }
247 // Simple assign
248 if (assignTok->str() == "=" && (assignTok->astParent() == assignTop || assignTok == assignTop)) {
249 Analyzer::Action rhsAction =
250 analyzer->analyze(assignTok->astOperand2(), Analyzer::Direction::Reverse);
251 Analyzer::Action lhsAction =
252 analyzer->analyze(assignTok->astOperand1(), Analyzer::Direction::Reverse);
253 // Assignment from
254 if (rhsAction.isRead() && !lhsAction.isInvalid() && assignTok->astOperand1()->exprId() > 0) {
255 const std::string info = "Assignment from '" + assignTok->expressionString() + "'";
256 ValuePtr<Analyzer> a = analyzer->reanalyze(assignTok->astOperand1(), info);
257 if (a) {
258 valueFlowGenericForward(nextAfterAstRightmostLeaf(assignTok->astOperand2()),
259 assignTok->astOperand2()->scope()->bodyEnd,
260 a,
261 tokenlist,

Callers 1

valueFlowGenericReverseFunction · 0.80

Calls 15

succeedsFunction · 0.85
updateRecursiveFunction · 0.85
valueFlowGenericForwardFunction · 0.85
isConstExpressionFunction · 0.85
valueFlowGenericReverseFunction · 0.85
isUnevaluatedFunction · 0.85
precedesFunction · 0.85
getCondTokFromEndFunction · 0.85
analyzeRecursiveFunction · 0.85
analyzeRangeFunction · 0.85

Tested by

no test coverage detected