| 125 | |
| 126 | template<class T, class F, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )> |
| 127 | Progress traverseTok(T* tok, const F &f, bool traverseUnknown, T** out = nullptr) { |
| 128 | if (Token::Match(tok, "asm|goto")) |
| 129 | return Break(Analyzer::Terminate::Bail); |
| 130 | if (Token::Match(tok, "setjmp|longjmp (")) { |
| 131 | // Traverse the parameters of the function before escaping |
| 132 | traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown); |
| 133 | return Break(Analyzer::Terminate::Bail); |
| 134 | } |
| 135 | if (Token::simpleMatch(tok, "continue")) { |
| 136 | if (loopEnds.empty()) |
| 137 | return Break(Analyzer::Terminate::Escape); |
| 138 | // If we are in a loop then jump to the end |
| 139 | if (out) |
| 140 | *out = loopEnds.back(); |
| 141 | } else if (Token::Match(tok, "return|throw")) { |
| 142 | traverseRecursive(tok->astOperand2(), f, traverseUnknown); |
| 143 | traverseRecursive(tok->astOperand1(), f, traverseUnknown); |
| 144 | return Break(Analyzer::Terminate::Escape); |
| 145 | } else if (Token::Match(tok, "%name% (") && isEscapeFunction(tok, settings.library)) { |
| 146 | // Traverse the parameters of the function before escaping |
| 147 | traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown); |
| 148 | return Break(Analyzer::Terminate::Escape); |
| 149 | } else if (isUnevaluated(tok->previous())) { |
| 150 | if (out) |
| 151 | *out = tok->link(); |
| 152 | return Progress::Skip; |
| 153 | } else if (tok->astOperand1() && tok->astOperand2() && Token::Match(tok, "?|&&|%oror%")) { |
| 154 | if (traverseConditional(tok, f, traverseUnknown) == Progress::Break) |
| 155 | return Break(); |
| 156 | if (out) |
| 157 | *out = nextAfterAstRightmostLeaf(tok); |
| 158 | return Progress::Skip; |
| 159 | // Skip lambdas |
| 160 | } else if (T* lambdaEndToken = findLambdaEndToken(tok)) { |
| 161 | if (checkScope(lambdaEndToken).isModified()) |
| 162 | return Break(Analyzer::Terminate::Bail); |
| 163 | if (out) |
| 164 | *out = lambdaEndToken->next(); |
| 165 | // Skip class scope |
| 166 | } else if (tok->str() == "{" && tok->scope() && tok->scope()->isClassOrStruct()) { |
| 167 | if (out) |
| 168 | *out = tok->link(); |
| 169 | } else { |
| 170 | if (f(tok) == Progress::Break) |
| 171 | return Break(); |
| 172 | } |
| 173 | return Progress::Continue; |
| 174 | } |
| 175 | |
| 176 | template<class T, class F, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )> |
| 177 | Progress traverseRecursive(T* tok, const F &f, bool traverseUnknown, unsigned int recursion=0) { |
no test coverage detected