Beispiel #1
0
        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);
        }
Beispiel #2
0
 // 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))),
     });
 }
Beispiel #3
0
        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);
        }