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

Method checkForUnsafeArgAlloc

lib/checkmemoryleak.cpp:1151–1199  ·  view source on GitHub ↗

--------------------------------------------------------------------------- Check if an exception could cause a leak in an argument constructed with shared_ptr/unique_ptr. For example, in the following code, it is possible that if g() throws an exception, the memory allocated by "new int(42)" could be leaked. See stackoverflow.com/questions/19034538/ why-is-there-memory-leak-while-using-shared-ptr

Source from the content-addressed store, hash-verified

1149// }
1150//---------------------------------------------------------------------------
1151void CheckMemoryLeakNoVarImpl::checkForUnsafeArgAlloc(const Scope *scope)
1152{
1153 // This test only applies to C++ source
1154 if (!mTokenizer->isCPP())
1155 return;
1156
1157 if (!mSettings.isPremiumEnabled("leakUnsafeArgAlloc") && (!mSettings.certainty.isEnabled(Certainty::inconclusive) || !mSettings.severity.isEnabled(Severity::warning)))
1158 return;
1159
1160 logChecker("CheckMemoryLeakNoVar::checkForUnsafeArgAlloc");
1161
1162 for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
1163 if (Token::Match(tok, "%name% (")) {
1164 const Token *endParamToken = tok->linkAt(1);
1165 const Token* pointerType = nullptr;
1166 const Token* functionCalled = nullptr;
1167
1168 // Scan through the arguments to the function call
1169 for (const Token *tok2 = tok->tokAt(2); tok2 && tok2 != endParamToken; tok2 = tok2->nextArgument()) {
1170 const Function *func = tok2->function();
1171 const bool isNothrow = func && (func->isAttributeNothrow() || func->isThrow());
1172
1173 if (Token::Match(tok2, "shared_ptr|unique_ptr <") && Token::Match(tok2->linkAt(1), "> ( new %name%")) {
1174 pointerType = tok2;
1175 } else if (!isNothrow) {
1176 if (Token::Match(tok2, "%name% ("))
1177 functionCalled = tok2;
1178 else if (tok2->isName() && Token::simpleMatch(tok2->linkAt(1), "> ("))
1179 functionCalled = tok2;
1180 }
1181 }
1182
1183 if (pointerType && functionCalled) {
1184 std::string functionName = functionCalled->str();
1185 if (functionCalled->strAt(1) == "<") {
1186 functionName += '<';
1187 for (const Token* tok2 = functionCalled->tokAt(2); tok2 != functionCalled->linkAt(1); tok2 = tok2->next())
1188 functionName += tok2->str();
1189 functionName += '>';
1190 }
1191 std::string objectTypeName;
1192 for (const Token* tok2 = pointerType->tokAt(2); tok2 != pointerType->linkAt(1); tok2 = tok2->next())
1193 objectTypeName += tok2->str();
1194
1195 unsafeArgAllocError(tok, functionName, pointerType->str(), objectTypeName);
1196 }
1197 }
1198 }
1199}
1200
1201void CheckMemoryLeakNoVarImpl::functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall)
1202{

Callers

nothing calls this directly

Calls 10

isCPPMethod · 0.80
isPremiumEnabledMethod · 0.80
nextMethod · 0.80
linkAtMethod · 0.80
simpleMatchFunction · 0.70
isEnabledMethod · 0.45
tokAtMethod · 0.45
nextArgumentMethod · 0.45
functionMethod · 0.45
strMethod · 0.45

Tested by

no test coverage detected