public void RedirectPredecessors() { if (this.Parent.Entry == OriginalCFGConstruct) { this.Parent.Entry = this; } foreach (CFGBlockLogicalConstruct predecessor in OriginalCFGConstruct.CFGPredecessors) { predecessor.RemoveFromSuccessors(OriginalCFGConstruct); predecessor.AddToSuccessors(this); this.AddToPredecessors(predecessor); LogicalConstructBase currentPredecessorParent = predecessor.Parent as LogicalConstructBase; while (currentPredecessorParent != null) { if (currentPredecessorParent.RemoveFromSuccessors(OriginalCFGConstruct)) { currentPredecessorParent.AddToSuccessors(this); } currentPredecessorParent = currentPredecessorParent.Parent as LogicalConstructBase; } } }
/// <summary> /// Redirect the predecessors and successors of the finally block. /// </summary> /// <remarks> /// Check if the finallyBlockEntry is only reachable by nodes in the try block. /// Make the successor of the finallyBlockEnd successor to all of the predecessors of the finallyBlockEntry. /// This will detach the finally block from the subgraph, which is a desired result since every normal finally block is not reachable from any where /// (the CLR takes care of executing the code in the finally block). /// </remarks> /// <param name="finallyBlockEntry"></param> /// <param name="finallyBlockEnd"></param> /// <returns>The successor of the finally block.</returns> private CFGBlockLogicalConstruct ProcessFinallyNode(CFGBlockLogicalConstruct finallyBlockEntry, CFGBlockLogicalConstruct finallyBlockEnd) { foreach (ILogicalConstruct predecessor in finallyBlockEntry.SameParentPredecessors) { if (!newTryBody.Contains(predecessor)) { throw new Exception("Invalid entry to the finally block"); } } CFGBlockLogicalConstruct finallySuccessor; using (IEnumerator <CFGBlockLogicalConstruct> enumerator = finallyBlockEnd.CFGSuccessors.GetEnumerator()) { enumerator.MoveNext(); finallySuccessor = enumerator.Current; if (enumerator.MoveNext()) { throw new Exception("Invalid count of successors"); } } HashSet <CFGBlockLogicalConstruct> finallyCFGPredecessors = new HashSet <CFGBlockLogicalConstruct>(finallyBlockEntry.CFGPredecessors); foreach (CFGBlockLogicalConstruct cfgPredecessor in finallyCFGPredecessors) { if (cfgPredecessor.TheBlock != finallyBlockEntry.TheBlock && cfgPredecessor.TheBlock.Successors.Length > 1) { ProcessMultiWayCFGPredecessor(finallyBlockEntry, cfgPredecessor.TheBlock, finallySuccessor.TheBlock); } LogicalConstructBase currenConstruct = cfgPredecessor; while (currenConstruct != finallyBlockEntry.Parent) { currenConstruct.RemoveFromSuccessors(finallyBlockEntry); currenConstruct.AddToSuccessors(finallySuccessor); currenConstruct = currenConstruct.Parent as LogicalConstructBase; } finallySuccessor.AddToPredecessors(cfgPredecessor); finallyBlockEntry.RemoveFromPredecessors(cfgPredecessor); } finallySuccessor.RemoveFromPredecessors(finallyBlockEnd); finallyBlockEnd.RemoveFromSuccessors(finallySuccessor); return(finallySuccessor); }