// 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); }
// 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); }
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); }
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)); }
// 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); }