Beispiel #1
0
        // Return a new copy of the program
        public override Program getProgram()
        {
            var     startTime = DateTime.Now;
            Program ret;

            if (unresolved_program != null)
            {
                FixedDuplicator dup = new FixedDuplicator();
                ret = dup.VisitProgram(unresolved_program);
            }
            else
            {
                var progStr = "";
                if (programStream is FileStream || programStream is MemoryStream)
                {
                    var stream = programStream as Stream;
                    stream.Seek(0, SeekOrigin.Begin);
                    progStr = ParserHelper.Fill(stream, new List <string>());
                }
                else
                {
                    Debug.Assert(programStream is string);
                    progStr = (string)programStream;
                }

                var v = Parser.Parse(progStr, "PersistentProgram", out ret);

                if (v != 0)
                {
                    writeToFile("error.bpl");
                    throw new InternalError("Illegal program given to PersistentProgram");
                }

                if (PersistentProgram.clearTokens)
                {
                    PersistentProgram.ClearTokens(ret);
                }

                // TODO: use this always (sometimes .NET-2-Boogie programs crash)
                if (useDuplicator)
                {
                    FixedDuplicator dup = new FixedDuplicator();
                    unresolved_program = dup.VisitProgram(ret);
                }
            }

            if (ret.Resolve() != 0)
            {
                writeToFile("error.bpl");
                throw new InternalError("Illegal program given to PersistentProgram");
            }

            persistenceCost += (DateTime.Now - startTime);
            return(ret);
        }
Beispiel #2
0
        // Return a new copy of the program
        public override Program getProgram()
        {
            var startTime = DateTime.Now;

            FixedDuplicator dup = new FixedDuplicator();
            Program         ret = dup.VisitProgram(program);

            if (ret.Resolve() != 0 || ret.Typecheck() != 0)
            {
                BoogieUtil.PrintProgram(ret, "error.bpl");
                throw new InternalError("Illegal program given to PersistentProgram");
            }

            persistenceCost += (DateTime.Now - startTime);
            return(ret);
        }
Beispiel #3
0
        private void readInProgram(Program p)
        {
            var startTime = DateTime.Now;

            // Make a copy of p into the persistent storage
            FixedDuplicator dup = new FixedDuplicator();

            program = dup.VisitProgram(p);

            // Unresolve the program to break any pointer links
            var unresolver = new UnResolver();

            unresolver.VisitProgram(program);

            persistenceCost += (DateTime.Now - startTime);
        }
Beispiel #4
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));
        }
Beispiel #5
0
        // Split on the postconditions of procedure "proc"
        // 1. only retain its postconditions; make everything else as assumes
        // 2. drop the implementation of the procedure
        // 3. convert calls to itself to calls to a fake procedure with assumed postconditions
        static Program SplitOnProcedure(Program program, string proc)
        {
            var dup = new FixedDuplicator();

            program = dup.VisitProgram(program);
            program = BoogieUtil.ReResolveInMem(program, true);

            var            toremove = new HashSet <Implementation>();
            Implementation procimpl = null;

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                if (impl.Name == proc)
                {
                    procimpl = impl;
                    continue;
                }

                if (impl.Proc.Ensures.All(ens => ens.Free))
                {
                    continue;
                }

                var newens = new List <Ensures>();
                impl.Proc.Ensures.Iter(ens => newens.Add(new Ensures(ens.tok, true, ens.Condition, ens.Comment)));
                impl.Proc.Ensures = newens;
                toremove.Add(impl);
            }

            program.RemoveTopLevelDeclarations(decl => decl is Implementation && toremove.Contains(decl));

            if (procimpl != null)
            {
                // create copy
                var proccopy = dup.VisitProcedure(procimpl.Proc);
                proccopy.Name += "_dup";

                // make assumes
                var newens = new List <Ensures>();
                proccopy.Ensures.Iter(ens => newens.Add(new Ensures(ens.tok, true, ens.Condition, ens.Comment)));
                proccopy.Ensures = newens;

                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    foreach (var blk in impl.Blocks)
                    {
                        for (int i = 0; i < blk.Cmds.Count; i++)
                        {
                            var ccmd = blk.Cmds[i] as CallCmd;
                            if (ccmd == null || ccmd.callee != procimpl.Name)
                            {
                                continue;
                            }
                            blk.Cmds[i] = new CallCmd(ccmd.tok, proccopy.Name, ccmd.Ins, ccmd.Outs, ccmd.Attributes);
                        }
                    }
                }

                program.AddTopLevelDeclaration(proccopy);
            }

            return(program);
        }