--------------------------------------------------------------------------- Checks if a call to an allocation function like malloc() is made and its return value is not assigned. ---------------------------------------------------------------------------
| 1082 | // Checks if a call to an allocation function like malloc() is made and its return value is not assigned. |
| 1083 | //--------------------------------------------------------------------------- |
| 1084 | void CheckMemoryLeakNoVarImpl::checkForUnusedReturnValue(const Scope *scope) |
| 1085 | { |
| 1086 | for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { |
| 1087 | const bool isNew = tok->isCpp() && tok->str() == "new"; |
| 1088 | if (!isNew && !Token::Match(tok, "%name% (")) |
| 1089 | continue; |
| 1090 | |
| 1091 | if (tok->varId()) |
| 1092 | continue; |
| 1093 | |
| 1094 | const AllocType allocType = getAllocationType(tok, 0); |
| 1095 | if (allocType == No) |
| 1096 | continue; |
| 1097 | |
| 1098 | const Token* ftok = tok->next()->astOperand1(); |
| 1099 | while (Token::simpleMatch(ftok, "::")) |
| 1100 | ftok = ftok->astOperand2() ? ftok->astOperand2() : ftok->astOperand1(); |
| 1101 | if (tok != ftok && !isNew) |
| 1102 | continue; |
| 1103 | |
| 1104 | if (isReopenStandardStream(tok)) |
| 1105 | continue; |
| 1106 | if (isOpenDevNull(tok)) |
| 1107 | continue; |
| 1108 | |
| 1109 | // get ast parent, skip casts |
| 1110 | const Token *parent = isNew ? tok->astParent() : tok->next()->astParent(); |
| 1111 | while (parent && parent->isCast()) |
| 1112 | parent = parent->astParent(); |
| 1113 | |
| 1114 | bool warn = true; |
| 1115 | if (isNew) { |
| 1116 | const Token* typeTok = tok->next(); |
| 1117 | warn = typeTok && (typeTok->isStandardType() || mSettings.library.detectContainer(typeTok)); |
| 1118 | } |
| 1119 | |
| 1120 | if (!parent && warn) { |
| 1121 | // Check if we are in a C++11 constructor |
| 1122 | const Token * closingBrace = Token::findmatch(tok, "}|;"); |
| 1123 | if (closingBrace->str() == "}" && Token::Match(closingBrace->link()->tokAt(-1), "%name%") && (!isNew && precedes(tok, closingBrace->link()))) |
| 1124 | continue; |
| 1125 | returnValueNotUsedError(tok, tok->str()); |
| 1126 | } else if (Token::Match(parent, "%comp%|!|,|%oror%|&&|:")) { |
| 1127 | if (parent->astParent() && parent->str() == ",") |
| 1128 | continue; |
| 1129 | if (parent->str() == ":") { |
| 1130 | if (!(Token::simpleMatch(parent->astParent(), "?") && !parent->astParent()->astParent())) |
| 1131 | continue; |
| 1132 | } |
| 1133 | if (tok->str() == "freopen") |
| 1134 | continue; |
| 1135 | returnValueNotUsedError(tok, tok->str()); |
| 1136 | } |
| 1137 | } |
| 1138 | } |
| 1139 | |
| 1140 | //--------------------------------------------------------------------------- |
| 1141 | // Check if an exception could cause a leak in an argument constructed with |
nothing calls this directly
no test coverage detected