| 534 | |
| 535 | |
| 536 | void CheckMemoryLeakInClassImpl::variable(const Scope *scope, const Token *tokVarname) |
| 537 | { |
| 538 | const std::string& varname = tokVarname->str(); |
| 539 | const int varid = tokVarname->varId(); |
| 540 | const std::string& classname = scope->className; |
| 541 | |
| 542 | // Check if member variable has been allocated and deallocated.. |
| 543 | AllocType memberAlloc = AllocType::No; |
| 544 | AllocType memberDealloc = AllocType::No; |
| 545 | |
| 546 | bool allocInConstructor = false; |
| 547 | bool deallocInDestructor = false; |
| 548 | |
| 549 | // Inspect member functions |
| 550 | for (const Function &func : scope->functionList) { |
| 551 | const bool constructor = func.isConstructor(); |
| 552 | const bool destructor = func.isDestructor(); |
| 553 | if (!func.hasBody()) { |
| 554 | if (destructor && !func.isDefault()) { // implementation for destructor is not seen and not defaulted => assume it deallocates all variables properly |
| 555 | deallocInDestructor = true; |
| 556 | memberDealloc = AllocType::Many; |
| 557 | } |
| 558 | continue; |
| 559 | } |
| 560 | bool body = false; |
| 561 | const Token *end = func.functionScope->bodyEnd; |
| 562 | for (const Token *tok = func.arg->link(); tok != end; tok = tok->next()) { |
| 563 | if (tok == func.functionScope->bodyStart) |
| 564 | body = true; |
| 565 | else { |
| 566 | if (!body) { |
| 567 | if (!Token::Match(tok, ":|, %varid% (", varid)) |
| 568 | continue; |
| 569 | } |
| 570 | |
| 571 | // Allocate.. |
| 572 | if (!body || Token::Match(tok, "%varid% =|[", varid)) { |
| 573 | // var1 = var2 = ... |
| 574 | // bail out |
| 575 | if (tok->strAt(-1) == "=") |
| 576 | return; |
| 577 | |
| 578 | // Foo::var1 = .. |
| 579 | // bail out when not same class |
| 580 | if (tok->strAt(-1) == "::" && |
| 581 | tok->strAt(-2) != scope->className) |
| 582 | return; |
| 583 | |
| 584 | const Token* allocTok = tok->tokAt(body ? 2 : 3); |
| 585 | if (tok->astParent() && tok->astParent()->str() == "[" && tok->astParent()->astParent()) |
| 586 | allocTok = tok->astParent()->astParent()->astOperand2(); |
| 587 | |
| 588 | AllocType alloc = getAllocationType(allocTok, 0); |
| 589 | if (alloc != AllocType::No) { |
| 590 | if (constructor) |
| 591 | allocInConstructor = true; |
| 592 | |
| 593 | if (memberAlloc != AllocType::No && memberAlloc != alloc) |