static Program Process(Program program) { // find null var nil = program.TopLevelDeclarations.OfType <Constant>().Where(g => g.Name == "null").FirstOrDefault(); if (nil == null) { Console.WriteLine("Error: null not found in the input program"); return(null); } // Add Freed: [Ref] bool; Freed = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "FreedRef", new MapType(Token.NoToken, new List <TypeVariable>(), new List <btype> { nil.TypedIdent.Type }, btype.Bool))); program.AddTopLevelDeclaration(Freed); // Find "Alloc" and add "assume !Freed[x];" var allocProc = program.TopLevelDeclarations.OfType <Implementation>() .Where(impl => impl.Name == "Alloc") .FirstOrDefault(); Alloc = program.TopLevelDeclarations.OfType <GlobalVariable>() .Where(impl => impl.Name == "$Alloc") .FirstOrDefault(); if (allocProc == null || Alloc == null) { Console.WriteLine("Error: Alloc procedure not found in the input program"); return(null); } var x = allocProc.OutParams[0]; allocProc.Blocks[0].Cmds.Add(new AssumeCmd(Token.NoToken, Expr.Not(BoogieAstFactory.MkMapAccessExpr(Freed, Expr.Ident(x))))); // Find System.Heap.Delete, add Freed[x] := true var freeProcs = program.TopLevelDeclarations.OfType <Implementation>() .Where(impl => impl.Name.StartsWith("System.Heap.Delete")).ToList(); if (freeProcs.Count != 1) { Console.WriteLine("Error: Free procedure not found, or multiple found in the input program"); return(null); } x = freeProcs[0].InParams[0]; freeProcs[0].Blocks[0].Cmds.Insert(0, BoogieAstFactory.MkMapAssign(Freed, Expr.Ident(x), Expr.Literal(true))); DesugarIte.Instrument(program); InstrumentMemoryAccesses.Instrument(program, nil); return(program); }
// assert e != null && $Alloc[e] && !Freed[e]; assume e != null List <Cmd> MkAssert(Expr e) { return(new List <Cmd> { new AssertCmd(Token.NoToken, Expr.Neq(e, nil)), new AssertCmd(Token.NoToken, BoogieAstFactory.MkMapAccessExpr(Driver.Alloc, e)), new AssertCmd(Token.NoToken, Expr.Not(BoogieAstFactory.MkMapAccessExpr(Driver.Freed, e))), new AssumeCmd(Token.NoToken, Expr.Neq(e, nil)), new AssumeCmd(Token.NoToken, BoogieAstFactory.MkMapAccessExpr(Driver.Alloc, e)), new AssumeCmd(Token.NoToken, Expr.Not(BoogieAstFactory.MkMapAccessExpr(Driver.Freed, e))), }); }
static void InitMemory(Program program) { // find curraddr var alloc = program.TopLevelDeclarations.OfType <GlobalVariable>().Where(g => g.Name == allocVar) .FirstOrDefault(); if (alloc == null) { return; } // create alloc_init var allocinit = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, alloc.Name + "_init", alloc.TypedIdent.Type), false); // malloc ensures ret > alloc_init program.TopLevelDeclarations.OfType <Procedure>() .Where(p => MallocNames.Contains(p.Name)) .Iter(p => p.Ensures.Add(new Ensures(false, Expr.Gt(Expr.Ident(p.OutParams[0]), Expr.Ident(allocinit))))); // forall x : int :: { M[x] } M[x] >= 0 && M[x] < alloc_init var initM = new Func <Variable, Expr>(M => { var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", btype.Int)); var mx = BoogieAstFactory.MkMapAccessExpr(M, Expr.Ident(x)); return(new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> { x }, null, new Trigger(Token.NoToken, true, new List <Expr> { mx }), Expr.And(Expr.Ge(mx, Expr.Literal(0)), Expr.Lt(mx, Expr.Ident(allocinit))))); }); var cmds = new List <Cmd>( program.TopLevelDeclarations.OfType <GlobalVariable>() .Where(g => g.Name.StartsWith("$M")) .Where(g => g.TypedIdent.Type.IsMap && (g.TypedIdent.Type as MapType).Result.IsInt) .Select(g => initM(g)) .Select(e => new AssumeCmd(Token.NoToken, e))); // alloc_init > 0 && alloc > alloc_init cmds.Insert(0, new AssumeCmd(Token.NoToken, Expr.And(Expr.Gt(Expr.Ident(allocinit), Expr.Literal(0)), Expr.Gt(Expr.Ident(alloc), Expr.Ident(allocinit))))); var blk = new Block(Token.NoToken, "start", cmds, new ReturnCmd(Token.NoToken)); // create init proc var initproc = new Procedure(Token.NoToken, "SmackExtraInit", new List <TypeVariable>(), new List <Variable>(), new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); initproc.AddAttribute(AvUtil.AvnAnnotations.InitialializationProcAttr); var initimpl = new Implementation(Token.NoToken, initproc.Name, new List <TypeVariable>(), new List <Variable>(), new List <Variable>(), new List <Variable>(), new List <Block> { blk }); program.AddTopLevelDeclaration(initproc); program.AddTopLevelDeclaration(initimpl); program.AddTopLevelDeclaration(allocinit); }