| 95 | } |
| 96 | |
| 97 | FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set<nonneg int> &exprVarIds, bool local, bool inInnerClass, int depth) |
| 98 | { |
| 99 | // Parse the given tokens |
| 100 | if (++depth > 1000) |
| 101 | return Result(Result::Type::BAILOUT); |
| 102 | |
| 103 | for (const Token* tok = startToken; precedes(tok, endToken); tok = tok->next()) { |
| 104 | if (Token::simpleMatch(tok, "try {")) { |
| 105 | // TODO: handle try |
| 106 | return Result(Result::Type::BAILOUT); |
| 107 | } |
| 108 | |
| 109 | if (Token::simpleMatch(tok, "break ;")) { |
| 110 | return Result(Result::Type::BREAK, tok); |
| 111 | } |
| 112 | |
| 113 | if (Token::simpleMatch(tok, "goto")) |
| 114 | return Result(Result::Type::BAILOUT); |
| 115 | |
| 116 | if (!inInnerClass && tok->str() == "{" && tok->scope()->isClassOrStruct()) { |
| 117 | // skip returns from local class definition |
| 118 | FwdAnalysis::Result result = checkRecursive(expr, tok, tok->link(), exprVarIds, local, true, depth); |
| 119 | if (result.type != Result::Type::NONE) |
| 120 | return result; |
| 121 | tok=tok->link(); |
| 122 | } |
| 123 | |
| 124 | if (tok->str() == "continue") |
| 125 | // TODO |
| 126 | return Result(Result::Type::BAILOUT); |
| 127 | |
| 128 | if (const Token *lambdaEndToken = findLambdaEndToken(tok)) { |
| 129 | tok = lambdaEndToken; |
| 130 | const Result lambdaResult = checkRecursive(expr, lambdaEndToken->link()->next(), lambdaEndToken, exprVarIds, local, inInnerClass, depth); |
| 131 | if (lambdaResult.type == Result::Type::READ || lambdaResult.type == Result::Type::BAILOUT) |
| 132 | return lambdaResult; |
| 133 | } |
| 134 | |
| 135 | if (Token::Match(tok, "return|throw")) { |
| 136 | // TODO: Handle these better |
| 137 | // Is expr variable used in expression? |
| 138 | |
| 139 | const Token* opTok = tok->astOperand1(); |
| 140 | if (!opTok) |
| 141 | opTok = tok->next(); |
| 142 | std::pair<const Token*, const Token*> startEndTokens = opTok->findExpressionStartEndTokens(); |
| 143 | FwdAnalysis::Result result = |
| 144 | checkRecursive(expr, startEndTokens.first, startEndTokens.second->next(), exprVarIds, local, true, depth); |
| 145 | if (result.type != Result::Type::NONE) |
| 146 | return result; |
| 147 | |
| 148 | // #9167: if the return is inside an inner class, it does not tell us anything |
| 149 | if (!inInnerClass) { |
| 150 | if (!local && mWhat == What::Reassign) |
| 151 | return Result(Result::Type::BAILOUT); |
| 152 | |
| 153 | return Result(Result::Type::RETURN); |
| 154 | } |
nothing calls this directly
no test coverage detected