List <Cmd> ProcessAssign(AssignCmd cmd, Dictionary <string, string> varDecls) { var ret = new List <Cmd>(); var reads = new GatherMemAccesses(); cmd.Lhss.Iter(e => reads.VisitExpr(e.AsExpr)); cmd.Rhss.Iter(e => reads.VisitExpr(e)); foreach (var tup in reads.accesses) { var ptr = tup.Item2; string basePtr; if (varDecls.TryGetValue(ptr.ToString(), out basePtr)) { ret.Add(MkAssert(Expr.Ident(BoogieAstFactory.MkFormal(basePtr, btype.Int, true)))); } else { ret.Add(MkAssert(ptr)); } } ret.Add(cmd); return(ret); }
static Function GetCandidateFunc(string prefix, string implname) { return(new Function(Token.NoToken, prefix + implname, new List <Variable> { BoogieAstFactory.MkFormal("a", Microsoft.Boogie.Type.Bool, true), BoogieAstFactory.MkFormal("b", Microsoft.Boogie.Type.Bool, true), BoogieAstFactory.MkFormal("c", Microsoft.Boogie.Type.Bool, true) }, BoogieAstFactory.MkFormal("d", Microsoft.Boogie.Type.Bool, false))); }
Function GetQueryFunc() { var f = new Function(Token.NoToken, "ASquery" + queries.Count, new List <Variable> { BoogieAstFactory.MkFormal("x", btype.Int, true) }, BoogieAstFactory.MkFormal("y", btype.Bool, false)); f.AddAttribute("aliasingQuery", "allocationsites"); queries.Add(f); return(f); }
public void Run(Program program) { // First add a MustReach function f = new Function(Token.NoToken, "ProcedureMustReach", new List <Variable> { BoogieAstFactory.MkFormal("x", btype.Bool, true) }, BoogieAstFactory.MkFormal("y", btype.Bool, false)); f.AddAttribute("ReachableStates"); program.AddTopLevelDeclaration(f); // Then add function calls to the beginning and end of each non-stub procedure program.Implementations.Iter(impl => VisitImplementation(impl)); }
public override List <Cmd> VisitCmdSeq(List <Cmd> cmdSeq) { int callCmdCount = -1; var newCmdSeq = new List <Cmd>(); foreach (Cmd c in cmdSeq) { newCmdSeq.Add(c); var callCmd = c as CallCmd; if (callCmd != null) { callCmdCount++; } if (callCmd != null && BoogieUtil.checkAttrExists(AvnAnnotations.AngelicUnknownCall, callCmd.Proc.Attributes)) { var retCall = callCmd.Outs[0]; btype retType = callCmd.Proc.OutParams[0].TypedIdent.Type; if (retType == null) { retType = btype.Int; } var mallocTriggerFn = new Function(Token.NoToken, mallocTriggerFuncName + mallocTriggers.Count, new List <Variable>() { BoogieAstFactory.MkFormal("a", retType, false) }, BoogieAstFactory.MkFormal("r", btype.Bool, false)); mallocTriggers[callCmd] = mallocTriggerFn; var callId = QKeyValue.FindIntAttribute(callCmd.Attributes, cba.RestrictToTrace.ConcretizeCallIdAttr, -1); Debug.Assert(callId == -1, "Calls to unknown must not already be tagged with an ID"); callId = instance.id++; callCmd.Attributes = new QKeyValue(Token.NoToken, cba.RestrictToTrace.ConcretizeCallIdAttr, new List <object> { Expr.Literal(callId) }, callCmd.Attributes); instance.mallocTriggersLocation[callId] = mallocTriggerFn.Name; instance.mallocTriggerToAllocationSite[mallocTriggerFn.Name] = callId; instance.prog.AddTopLevelDeclaration(mallocTriggerFn); var fnApp = new NAryExpr(Token.NoToken, new FunctionCall(mallocTriggerFn), new List <Expr> () { retCall }); newCmdSeq.Add(BoogieAstFactory.MkAssume(fnApp)); } } return(base.VisitCmdSeq(newCmdSeq)); }
// instrumentation functions for buffer overflow detection private void BufferInstrument(Procedure mallocProcedure) { var sizeFun = new Function(Token.NoToken, "Size", new List <Variable>() { BoogieAstFactory.MkFormal("x", btype.Int, false) }, BoogieAstFactory.MkFormal("r", btype.Int, false)); sizeFun.AddAttribute("buffer", new Object[] { "size" }); var baseFun = new Function(Token.NoToken, "Base", new List <Variable>() { BoogieAstFactory.MkFormal("x", btype.Int, false) }, BoogieAstFactory.MkFormal("r", btype.Int, false)); baseFun.AddAttribute("buffer", new Object[] { "base" }); var allocMap = BoogieAstFactory.MkGlobal("nonfree", BoogieAstFactory.MkMapType(btype.Int, btype.Bool)); allocMap.AddAttribute("buffer", new Object[] { "free" }); prog.AddTopLevelDeclaration(sizeFun); prog.AddTopLevelDeclaration(baseFun); prog.AddTopLevelDeclaration(allocMap); var mallocRet = Expr.Ident(mallocProcedure.OutParams[0]); mallocProcedure.Ensures.Add(new Ensures(true, Expr.Eq( new NAryExpr(Token.NoToken, new FunctionCall(baseFun), new List <Expr>() { mallocRet }), mallocRet))); var mallocIn = Expr.Ident(mallocProcedure.InParams[0]); mallocProcedure.Ensures.Add(new Ensures(true, Expr.Eq( new NAryExpr(Token.NoToken, new FunctionCall(sizeFun), new List <Expr>() { mallocRet }), mallocIn))); //mallocProcedure.Ensures.Add(new Ensures(true, // BoogieAstFactory.MkMapAccessExpr(allocMap, mallocRet))); }
public override Implementation VisitImplementation(Implementation node) { var varDecls = new Dictionary <string, string>(); var cb = new CollectBasePointer(varDecls); cb.VisitImplementation(node); foreach (var b in node.Blocks) { var newCmds = new List <Cmd>(); foreach (var c in b.Cmds) { if (c is AssumeCmd) { var asmCmd = c as AssumeCmd; if (BoogieUtil.checkAttrExists("nonnull", asmCmd.Attributes)) { var expr = asmCmd.Expr as NAryExpr; expr.Args[1] = nil; newCmds.Add(c); continue; } } if (c is AssignCmd) { var asnCmd = c as AssignCmd; var reads = new GatherMemAccesses(); asnCmd.Rhss.Iter(e => reads.VisitExpr(e)); foreach (var tup in reads.accesses) { var ptr = tup.Item2; string basePtr; if (varDecls.TryGetValue(ptr.ToString(), out basePtr)) { newCmds.Add(MkAssume(Expr.Ident(BoogieAstFactory.MkFormal(basePtr, btype.Int, true)))); } else { newCmds.Add(MkAssume(ptr)); } } } newCmds.Add(c); } b.cmds = newCmds; } return(node); }
public static Function FindReachableStatesFunc(Program program) { var ret = program.TopLevelDeclarations.OfType <Function>() .Where(f => QKeyValue.FindBoolAttribute(f.Attributes, AvnAnnotations.ReachableStatesAttr)) .FirstOrDefault(); if (ret != null) { return(ret); } ret = new Function(Token.NoToken, "MustReach", new List <Variable> { BoogieAstFactory.MkFormal("x", btype.Bool, true) }, BoogieAstFactory.MkFormal("y", btype.Bool, false)); ret.AddAttribute(AvnAnnotations.ReachableStatesAttr); program.AddTopLevelDeclaration(ret); return(ret); }
// assert !aliasQ(e, NULL) AssertCmd MkAssert(Expr e) { var a = BoogieAstFactory.MkFormal("a", btype.Int, true); var b = BoogieAstFactory.MkFormal("b", btype.Int, true); var f = new Function(Token.NoToken, "aliasQ" + (counter++), new List <Variable> { a, b }, BoogieAstFactory.MkFormal("c", btype.Bool, false)); f.AddAttribute("aliasingQuery"); f.AddAttribute("inline"); f.Body = Expr.Eq(Expr.Ident(a), Expr.Ident(b)); aliasQfuncs.Add(f); return(new AssertCmd(Token.NoToken, Expr.Not(new NAryExpr(Token.NoToken, new FunctionCall(f), new List <Expr> { e, nil })))); }
// replace formal-ins and outs with a unique variable public static string ExprToTemplateGeneral(Expr expr) { var GetFin = new Func <btype, Variable>(ty => BoogieAstFactory.MkFormal("v_fin_" + ty.ToString(), ty, true)); var GetFout = new Func <btype, Variable>(ty => BoogieAstFactory.MkFormal("v_fout_" + ty.ToString(), ty, true)); var ret = Substituter.Apply(new Substitution(v => { if (v is Formal && (v as Formal).InComing) { return(Expr.Ident(GetFin(v.TypedIdent.Type))); } if (v is Formal && !(v as Formal).InComing) { return(Expr.Ident(GetFout(v.TypedIdent.Type))); } return(Expr.Ident(v)); }), expr); return(ret.ToString()); }
public static void Instrument(Program program, HashSet <string> scalars) { memAccess = BoogieAstFactory.MkLocal("memAccess", Microsoft.Boogie.Type.Int) as LocalVariable; scalarGlobals = new HashSet <string>(); program.TopLevelDeclarations .OfType <GlobalVariable>() .Where(g => scalars.Contains(g.Name)) .Iter(g => scalarGlobals.Add(g.Name)); program.TopLevelDeclarations .OfType <Implementation>() .Iter(Instrument); var decl = BoogieAstFactory.MkProc(recordProc, new List <Variable>(new Variable[] { BoogieAstFactory.MkFormal("address", Microsoft.Boogie.Type.Int, true) }), new List <Variable>()); program.AddTopLevelDeclaration(decl); }
public static string ExprToTemplateSpecific(Expr expr, bool loop) { int cnt = 0; var inCache = new Dictionary <string, Expr>(); var outCache = new Dictionary <string, Expr>(); var inToOut = new Func <string, string>(s => s.StartsWith("in_") ? "out_" + s.Substring("in_".Length) : ""); var outToIn = new Func <string, string>(s => s.StartsWith("out_") ? "in_" + s.Substring("out_".Length) : ""); var GetFin = new Func <Variable, Expr>(v => { if (inCache.ContainsKey(v.Name)) { return(inCache[v.Name]); } if (loop && outCache.ContainsKey(inToOut(v.Name))) { return(new OldExpr(Token.NoToken, outCache[inToOut(v.Name)])); } var prefix = loop ? "v_loop_" : "v_fin_"; prefix += v.TypedIdent.Type.ToString(); prefix += string.Format("_{0}", cnt++); var outv = BoogieAstFactory.MkFormal(prefix, v.TypedIdent.Type, true); var outexpr = loop ? (Expr)(new OldExpr(Token.NoToken, Expr.Ident(outv))) : Expr.Ident(outv); inCache[v.Name] = outexpr; return(outexpr); }); var GetFout = new Func <Variable, Expr>(v => { if (outCache.ContainsKey(v.Name)) { return(outCache[v.Name]); } if (loop && inCache.ContainsKey(outToIn(v.Name)) && inCache[outToIn(v.Name)] is OldExpr) { return((inCache[outToIn(v.Name)] as OldExpr).Expr); } var prefix = loop ? "v_loop_" : "v_fout_"; prefix += v.TypedIdent.Type.ToString(); prefix += string.Format("_{0}", cnt++); var outv = BoogieAstFactory.MkFormal(prefix, v.TypedIdent.Type, false); var outexpr = Expr.Ident(outv); outCache[v.Name] = outexpr; return(outexpr); }); var ret = Substituter.Apply(new Substitution(v => { if (v is Formal && (v as Formal).InComing) { return(GetFin(v)); } if (v is Formal && !(v as Formal).InComing) { return(GetFout(v)); } return(Expr.Ident(v)); }), expr); return(ret.ToString()); }