Пример #1
0
        public override CBAProgram runCBAPass(CBAProgram p)
        {
            p.Typecheck();

            p.TopLevelDeclarations.OfType <Procedure>().Iter(proc => procsWithoutBody.Add(proc.Name));
            p.TopLevelDeclarations.OfType <Implementation>().Iter(impl => procsWithoutBody.Remove(impl.Name));

            // remove malloc
            //procsWithoutBody.RemoveWhere(str => str.Contains("malloc"));

            // Make sure that procs without a body don't modify globals
            foreach (var proc in p.TopLevelDeclarations.OfType <Procedure>().Where(proc => procsWithoutBody.Contains(proc.Name)))
            {
                if (proc.Modifies.Count > 0 && !BoogieUtil.checkAttrExists("allocator", proc.Attributes))
                {
                    throw new InvalidInput("Produce Bug Witness: Procedure " + proc.Name + " modifies globals");
                }
            }

            // Add the boogie_si_record_int procedure
            var inpVarInt  = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "x", Microsoft.Boogie.Type.Int), true);
            var inpVarBool = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "x", Microsoft.Boogie.Type.Bool), true);

            var reProcInt = new Procedure(Token.NoToken, recordProcNameInt, new List <TypeVariable>(), new List <Variable> {
                inpVarInt
            }, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
            var reProcBool = new Procedure(Token.NoToken, recordProcNameBool, new List <TypeVariable>(), new List <Variable> {
                inpVarBool
            }, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            // Add procedures for initialization of local variables
            foreach (var impl in p.TopLevelDeclarations.OfType <Implementation>())
            {
                var ncmds = new List <Cmd>();
                foreach (var loc in (impl.LocVars.Concat(impl.OutParams)))
                {
                    var cc = new CallCmd(Token.NoToken, GetInitLocalsProc(loc.TypedIdent.Type).Name, new List <Expr>(), new List <IdentifierExpr>(new IdentifierExpr[] { Expr.Ident(loc) }));
                    cc.Attributes = new QKeyValue(Token.NoToken, RestrictToTrace.ConcretizeConstantNameAttr, new List <object> {
                        LocalVarInitValueAttr
                    }, cc.Attributes);
                    cc.Proc = GetInitLocalsProc(loc.TypedIdent.Type);
                    ncmds.Add(cc);
                }
                ncmds.AddRange(impl.Blocks[0].Cmds);
                impl.Blocks[0].Cmds = ncmds;
            }
            typeToInitLocalsProc.Values.Iter(pr => procsWithoutBody.Add(pr.Name));
            typeToInitLocalsProc.Values.Iter(pr => p.AddTopLevelDeclaration(pr));

            // save the current program
            var fd         = new FixedDuplicator(true);
            var modInpProg = fd.VisitProgram(p);

            // Instrument to record stuff
            p.TopLevelDeclarations.OfType <Implementation>().Iter(impl =>
                                                                  impl.Blocks.Iter(b => instrument(b)));

            // Name clash if this assert fails
            Debug.Assert(BoogieUtil.findProcedureDecl(p.TopLevelDeclarations, recordProcNameInt) == null);
            Debug.Assert(BoogieUtil.findProcedureDecl(p.TopLevelDeclarations, recordProcNameBool) == null);
            foreach (var rp in typeToRecordProc.Values)
            {
                Debug.Assert(BoogieUtil.findProcedureDecl(p.TopLevelDeclarations, rp.Name) == null);
            }

            p.AddTopLevelDeclaration(reProcInt);
            p.AddTopLevelDeclaration(reProcBool);
            p.AddTopLevelDeclarations(typeToRecordProc.Values);

            var tmainimpl = BoogieUtil.findProcedureImpl(p.TopLevelDeclarations, p.mainProcName);

            if (!QKeyValue.FindBoolAttribute(tmainimpl.Attributes, "entrypoint"))
            {
                tmainimpl.AddAttribute("entrypoint");
            }

            var program = new PersistentCBAProgram(p, p.mainProcName, 0);
            //program.writeToFile("beforeverify.bpl");
            var vp = new VerificationPass(true);

            vp.run(program);

            success = vp.success;
            if (success)
            {
                return(null);
            }

            var trace = mapBackTraceRecord(vp.trace);

            RestrictToTrace.addConcretization            = true;
            RestrictToTrace.addConcretizationAsConstants = true;
            var tinfo = new InsertionTrans();
            var rt    = new RestrictToTrace(modInpProg, tinfo);

            rt.addTrace(trace);
            RestrictToTrace.addConcretization            = false;
            RestrictToTrace.addConcretizationAsConstants = false;

            var rtprog = rt.getProgram();

            // Build a map of where the alloc constants are from
            allocConstants = rt.concretizeConstantToCall;

            // Add symbolic constants for angelic map havocs
            var newDecls = new List <Constant>();

            rtprog.TopLevelDeclarations.OfType <Implementation>().Iter(impl =>
                                                                       impl.Blocks.Iter(b => instrumentMapHavocs(b, allocConstants, newDecls)));
            rtprog.AddTopLevelDeclarations(newDecls);

            /*
             * foreach (var impl in rtprog.TopLevelDeclarations.OfType<Implementation>())
             * {
             *  // strip _trace from the impl name
             *  var implName = impl.Name;
             *  var c = implName.LastIndexOf("_trace");
             *  while (c != -1)
             *  {
             *      implName = implName.Substring(0, c);
             *      c = implName.LastIndexOf("_trace");
             *  }
             *
             *  var vu = new VarsUsed();
             *  vu.VisitImplementation(impl);
             *  vu.varsUsed.Where(s => s.StartsWith("alloc_"))
             *      .Iter(s => allocConstants[s] = implName);
             * }
             */
            BoogieUtil.findProcedureImpl(rtprog.TopLevelDeclarations, rt.getFirstNameInstance(p.mainProcName))
            .AddAttribute("entrypoint");

            program = new PersistentCBAProgram(rtprog, rt.getFirstNameInstance(p.mainProcName), p.contextBound);

            // Lets inline it all
            var inlp = new InliningPass(1);

            program = inlp.run(program);

            var compress = new CompressBlocks();
            var ret      = program.getProgram();

            compress.VisitProgram(ret);


            return(new CBAProgram(ret, program.mainProcName, 0));
        }
Пример #2
0
        public RHS(CBAProgram program, IWeight iw)
        {
            this.iw      = iw;
            this.program = program;
            intraGraphs  = new List <IntraGraph>();
            id2Graph     = new Dictionary <string, IntraGraph>();
            Succ         = new Dictionary <string, HashSet <IntraGraph> >();
            Pred         = new Dictionary <string, HashSet <IntraGraph> >();
            computeTime  = TimeSpan.Zero;

            // Make all the graphs
            program.TopLevelDeclarations
            .OfType <Implementation>()
            .Iter(impl => intraGraphs.Add(
                      new IntraGraph(impl, iw, p =>
            {
                if (!id2Graph.ContainsKey(p))
                {
                    return(null);
                }
                else
                {
                    return(id2Graph[p].summary);
                }
            }
                                     )));

            intraGraphs.Iter(g => id2Graph.Add(g.Id, g));

            intraGraphs.Iter(g =>
            {
                Succ.Add(g.Id, new HashSet <IntraGraph>());
                Pred.Add(g.Id, new HashSet <IntraGraph>());
            });

            intraGraphs.Iter(g =>
                             g.Callees
                             .Where(s => id2Graph.ContainsKey(s))
                             .Iter(s =>
            {
                Succ[g.Id].Add(id2Graph[s]);
                Pred[s].Add(g);
            }
                                   ));

            // assign priorities
            var sccs = new StronglyConnectedComponents <IntraGraph>(
                intraGraphs,
                new Adjacency <IntraGraph>(g => Succ[g.Id]),
                new Adjacency <IntraGraph>(g => Pred[g.Id]));

            sccs.Compute();

            var priority = intraGraphs.Count;

            foreach (var scc in sccs)
            {
                /*
                 * if (scc.Count > 1)
                 * {
                 *  Console.WriteLine("SCC size: {0}", scc.Count);
                 *  scc.Iter(g => Console.WriteLine("{0}", g.Id));
                 * }
                 */
                scc.Iter(g => g.priority = priority);
                priority--;
            }
        }