Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
            //Change the body of any stub that returns a pointer into calling unknown()
            //TODO: only do this for procedures with a single return with a pointer type
            private void MkStubImplementation(List <Implementation> stubImpls, Procedure p)
            {
                List <Cmd>      cmds      = new List <Cmd>();
                List <Variable> localVars = new List <Variable>();

                stubs.Add(p.Name);
                foreach (var op in p.OutParams)
                {
                    if (IsPointerVariable(op))
                    {
                        cmds.Add(AllocatePointerAsUnknown(op));
                    }
                    else
                    {
                        // Avoid using Havoc -- we'll let this fall on the floor as an
                        // uninitialized variable. AVN will take care of concretizing it
                        //cmds.Add(BoogieAstFactory.MkHavocVar(op));
                    }
                }
                foreach (var v in p.Modifies.Select(ie => ie.Decl))
                {
                    if (IsPointerVariable(v))
                    {
                        cmds.Add(AllocatePointerAsUnknown(v));
                    }
                    else
                    {
                        // unsupported
                        Console.WriteLine("Warning: demonic havoc of global {0} in {1}", v.Name, p.Name);
                    }
                }
                foreach (var ip in p.InParams)
                {
                    if (!BoogieUtil.checkAttrExists("ref", ip.Attributes))
                    {
                        continue;
                    }
                    string mapName = QKeyValue.FindStringAttribute(ip.Attributes, "ref");
                    if (mapName == null)
                    {
                        Utils.Print(String.Format("Expecting a map <name> with {:ref <name>} annotation on procedure {0}", p.Name),
                                    Utils.PRINT_TAG.AV_WARNING);
                        continue;
                    }
                    var mapVars = prog.TopLevelDeclarations.OfType <Variable>().Where(x => x.Name == mapName && x.TypedIdent.Type.IsMap);
                    if (mapVars.Count() != 1)
                    {
                        Utils.Print(String.Format("Mapname {0} provided in {{:ref}} for parameter {1} for procedure {2} has {3} matches, expecting exactly 1 match",
                                                  mapName, ip.Name, p.Name, mapVars.Count()),
                                    Utils.PRINT_TAG.AV_WARNING);
                        continue;
                    }
                    var tmpVar = BoogieAstFactory.MkLocal("__tmp_" + ip.Name, ip.TypedIdent.Type);
                    localVars.Add(tmpVar);
                    cmds.Add(AllocatePointerAsUnknown(tmpVar));
                    cmds.Add(BoogieAstFactory.MkMapAssign(mapVars.First(), IdentifierExpr.Ident(ip), IdentifierExpr.Ident(tmpVar)));
                }
                if (cmds.Count == 0)
                {
                    return;                  //don't create a body if no statements
                }
                var blk  = BoogieAstFactory.MkBlock(cmds, new ReturnCmd(Token.NoToken));
                var blks = new List <Block>()
                {
                    blk
                };
                //don't insert the proc as it already exists
                var impl = BoogieAstFactory.MkImpl(p.Name,
                                                   DropAnnotations(p.InParams),
                                                   DropAnnotations(p.OutParams),
                                                   new List <Variable>(), blks);

                ((Implementation)impl[1]).LocVars.AddRange(localVars);
                stubImpls.Add((Implementation)impl[1]);
            }