コード例 #1
0
 public override Procedure VisitProcedure(Procedure node)
 {
     if (!Visited.Contains(node))
     {
         Visited.Add(node);
         node.AddAttribute("prefix", this.Prefix);
         node.Name = AppendPrefix(node.Name);
     }
     return(base.VisitProcedure(node));
 }
コード例 #2
0
        private void AddDisableNetworkFunc()
        {
            Procedure proc = new Procedure(Token.NoToken, "_DISABLE_NETWORK_$" + this.EP.Name,
                                           new List <TypeVariable>(), new List <Variable>(), new List <Variable>(),
                                           new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            proc.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

            this.AC.TopLevelDeclarations.Add(proc);
            this.AC.ResContext.AddProcedure(proc);
        }
コード例 #3
0
        private void AddUnregisterDeviceFunc()
        {
            var proc = new Procedure(Token.NoToken, "_UNREGISTER_DEVICE_$" + this.EP.Name,
                                     new List <TypeVariable>(), new List <Variable>(), new List <Variable>(), new List <Requires>(),
                                     new List <IdentifierExpr>(), new List <Ensures>());

            proc.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

            this.AC.TopLevelDeclarations.Add(proc);
            this.AC.ResContext.AddProcedure(proc);
        }
コード例 #4
0
        private void AddNonCheckedFunc()
        {
            Procedure proc = new Procedure(Token.NoToken, "_NO_OP",
                                           new List <TypeVariable>(), new List <Variable>(), new List <Variable>(),
                                           new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            proc.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

            this.AC.TopLevelDeclarations.Add(proc);
            this.AC.ResContext.AddProcedure(proc);
        }
コード例 #5
0
        private void AddUpdateAtomicLocksetFunc()
        {
            var ls = this.AC.CurrentLocksets.Where(val => val.Thread.Equals(this.Thread)).
                     FirstOrDefault(val => val.Lock.Name.Equals("lock$atomic"));

            if (ls == null)
            {
                return;
            }

            var str = "_UPDATE_CLS_ATOMIC_$";

            var inParams = new List <Variable>();
            var inParam  = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                           "isLocked", Microsoft.Boogie.Type.Bool));

            inParams.Add(inParam);

            Procedure proc = new Procedure(Token.NoToken,
                                           str + this.Thread.Name + "$" + this.Thread.Id,
                                           new List <TypeVariable>(), inParams, new List <Variable>(),
                                           new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            proc.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });
            proc.Modifies.Add(new IdentifierExpr(ls.Id.tok, ls.Id));

            this.AC.TopLevelDeclarations.Add(proc);
            this.AC.ResContext.AddProcedure(proc);

            Block b = new Block(Token.NoToken, "_UPDATE", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            List <AssignLhs> newLhss = new List <AssignLhs>();
            List <Expr>      newRhss = new List <Expr>();

            newLhss.Add(new SimpleAssignLhs(ls.Id.tok, new IdentifierExpr(ls.Id.tok, ls.Id)));
            newRhss.Add(new IdentifierExpr(inParam.tok, inParam));

            var assign = new AssignCmd(Token.NoToken, newLhss, newRhss);

            b.Cmds.Add(assign);

            Implementation impl = new Implementation(Token.NoToken,
                                                     str + this.Thread.Name + "$" + this.Thread.Id,
                                                     new List <TypeVariable>(), inParams, new List <Variable>(),
                                                     new List <Variable>(), new List <Block>());

            impl.Blocks.Add(b);
            impl.Proc = proc;
            impl.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

            this.AC.TopLevelDeclarations.Add(impl);
        }
コード例 #6
0
        private void AddRegisterDeviceFunc()
        {
            var outParams = new List <Variable>();
            var outParam  = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                            "r", Microsoft.Boogie.Type.Int));

            outParams.Add(outParam);

            var proc = new Procedure(Token.NoToken, "_REGISTER_DEVICE_$" + this.EP.Name,
                                     new List <TypeVariable>(), new List <Variable>(), outParams, new List <Requires>(),
                                     new List <IdentifierExpr>(), new List <Ensures>());

            proc.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

            this.AC.TopLevelDeclarations.Add(proc);
            this.AC.ResContext.AddProcedure(proc);
        }
