Beispiel #1
0
        private void Propagate(CFGNode node, PathEdges pathEdge, LinkedList <CFGNode> workList)
        {
            PathEdges nodePaths;

            m_PathEdges.TryGetValue(node, out nodePaths);

            if (pathEdge != null)
            {
                List <PathEdgesPartition> newPaths = pathEdge.PathEdgesByLength;

                int index = 0;

                bool updated = false;
                while (index < newPaths.Count)
                {
                    if (nodePaths.AddPathEdge(newPaths[index], m_BddManager))
                    {
                        updated = true;
                        newPaths[index].PathEdges.UnfreeBdd();
                    }

                    index++;
                }

                if (updated)
                {
                    workList.AddLast(node);
                }
            }
        }
Beispiel #2
0
        private PathEdges Join(PathEdges pathEdge, Bdd TransitionBdd, Variables localVariables)
        {
            PathEdges tempPathEdge = new PathEdges();

            List <PathEdgesPartition> Partitions = pathEdge.PathEdgesByLength;

            foreach (PathEdgesPartition part in Partitions)
            {
                Bdd tempBdd = Join(part.PathEdges, TransitionBdd, localVariables);

                tempPathEdge.AddPathEdge(new PathEdgesPartition(part.Length + 1, tempBdd), m_BddManager);

                // tempBdd.FreeBdd();
            }

            return(tempPathEdge);
        }
Beispiel #3
0
        private PathEdges SelfLoop(PathEdges pathEdge, Variables localVariables1, Variables localVariables2)
        {
            List <PathEdgesPartition> Partitions = pathEdge.PathEdgesByLength;
            PathEdges tempPathEdge = new PathEdges();

            //Bdd tempBdd;

            foreach (PathEdgesPartition part in Partitions)
            {
                //tempBdd = part.PathEdges;

                //part.PathEdges = SelfLoop(tempBdd, localVariables1, localVariables2);

                //tempBdd.FreeBdd();
                tempPathEdge.AddPathEdge(new PathEdgesPartition(part.Length, SelfLoop(part.PathEdges, localVariables1, localVariables2)), m_BddManager);
            }

            //return pathEdge;
            return(tempPathEdge);
        }
