* remove a statement from this block. this may trigger other events: deleting it from * break_stms, deleting CFG edges linked to it, etc */
| 652 | * break_stms, deleting CFG edges linked to it, etc |
| 653 | */ |
| 654 | size_t |
| 655 | Block::remove_stmt(const Statement* s) |
| 656 | { |
| 657 | int i, len, cnt; |
| 658 | cnt = 0; |
| 659 | assert(func); |
| 660 | FactMgr* fm = get_fact_mgr_for_func(func); |
| 661 | vector<const Statement*> cfg_stms; |
| 662 | vector<int> types; |
| 663 | types.push_back(eContinue); |
| 664 | types.push_back(eBreak); |
| 665 | types.push_back(eGoto); |
| 666 | //if (func->name == "func_109") |
| 667 | // s->Output(cout, fm); |
| 668 | if (s->find_typed_stmts(cfg_stms, types)) { |
| 669 | // remove from the break_stms list if it is or contains a break |
| 670 | Block* b; |
| 671 | for (b = this; b && !b->looping; b = b->parent) { |
| 672 | /* Empty. */ |
| 673 | } |
| 674 | if (b != 0) { |
| 675 | len = b->break_stms.size(); |
| 676 | for (i=0; i<len; i++) { |
| 677 | if (find_stm_in_set(cfg_stms, b->break_stms[i]) >= 0) { |
| 678 | b->break_stms.erase(b->break_stms.begin() + i); |
| 679 | i--; |
| 680 | len--; |
| 681 | } |
| 682 | } |
| 683 | } |
| 684 | // remove any CFG edges that has s (or flow-control statements inside s) as src |
| 685 | len = fm->cfg_edges.size(); |
| 686 | for (i=0; i<len; i++) { |
| 687 | const CFGEdge* edge = fm->cfg_edges[i]; |
| 688 | if (find_stm_in_set(cfg_stms, edge->src) >= 0) { |
| 689 | fm->cfg_edges.erase(fm->cfg_edges.begin() + i); |
| 690 | delete edge; |
| 691 | i--; |
| 692 | len--; |
| 693 | } |
| 694 | } |
| 695 | } |
| 696 | |
| 697 | // remove any CFG edges that has s (or statements inside s) as dest |
| 698 | len = fm->cfg_edges.size(); |
| 699 | for (i=0; i<len; i++) { |
| 700 | const CFGEdge* edge = fm->cfg_edges[i]; |
| 701 | const Statement* src = edge->src; |
| 702 | if (s->contains_stmt(edge->dest)) { |
| 703 | fm->cfg_edges.erase(fm->cfg_edges.begin() + i); |
| 704 | delete edge; |
| 705 | i--; |
| 706 | len--; |
| 707 | // delete the source statement (most likely goto) as well |
| 708 | if (src->eType == eGoto) { |
| 709 | int deleted = src->parent->remove_stmt(src); |
| 710 | if (src->parent == this) { |
| 711 | cnt += deleted; |
nothing calls this directly
no test coverage detected