コード例 #7
0
        private static Procedure CreateProtoype(List <Variable> modSet, string procName, List <Constant> outputGuards, out List <Variable> equivOutParams, out List <Ensures> equivEnsures)
        {
            equivOutParams = new List <Variable>();
            equivEnsures   = new List <Ensures>();
            for (int i = 1; i <= modSet.Count; i++)
            {
                equivOutParams.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, RefineConsts.equivCheckVarName + i, Microsoft.Boogie.Type.Bool), false));
                equivEnsures.Add(new Ensures(false, Expr.Imp(Expr.Ident(outputGuards[i - 1]), Expr.Ident(equivOutParams[i - 1])))); // ensures bo_k => eq_k
            }

            var refineProc = new Procedure(new Token(), RefineConsts.refinedProcNamePrefix + procName, new List <TypeVariable>(),
                                           new List <Variable>(),
                                           equivOutParams,
                                           new List <Requires>(),
                                           new List <IdentifierExpr>(),
                                           equivEnsures);

            string[] vals = { procName };
            refineProc.AddAttribute(RefineConsts.checkDepAttribute, vals);
            return(refineProc);
        }
コード例 #8
0
        private void AddUpdateLocksetFunc(Microsoft.Boogie.Type type = null)
        {
            var str = "_UPDATE_CLS_$";

            var inParams  = new List <Variable>();
            var outParams = new List <Variable>();
            var in1       = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                            "lock", this.AC.MemoryModelType));
            var in2 = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                      "isLocked", Microsoft.Boogie.Type.Bool));

            if (type != null)
            {
                str += type.ToString() + "$";
                outParams.Add(new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                              "$r", type)));
            }

            inParams.Add(in1);
            inParams.Add(in2);

            Procedure proc = new Procedure(Token.NoToken, str + this.EP.Name,
                                           new List <TypeVariable>(), inParams, outParams,
                                           new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            proc.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

            foreach (var ls in this.AC.CurrentLocksets)
            {
                if (this.ShouldSkipLockset(ls))
                {
                    continue;
                }

                proc.Modifies.Add(new IdentifierExpr(ls.Id.tok, ls.Id));
            }

            this.AC.TopLevelDeclarations.Add(proc);
            this.AC.ResContext.AddProcedure(proc);

            Block b = new Block(Token.NoToken, "_UPDATE", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            foreach (var ls in this.AC.CurrentLocksets)
            {
                if (this.ShouldSkipLockset(ls))
                {
                    continue;
                }

                List <AssignLhs> newLhss = new List <AssignLhs>();
                List <Expr>      newRhss = new List <Expr>();

                newLhss.Add(new SimpleAssignLhs(ls.Id.tok, new IdentifierExpr(ls.Id.tok, ls.Id)));
                newRhss.Add(new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken),
                                         new List <Expr>(new Expr[] { Expr.Eq(new IdentifierExpr(in1.tok, in1),
                                                                              new IdentifierExpr(ls.Lock.tok, ls.Lock)),
                                                                      new IdentifierExpr(in2.tok, in2), new IdentifierExpr(ls.Id.tok, ls.Id) })));

                var assign = new AssignCmd(Token.NoToken, newLhss, newRhss);
                b.Cmds.Add(assign);
            }

            Implementation impl = new Implementation(Token.NoToken, str + this.EP.Name,
                                                     new List <TypeVariable>(), inParams, outParams,
                                                     new List <Variable>(), new List <Block>());

            if (type != null)
            {
                var bVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                           "$b", Microsoft.Boogie.Type.Bool));
                var bVarId = new IdentifierExpr(Token.NoToken, bVar);
                impl.LocVars.Add(bVar);
                b.Cmds.Add(new HavocCmd(Token.NoToken, new List <IdentifierExpr> {
                    bVarId
                }));
                b.Cmds.Add(new AssignCmd(Token.NoToken,
                                         new List <AssignLhs> {
                    new SimpleAssignLhs(Token.NoToken,
                                        new IdentifierExpr(Token.NoToken, outParams[0]))
                },
                                         new List <Expr> {
                    bVarId
                }));
            }

            impl.Blocks.Add(b);
            impl.Proc = proc;
            impl.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

            this.AC.TopLevelDeclarations.Add(impl);
        }
