Example #1
0
        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);
        }