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

Method forwardRange

lib/pathanalysis.cpp:84–173  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

82}
83
84PathAnalysis::Progress PathAnalysis::forwardRange(const Token* startToken, const Token* endToken, Info info, const std::function<PathAnalysis::Progress(const Info&)>& f) const
85{
86 for (const Token *tok = startToken; precedes(tok, endToken); tok = tok->next()) {
87 if (Token::Match(tok, "asm|goto|break|continue"))
88 return Progress::Break;
89 if (Token::Match(tok, "return|throw")) {
90 forwardRecursive(tok, std::move(info), f);
91 return Progress::Break;
92 // Evaluate RHS of assignment before LHS
93 }
94 if (const Token* assignTok = assignExpr(tok)) {
95 if (forwardRecursive(assignTok->astOperand2(), info, f) == Progress::Break)
96 return Progress::Break;
97 if (forwardRecursive(assignTok->astOperand1(), info, f) == Progress::Break)
98 return Progress::Break;
99 tok = nextAfterAstRightmostLeaf(assignTok);
100 if (!tok)
101 return Progress::Break;
102 } else if (Token::simpleMatch(tok, "}") && Token::simpleMatch(tok->link()->previous(), ") {") && Token::Match(tok->link()->linkAt(-1)->previous(), "if|while|for (")) {
103 const Token * blockStart = tok->link()->linkAt(-1)->previous();
104 const Token * condTok = getCondTok(blockStart);
105 if (!condTok)
106 continue;
107 info.errorPath.emplace_back(condTok, "Assuming condition is true.");
108 // Traverse a loop a second time
109 if (Token::Match(blockStart, "for|while (")) {
110 const Token* endCond = blockStart->linkAt(1);
111 bool traverseLoop = true;
112 // Only traverse simple for loops
113 if (Token::simpleMatch(blockStart, "for") && !Token::Match(endCond->tokAt(-3), "; ++|--|%var% %var%|++|-- ) {"))
114 traverseLoop = false;
115 // Traverse loop a second time
116 if (traverseLoop) {
117 // Traverse condition
118 if (forwardRecursive(condTok, info, f) == Progress::Break)
119 return Progress::Break;
120 // TODO: Should we traverse the body: forwardRange(tok->link(), tok, info, f)?
121 }
122 }
123 if (Token::simpleMatch(tok, "} else {")) {
124 tok = tok->linkAt(2);
125 }
126 } else if (Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->linkAt(1), ") {")) {
127 const Token * endCond = tok->linkAt(1);
128 const Token * endBlock = endCond->linkAt(1);
129 const Token * condTok = getCondTok(tok);
130 if (!condTok)
131 continue;
132 // Traverse condition
133 if (forwardRange(tok->next(), tok->linkAt(1), info, f) == Progress::Break)
134 return Progress::Break;
135 Info i = info;
136 i.known = false;
137 i.errorPath.emplace_back(condTok, "Assuming condition is true.");
138
139 // Check if condition is true or false
140 bool checkThen = false;
141 bool checkElse = false;

Callers

nothing calls this directly

Calls 11

precedesFunction · 0.85
getCondTokFunction · 0.85
nextMethod · 0.80
astOperand2Method · 0.80
astOperand1Method · 0.80
linkAtMethod · 0.80
assignExprFunction · 0.70
simpleMatchFunction · 0.70
fFunction · 0.50
tokAtMethod · 0.45

Tested by

no test coverage detected