コード例 #9
0
        private void AddAccessFuncs(AccessType access)
        {
            foreach (var mr in SharedStateAnalyser.GetMemoryRegions(this.EP))
            {
                List <Variable> inParams = new List <Variable>();

                if (mr.TypedIdent.Type.IsMap)
                {
                    inParams.Add(new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "ptr",
                                                                                 this.AC.MemoryModelType)));
                }

                Procedure proc = new Procedure(Token.NoToken, this.MakeAccessFuncName(access, mr.Name),
                                               new List <TypeVariable>(), inParams, new List <Variable>(),
                                               new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
                proc.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

                this.AC.TopLevelDeclarations.Add(proc);
                this.AC.ResContext.AddProcedure(proc);

                var cmds = new List <Cmd>();

                foreach (var ls in this.AC.MemoryLocksets)
                {
                    if (!ls.TargetName.Equals(mr.Name))
                    {
                        continue;
                    }
                    if (this.ShouldSkipLockset(ls))
                    {
                        continue;
                    }

                    foreach (var cls in this.AC.CurrentLocksets)
                    {
                        if (!cls.Lock.Name.Equals(ls.Lock.Name))
                        {
                            continue;
                        }

                        IdentifierExpr lsExpr = new IdentifierExpr(ls.Id.tok, ls.Id);

                        cmds.Add(new AssignCmd(Token.NoToken,
                                               new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, lsExpr)
                        }, new List <Expr> {
                            Expr.And(new IdentifierExpr(cls.Id.tok, cls.Id), lsExpr)
                        }));

                        proc.Modifies.Add(lsExpr);
                        break;
                    }
                }

                if (access == AccessType.WRITE)
                {
                    foreach (var acv in this.AC.GetWriteAccessCheckingVariables())
                    {
                        if (!acv.Name.Split('_')[1].Equals(mr.Name))
                        {
                            continue;
                        }

                        var wacs = this.AC.GetWriteAccessCheckingVariables().Find(val =>
                                                                                  val.Name.Contains(this.AC.GetWriteAccessVariableName(this.EP, mr.Name)));
                        var wacsExpr = new IdentifierExpr(wacs.tok, wacs);

                        cmds.Add(new AssignCmd(Token.NoToken,
                                               new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, wacsExpr)
                        }, new List <Expr> {
                            Expr.True
                        }));

                        proc.Modifies.Add(wacsExpr);
                    }
                }
                else if (access == AccessType.READ)
                {
                    foreach (var acv in this.AC.GetReadAccessCheckingVariables())
                    {
                        if (!acv.Name.Split('_')[1].Equals(mr.Name))
                        {
                            continue;
                        }

                        var racs = this.AC.GetReadAccessCheckingVariables().Find(val =>
                                                                                 val.Name.Contains(this.AC.GetReadAccessVariableName(this.EP, mr.Name)));
                        var racsExpr = new IdentifierExpr(racs.tok, racs);

                        cmds.Add(new AssignCmd(Token.NoToken,
                                               new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, racsExpr)
                        }, new List <Expr> {
                            Expr.True
                        }));

                        proc.Modifies.Add(racsExpr);
                    }
                }

                List <BigBlock> blocks = null;
                if (mr.TypedIdent.Type.IsMap)
                {
                    var ptr = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "ptr",
                                                                              this.AC.MemoryModelType));
                    var watchdog = this.AC.GetAccessWatchdogConstants().Find(val =>
                                                                             val.Name.Contains(this.AC.GetAccessWatchdogConstantName(mr.Name)));

                    var ptrExpr      = new IdentifierExpr(ptr.tok, ptr);
                    var watchdogExpr = new IdentifierExpr(watchdog.tok, watchdog);
                    var guardExpr    = Expr.Eq(watchdogExpr, ptrExpr);

                    var ifStmts = new StmtList(new List <BigBlock> {
                        new BigBlock(Token.NoToken, null, cmds, null, null)
                    }, Token.NoToken);
                    var ifCmd = new IfCmd(Token.NoToken, guardExpr, ifStmts, null, null);

                    blocks = new List <BigBlock> {
                        new BigBlock(Token.NoToken, "_" + access.ToString(), new List <Cmd>(), ifCmd, null)
                    };
                }
                else
                {
                    blocks = new List <BigBlock> {
                        new BigBlock(Token.NoToken, "_" + access.ToString(), cmds, null, null)
                    };
                }

                Implementation impl = new Implementation(Token.NoToken, this.MakeAccessFuncName(access, mr.Name),
                                                         new List <TypeVariable>(), inParams, new List <Variable>(), new List <Variable>(),
                                                         new StmtList(blocks, Token.NoToken));

                impl.Proc = proc;
                impl.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

                this.AC.TopLevelDeclarations.Add(impl);
            }
        }
