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

Method ret

lib/checkleakautovar.cpp:1179–1279  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1177}
1178
1179void CheckLeakAutoVarImpl::ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope)
1180{
1181 const std::map<int, VarInfo::AllocInfo> &alloctype = varInfo.alloctype;
1182 const auto& possibleUsage = varInfo.possibleUsage;
1183 std::vector<int> toRemove;
1184
1185 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
1186 for (auto it = alloctype.cbegin(); it != alloctype.cend(); ++it) {
1187 // don't warn if variable is conditionally allocated, unless it leaves the scope
1188 if (!isEndOfScope && !it->second.managed() && varInfo.conditionalAlloc.find(it->first) != varInfo.conditionalAlloc.end())
1189 continue;
1190
1191 // don't warn if there is a reference of the variable
1192 if (varInfo.referenced.find(it->first) != varInfo.referenced.end())
1193 continue;
1194
1195 const int varid = it->first;
1196 const Variable *var = symbolDatabase->getVariableFromVarId(varid);
1197 if (var) {
1198 // don't warn if we leave an inner scope
1199 if (isEndOfScope && var->scope() && tok != var->scope()->bodyEnd)
1200 continue;
1201 enum class PtrUsage : std::uint8_t { NONE, DEREF, PTR } used = PtrUsage::NONE;
1202 for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
1203 if (tok2->str() == ";")
1204 break;
1205 if (!Token::Match(tok2, "return|(|{|,|*"))
1206 continue;
1207
1208 const Token* tok3 = tok2->next();
1209 while (tok3 && tok3->isCast() &&
1210 (!tok3->valueType() ||
1211 tok3->valueType()->pointer ||
1212 isSafeCast(tok3->valueType(), mSettings)))
1213 tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1();
1214 if (tok3 && tok3->varId() == varid)
1215 tok2 = tok3->next();
1216 else if (Token::Match(tok3, "& %varid% . %name%", varid))
1217 tok2 = tok3->tokAt(4);
1218 else if (Token::simpleMatch(tok3, "*") && tok3->next()->varId() == varid)
1219 tok2 = tok3;
1220 else
1221 continue;
1222 if (Token::Match(tok2, "[});,+]") && (!astIsBool(tok) || tok2->str() != ";")) {
1223 used = PtrUsage::PTR;
1224 break;
1225 }
1226 if (Token::Match(tok2, "[|.|*")) {
1227 used = PtrUsage::DEREF;
1228 break;
1229 }
1230 }
1231
1232 // don't warn when returning after checking return value of outparam allocation
1233 const Token* outparamFunc{};
1234 if ((tok->scope()->type == ScopeType::eIf || tok->scope()->type== ScopeType::eElse) &&
1235 (outparamFunc = getOutparamAllocation(it->second.allocTok, mSettings))) {
1236 const Scope* scope = tok->scope();

Callers

nothing calls this directly

Calls 15

isSafeCastFunction · 0.85
astIsBoolFunction · 0.85
getOutparamAllocationFunction · 0.85
precedesFunction · 0.85
succeedsFunction · 0.85
managedMethod · 0.80
scopeMethod · 0.80
nextMethod · 0.80
isCastMethod · 0.80
astOperand2Method · 0.80
astOperand1Method · 0.80
astParentMethod · 0.80

Tested by

no test coverage detected