Beispiel #4
0
        public void Reachable(debugPrintDelegate debugPrint)
        {
            if (ProgramCFG.CfgNodes.Count <= 1)
            {
                debugPrint("Invalid Program, unable to proceed!\n");
                return;
            }

            m_PathEdges.Clear();
            m_SummaryEdges.Clear();

            BuildTransferFunctions();

            LinkedList <CFGNode> workList = new LinkedList <CFGNode>();

            CFGNodeProcedure tempNodeProc;
            CFGNode          tempNode;

            Bdd       bddLift, bddSummaryEdges, bddNew;
            PathEdges bddSelfLoop, bddJoin, bddPathEdges;

            Bdd [] array = new Bdd[3];

            foreach (CFGNode node in ProgramCFG.CfgNodes)
            {
                m_PathEdges.Add(node, new PathEdges());
                m_SummaryEdges.Add(node, m_BddManager.CreateBddZero());
            }


            ProgramCFG.ProcedureNameToNode().TryGetValue("main", out tempNodeProc);
            workList.AddFirst(tempNodeProc.FirstStmtOf);
            m_PathEdges.Remove(tempNodeProc.FirstStmtOf);
            PathEdges firstMain = new PathEdges();

            firstMain.AddPathEdge(new PathEdgesPartition(0, HelperFunctions.BuildIdentityTransfer
                                                             (m_BddManager, tempNodeProc.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId)), m_BddManager);
            m_PathEdges.Add(tempNodeProc.FirstStmtOf, firstMain);

            #region Debug part of the reachability algorithm

            /*
             * ///////Debug ////////////
             * Dictionary<string, int>.ValueCollection valCollection = tempNodeProc.LocalVariables.VariablesToId.Values;
             * foreach (int id in valCollection)
             * {
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalOr(tempBdd, m_BddManager.GetBddVariableWithID(id));
             *  tempBdd1.FreeBdd();
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalXnor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2));
             *  tempBdd1.FreeBdd();
             * }
             *
             * foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values)
             * {
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalImplies(tempBdd, m_BddManager.GetBddVariableWithID(id));
             *  tempBdd1.FreeBdd();
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalOr(tempBdd, m_BddManager.GetBddVariableWithID(id + 2));
             *  tempBdd1.FreeBdd();
             * }
             * array[0] = tempBdd;
             * tempBdd = m_BddManager.CreateBddOne();
             *
             * foreach (int id in valCollection)
             * {
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalAnd(tempBdd, m_BddManager.GetBddVariableWithID(id));
             *  tempBdd1.FreeBdd();
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalNor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2));
             *  tempBdd1.FreeBdd();
             * }
             *
             * foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values)
             * {
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalImplies(tempBdd, m_BddManager.GetBddVariableWithID(id));
             *  tempBdd1.FreeBdd();
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalXor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2));
             *  tempBdd1.FreeBdd();
             * }
             * array[1] = tempBdd;
             *
             * //array[2] = Join(array[0], array[1], tempNodeProc.LocalVariables);
             * array[2] = SelfLoop(array[1], tempNodeProc.LocalVariables, tempNodeProc.LocalVariables);
             * m_BddManager.ForceGarbageCollection();
             * return array;
             * ////////////////////////
             */
            #endregion
            while (workList.Count != 0)
            {
                tempNode = workList.First.Value;

                debugPrint("Processing Node: " + tempNode.ToString() + ".\n");

                workList.RemoveFirst();

                if (tempNode is CFGNodeStmtProcCall)
                {
                    CFGNodeStmtProcCall procCall = tempNode as CFGNodeStmtProcCall;
                    m_PathEdges.TryGetValue(tempNode, out bddPathEdges);

                    bddJoin     = Join(bddPathEdges, procCall.Transfer, procCall.ProcOf.LocalVariables);
                    bddSelfLoop = SelfLoop(bddJoin, procCall.ProcOf.LocalVariables, (procCall.Succesor as CFGNodeStatement).ProcOf.LocalVariables);
                    Propagate(procCall.Succesor, bddSelfLoop, workList);

                    bddJoin.FreeAllBdd();
                    bddSelfLoop.FreeAllBdd();

                    m_PathEdges.TryGetValue(tempNode, out bddPathEdges);
                    m_SummaryEdges.TryGetValue(tempNode, out bddSummaryEdges);
                    if (bddSummaryEdges != null)
                    {
                        bddJoin = Join(bddPathEdges, bddSummaryEdges, procCall.ProcOf.LocalVariables);
                        Propagate(procCall.ReturnPoint, bddJoin, workList);
                        bddJoin.FreeAllBdd();
                    }
                }
                else if (tempNode is CFGNodeProcedure)
                {
                    foreach (CFGNodeStmtSkip node in (tempNode as CFGNodeProcedure).Succesor)
                    {
                        bddLift = Lift(node.previousProcCall, tempNode as CFGNodeProcedure);

                        m_SummaryEdges.TryGetValue(node.previousProcCall, out bddSummaryEdges);
                        m_PathEdges.TryGetValue(node.previousProcCall, out bddPathEdges);

                        if (bddSummaryEdges != null)
                        {
                            bddNew = m_BddManager.LogicalOr(bddLift, bddSummaryEdges);
                            bddLift.FreeBdd();
                        }
                        else
                        {
                            bddNew = bddLift;
                        }

                        if (bddSummaryEdges != bddNew)
                        {
                            m_SummaryEdges.Remove(node.previousProcCall);
                            m_SummaryEdges.Add(node.previousProcCall, bddNew);
                            bddSummaryEdges.FreeBdd();

                            bddJoin = Join(bddPathEdges, bddNew, (node as CFGNodeStmtSkip).previousProcCall.ProcOf.LocalVariables);

                            Propagate(node, bddJoin, workList);
                            bddJoin.FreeAllBdd();
                        }
                    }
                }
                else if (tempNode is CFGNodeStmtConditional)
                {
                    CFGNodeStmtConditional tempNode1 = tempNode as CFGNodeStmtConditional;

                    m_PathEdges.TryGetValue(tempNode, out bddPathEdges);
                    bddJoin = Join(bddPathEdges, tempNode1.TransferTrue, tempNode1.ProcOf.LocalVariables);
                    Propagate(tempNode1.TrueSuccesor, bddJoin, workList);
                    bddJoin.FreeAllBdd();

                    m_PathEdges.TryGetValue(tempNode, out bddPathEdges);
                    bddJoin = Join(bddPathEdges, tempNode1.TransferFalse, tempNode1.ProcOf.LocalVariables);
                    Propagate(tempNode1.FalseSuccesor, bddJoin, workList);
                    bddJoin.FreeAllBdd();
                }
                else
                {
                    if (!(tempNode is CFGNodeError))
                    {
                        m_PathEdges.TryGetValue(tempNode, out bddPathEdges);
                        bddJoin = Join(bddPathEdges, (tempNode as CFGNodeStatement).Transfer, (tempNode as CFGNodeStatement).ProcOf.LocalVariables);
                        Propagate(tempNode.Succesor, bddJoin, workList);
                        bddJoin.FreeAllBdd();
                    }
                }
            }

            m_BddManager.ForceGarbageCollection();
        }