コード例 #10
0
            private void FindUnknown()
            {
                // Which {:unknown} already exist?
                foreach (var proc in prog.TopLevelDeclarations.OfType <Procedure>()
                         .Where(p => QKeyValue.FindBoolAttribute(p.Attributes, AvnAnnotations.AngelicUnknownCall)))
                {
                    if (proc.OutParams.Count != 1 || proc.InParams.Count != 0)
                    {
                        continue;
                    }
                    //throw new InputProgramDoesNotMatchExn(string.Format("Unknown-generating procs should have exactly one out parameter and no input parameters: {0}", proc.Name));
                    unknownGenProcs.Add(proc.OutParams[0].TypedIdent.Type.ToString(), proc);
                }

                foreach (var ty in Options.unknownTypes)
                {
                    // Find the type
                    btype type = null;
                    if (ty == "int")
                    {
                        type = btype.Int;
                    }
                    else if (ty == "bool")
                    {
                        type = btype.Bool;
                    }
                    else if (ty == "[int]int")
                    {
                        type = new MapType(Token.NoToken, new List <TypeVariable>(), new List <btype> {
                            btype.Int
                        }, btype.Int);
                    }
                    else
                    {
                        // lookup user types
                        type = prog.TopLevelDeclarations.OfType <TypeCtorDecl>()
                               .Where(t => t.Name == ty)
                               .Select(t => new CtorType(Token.NoToken, t, new List <btype>()))
                               .FirstOrDefault();

                        if (type == null)
                        {
                            type = prog.TopLevelDeclarations.OfType <TypeSynonymDecl>()
                                   .Where(t => t.Name == ty)
                                   .Select(t => new TypeSynonymAnnotation(Token.NoToken, t, new List <btype>()))
                                   .FirstOrDefault();
                        }
                    }
                    if (type == null)
                    {
                        Console.WriteLine("Error: type {0} not found", type);
                        throw new InputProgramDoesNotMatchExn("Invalid unknown type given");
                    }

                    if (unknownGenProcs.ContainsKey(ty))
                    {
                        continue;
                    }

                    // create a new procedure
                    var proc = new Procedure(Token.NoToken, "unknown_" + SanitizeTypeName(type), new List <TypeVariable>(), new List <Variable>(),
                                             new List <Variable> {
                        new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "r", type), false)
                    },
                                             new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
                    proc.AddAttribute(AvnAnnotations.AngelicUnknownCall);
                    unknownGenProcs.Add(ty, proc);
                    prog.AddTopLevelDeclaration(proc);
                }

                // Remove extra ones
                var extra = new HashSet <string>(unknownGenProcs.Keys);

                extra.ExceptWith(Options.unknownTypes);
                extra.Iter(s => unknownGenProcs.Remove(s));

                foreach (var proc in unknownGenProcs.Values)
                {
                    // Add {:allocator "full"} annotation
                    var attr = QKeyValue.FindStringAttribute(proc.Attributes, "allocator");
                    if (attr != null && attr == "full")
                    {
                        continue;
                    }
                    proc.AddAttribute("allocator", "full");

                    // Drop Requires/Ensures
                    proc.Requires = new List <Requires>();
                    proc.Ensures  = new List <Ensures>();
                    proc.Modifies = new List <IdentifierExpr>();
                }

                // Extra annotations for user-defined unknowns
                prog.TopLevelDeclarations.OfType <Procedure>()
                .Where(p => Options.unknownProcs.Contains(p.Name))
                .Iter(p => p.AddAttribute(AvnAnnotations.AngelicUnknownCall));
            }
コード例 #11
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);
        }