| 145 | |
| 146 | |
| 147 | CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getReallocationType(const Token *tok2, nonneg int varid) const |
| 148 | { |
| 149 | // What we may have... |
| 150 | // * var = (char *)realloc(..; |
| 151 | if (tok2 && tok2->str() == "(") { |
| 152 | tok2 = tok2->link(); |
| 153 | tok2 = tok2 ? tok2->next() : nullptr; |
| 154 | } |
| 155 | if (!tok2) |
| 156 | return No; |
| 157 | |
| 158 | if (!Token::Match(tok2, "%name% (")) |
| 159 | return No; |
| 160 | |
| 161 | const Library::AllocFunc *f = mSettings.library.getReallocFuncInfo(tok2); |
| 162 | if (!(f && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(tok2))) |
| 163 | return No; |
| 164 | const auto args = getArguments(tok2); |
| 165 | if (args.size() < (f->reallocArg)) |
| 166 | return No; |
| 167 | const Token* arg = args.at(f->reallocArg - 1); |
| 168 | while (arg && arg->isCast()) |
| 169 | arg = arg->astOperand1(); |
| 170 | while (arg && arg->isUnaryOp("*")) |
| 171 | arg = arg->astOperand1(); |
| 172 | if (varid > 0 && !Token::Match(arg, "%varid% [,)]", varid)) |
| 173 | return No; |
| 174 | |
| 175 | const int realloctype = mSettings.library.getReallocId(tok2, -1); |
| 176 | if (realloctype > 0) { |
| 177 | if (realloctype == mSettings.library.deallocId("free")) |
| 178 | return Malloc; |
| 179 | if (realloctype == mSettings.library.deallocId("fclose")) |
| 180 | return File; |
| 181 | return Library::ismemory(realloctype) ? OtherMem : OtherRes; |
| 182 | } |
| 183 | return No; |
| 184 | } |
| 185 | |
| 186 | |
| 187 | CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getDeallocationType(const Token *tok, nonneg int varid) const |
nothing calls this directly
no test coverage detected