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

Method checkRecursive

lib/fwdanalysis.cpp:97–411  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

95}
96
97FwdAnalysis::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 }

Callers

nothing calls this directly

Calls 15

precedesFunction · 0.85
findLambdaEndTokenFunction · 0.85
isUnchangedFunction · 0.85
isReturnScopeFunction · 0.85
isSameExpressionFunction · 0.85
hasFunctionCallFunction · 0.85
hasGccCompoundStatementFunction · 0.85
findNextTokenFromBreakFunction · 0.85
nextMethod · 0.80
scopeMethod · 0.80
astOperand1Method · 0.80

Tested by

no test coverage detected