/// <summary> /// Simplifies the CFG of the given implementation impl by merging each /// basic block with a single predecessor into that predecessor if the /// predecessor has a single successor. If a uniformity analyser is /// being used then blocks will only be merged if they are both uniform /// or both non-uniform /// </summary> public static void MergeBlocksIntoPredecessors(Program prog, Implementation impl, UniformityAnalyser uni) { var blockGraph = prog.ProcessLoops(impl); var predMap = new Dictionary<Block, Block>(); foreach (var block in blockGraph.Nodes) { try { var pred = blockGraph.Predecessors(block).Single(); if (blockGraph.Successors(pred).Single() == block && (uni == null || (uni.IsUniform(impl.Name, pred) && uni.IsUniform(impl.Name, block)) || (!uni.IsUniform(impl.Name, pred) && !uni.IsUniform(impl.Name, block)))) { Block predMapping; while (predMap.TryGetValue(pred, out predMapping)) pred = predMapping; pred.Cmds.AddRange(block.Cmds); pred.TransferCmd = block.TransferCmd; impl.Blocks.Remove(block); predMap[block] = pred; } // If Single throws an exception above (i.e. not exactly one pred/succ), skip this block. } catch (InvalidOperationException) { } } }
public void Insert(Implementation impl, VerificationResult result) { Contract.Requires(impl != null); Contract.Requires(result != null); Cache.Set(impl.Id, result, Policy); }
BlockPredicator(Program p, Implementation i, bool cci, bool upp) { prog = p; impl = i; createCandidateInvariants = cci; useProcedurePredicates = upp; }
/*!*/ private static HashSet<Block/*!*/> ComputeMultiPredecessorBlocks(Implementation/*!*/ impl) { Contract.Requires(impl != null); Contract.Ensures(cce.NonNullElements(Contract.Result<HashSet<Block>>())); HashSet<Block/*!*/> visitedBlocks = new HashSet<Block/*!*/>(); HashSet<Block/*!*/> multiPredBlocks = new HashSet<Block/*!*/>(); Stack<Block/*!*/> dfsStack = new Stack<Block/*!*/>(); dfsStack.Push(impl.Blocks[0]); while (dfsStack.Count > 0) { Block/*!*/ b = dfsStack.Pop(); Contract.Assert(b != null); if (visitedBlocks.Contains(b)) { multiPredBlocks.Add(b); continue; } visitedBlocks.Add(b); if (b.TransferCmd == null) continue; if (b.TransferCmd is ReturnCmd) continue; Contract.Assert(b.TransferCmd is GotoCmd); GotoCmd gotoCmd = (GotoCmd)b.TransferCmd; if (gotoCmd.labelTargets == null) continue; foreach (Block/*!*/ succ in gotoCmd.labelTargets) { Contract.Assert(succ != null); dfsStack.Push(succ); } } return multiPredBlocks; }
SmartBlockPredicator(Program p, Implementation i, Func<Procedure, bool> upp, UniformityAnalyser u) { prog = p; impl = i; useProcedurePredicates = upp; myUseProcedurePredicates = useProcedurePredicates(i.Proc); uni = u; }
public bool isThreadEntry(bpl.Implementation impl) { if (impl == null) { return(false); } return(isThreadEntry(impl.Proc)); }
public static void Predicate(Program p, Func<Procedure, bool> useProcedurePredicates = null, UniformityAnalyser uni = null) { useProcedurePredicates = useProcedurePredicates ?? (proc => false); if (uni != null) { var oldUPP = useProcedurePredicates; useProcedurePredicates = proc => oldUPP(proc) && !uni.IsUniform(proc.Name); } foreach (var decl in p.TopLevelDeclarations.ToList()) { if (decl is Procedure || decl is Implementation) { var proc = decl as Procedure; Implementation impl = null; if (proc == null) { impl = (Implementation)decl; proc = impl.Proc; } bool upp = useProcedurePredicates(proc); if (upp) { var dwf = (DeclWithFormals)decl; var fpVar = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "_P", Microsoft.Boogie.Type.Bool), /*incoming=*/true); dwf.InParams = new List<Variable>( (new Variable[] {fpVar}.Concat(dwf.InParams.Cast<Variable>())) .ToArray()); if (impl == null) { var fpIdentifierExpr = new IdentifierExpr(Token.NoToken, fpVar); foreach (Requires r in proc.Requires) { new EnabledReplacementVisitor(fpIdentifierExpr).VisitExpr(r.Condition); if (!QKeyValue.FindBoolAttribute(r.Attributes, "do_not_predicate")) { r.Condition = Expr.Imp(fpIdentifierExpr, r.Condition); } } foreach (Ensures e in proc.Ensures) { new EnabledReplacementVisitor(new IdentifierExpr(Token.NoToken, fpVar)).VisitExpr(e.Condition); if (!QKeyValue.FindBoolAttribute(e.Attributes, "do_not_predicate")) { e.Condition = Expr.Imp(fpIdentifierExpr, e.Condition); } } } } if (impl != null) { try { new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation(); } catch (Program.IrreducibleLoopException) { } } } } }
public VerificationResult Lookup(Implementation impl) { if (!NeedsToBeVerified(impl)) { return Lookup(impl.Id); } else { return null; } }
public MyDuplicator(MoverTypeChecker moverTypeChecker, int layerNum) { this.moverTypeChecker = moverTypeChecker; this.layerNum = layerNum; this.enclosingProc = null; this.enclosingImpl = null; this.procMap = new Dictionary<Procedure, Procedure>(); this.absyMap = new Dictionary<Absy, Absy>(); this.implMap = new Dictionary<Implementation, Implementation>(); this.yieldingProcs = new HashSet<Procedure>(); this.impls = new List<Implementation>(); }
/* ComputePhaseIntervals : 1.1 Input parameters : 1.1.1 Implementation impl : Implementation whose body is being YTS checked. 1.1.2 int specPhaseNumImpl : Phase number in which procedure of implementation, impl, reaches its specification,{A,R,L,B} 1.1.3 MoverTypeChecker moverTypeChecker : moverTypeChecker is the integration point of YieldTypeChecker to OG class. moverTypeChecker has functions enables YieldTypeChecker to find phaseNum and spec of procedures. 1.2 Return value : is a list of tuples(phase interval start,phase interval end). Every tuple in this list is representing an interval formed by callCmds' phase numbers inside impl. 1.3 Action : This function first traverses the blocks inside impl, collects all CallCmds inside it into a HashSet ,callCmdsInImpl. * Then it puts all these callCmds' phase numbers into a HashSet,callCmdPhaseNumSet. * After adding all callCmds' phase numbers' it adds phase number of procedure of impl into the set. * It sorts all numbers in this set and creates [-inf...n-1] [n...k-1] [k PhaseNumProcOfImpl] disjoint intervals. */ private static List<Tuple<int, int>> ComputePhaseIntervals(Implementation impl, int specPhaseNumImpl, MoverTypeChecker moverTypeChecker) { HashSet<CallCmd> callCmdsInImpl = new HashSet<CallCmd>(); // callCmdsInImpl[Implementation] ==> Set = { call1, call2, call3 ... } List<Tuple<int, int>> phaseIntervals = new List<Tuple<int, int>>(); // [MinValue ph0 ] [ph0 ph1] [ph1 ph2] ..... [phk phk+1] intervals // Compute CallCmds inside impl foreach (Block b in impl.Blocks) { for (int i = 0; i < b.Cmds.Count; i++) { CallCmd callCmd = b.Cmds[i] as CallCmd; if (callCmd == null) continue; callCmdsInImpl.Add(callCmd); } } //Collect phase numbers of CallCmds inside impl HashSet<int> callCmdPhaseNumSet = new HashSet<int>(); foreach (CallCmd callCmd in callCmdsInImpl) { int tmpPhaseNum = moverTypeChecker.FindPhaseNumber(callCmd.Proc); callCmdPhaseNumSet.Add(tmpPhaseNum); } callCmdPhaseNumSet.Add(specPhaseNumImpl); List<int> callCmdPhaseNumList = callCmdPhaseNumSet.ToList(); callCmdPhaseNumList.Sort(); //Create Phase Intervals for (int i = 0; i < callCmdPhaseNumList.Count; i++) { //create the initial phase (-inf leastPhaseNum] if (i == 0) { Tuple<int, int> initTuple = new Tuple<int, int>(int.MinValue, callCmdPhaseNumList[i]); phaseIntervals.Add(initTuple); } else // create other phase intervals { Tuple<int, int> intervalToInsert = new Tuple<int, int>(callCmdPhaseNumList[i - 1] + 1, callCmdPhaseNumList[i]); phaseIntervals.Add(intervalToInsert); } } #if (DEBUG && !DEBUG_DETAIL) Console.Write("\n Number of phases is " + phaseIntervals.Count.ToString()); for (int i = 0;i<phaseIntervals.Count ; i++) { Console.Write("\n Phase " + i.ToString() + "[" + phaseIntervals[i].Item1.ToString() + "," + phaseIntervals[i].Item2.ToString() + "]" + "\n"); } #endif return phaseIntervals; }
private YieldTypeChecker(MoverTypeChecker moverTypeChecker, Implementation impl, int currLayerNum, IEnumerable<Block> loopHeaders) { this.moverTypeChecker = moverTypeChecker; this.impl = impl; this.currLayerNum = currLayerNum; this.loopHeaders = loopHeaders; this.stateCounter = 0; this.absyToNode = new Dictionary<Absy, int>(); this.initialState = 0; this.finalStates = new HashSet<int>(); this.edgeLabels = new Dictionary<Tuple<int, int>, int>(); foreach (Block block in impl.Blocks) { absyToNode[block] = stateCounter; stateCounter++; foreach (Cmd cmd in block.Cmds) { absyToNode[cmd] = stateCounter; stateCounter++; } absyToNode[block.TransferCmd] = stateCounter; stateCounter++; if (block.TransferCmd is ReturnCmd) { finalStates.Add(absyToNode[block.TransferCmd]); } } foreach (Block block in impl.Blocks) { Absy blockEntry = block.Cmds.Count == 0 ? (Absy)block.TransferCmd : (Absy)block.Cmds[0]; edgeLabels[new Tuple<int, int>(absyToNode[block], absyToNode[blockEntry])] = 'P'; GotoCmd gotoCmd = block.TransferCmd as GotoCmd; if (gotoCmd == null) continue; foreach (Block successor in gotoCmd.labelTargets) { edgeLabels[new Tuple<int, int>(absyToNode[gotoCmd], absyToNode[successor])] = 'P'; } } this.nodeToAbsy = new Dictionary<int, Absy>(); foreach (KeyValuePair<Absy, int> state in absyToNode) { this.nodeToAbsy[state.Value] = state.Key; } ComputeGraph(); IsYieldTypeSafe(); }
private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true); Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true); Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false); Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a); Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b); Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c); Bpl.Procedure proc = new Bpl.Procedure( Bpl.Token.NoToken, sink.DelegateRemove(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { a, b }), new List <Bpl.Variable>(new Bpl.Variable[] { c }), new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), new List <Bpl.Ensures>()); proc.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(proc); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { cExpr }))); foreach (IMethodDefinition defn in delegates) { Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn)); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr)))))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr)))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr)))); } Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef); Bpl.IfCmd ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken)); ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd); Bpl.Implementation impl = new Bpl.Implementation( Bpl.Token.NoToken, sink.DelegateRemove(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { a, b }), new List <Bpl.Variable>(new Bpl.Variable[] { c }), new List <Bpl.Variable>(), BuildStmtList(ifCmd) ); impl.AddAttribute("inline", Bpl.Expr.Literal(1)); impl.Proc = proc; sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
public void addNavigationUriHavocer(Sink sink) { Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(getUriHavocerMethod(sink).ResolvedMethod); procInfo.Decl.AddAttribute("inline", new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.ONE)); Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder(); Bpl.HavocCmd havoc = new Bpl.HavocCmd(Bpl.Token.NoToken, new List <Bpl.IdentifierExpr>(new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition)) }))); builder.Add(havoc); Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, procInfo.Decl.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(), builder.Collect(Bpl.Token.NoToken)); sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
private static void CreateDelegateCreateMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Bpl.Formal method = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Method", Bpl.Type.Int), true); Bpl.Formal receiver = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Receiver", sink.Heap.RefType), true); Bpl.Formal typeParameters = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "TypeParameters", sink.Heap.TypeType), true); Bpl.Formal returnDelegate = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false); Bpl.IdentifierExpr methodExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, method); Bpl.IdentifierExpr receiverExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, receiver); Bpl.IdentifierExpr typeParametersExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, typeParameters); Bpl.IdentifierExpr returnDelegateExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, returnDelegate); Bpl.Procedure proc = new Bpl.Procedure( Bpl.Token.NoToken, sink.DelegateCreate(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }), new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), new List <Bpl.Ensures>()); proc.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(proc); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { returnDelegateExpr }))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(methodExpr, returnDelegateExpr), receiverExpr))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(methodExpr, returnDelegateExpr), typeParametersExpr))); foreach (IMethodDefinition defn in delegates) { Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn)); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, returnDelegateExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, methodExpr, cie)))); } Bpl.Implementation impl = new Bpl.Implementation( Bpl.Token.NoToken, sink.DelegateCreate(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }), new List <Bpl.Variable>(), stmtBuilder.Collect(Bpl.Token.NoToken)); impl.AddAttribute("inline", Bpl.Expr.Literal(1)); impl.Proc = proc; sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
public int VerificationPriority(Implementation impl) { if (!Cache.ContainsKey(impl.Id)) { return 3; // high priority (has been never verified before) } else if (Cache[impl.Id].Checksum != impl.Checksum) { return 2; // medium priority (old snapshot has been verified before) } else if (impl.DependenciesChecksum == null || Cache[impl.Id].DependeciesChecksum != impl.DependenciesChecksum) { return 1; // low priority (the same snapshot has been verified before, but a callee has changed) } else { return int.MaxValue; // skip verification (highest priority to get them done as soon as possible) } }
public override Implementation VisitImplementation(Implementation node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Implementation>() != null); //Console.WriteLine("Procedure {0}", node.Name); Implementation/*!*/ impl = base.VisitImplementation(node); Contract.Assert(impl != null); //Console.WriteLine("Old number of local variables = {0}", impl.LocVars.Length); List<Variable>/*!*/ vars = new List<Variable>(); foreach (Variable/*!*/ var in impl.LocVars) { Contract.Assert(var != null); if (_usedVars.Contains(var)) vars.Add(var); } impl.LocVars = vars; //Console.WriteLine("New number of local variables = {0}", impl.LocVars.Length); //Console.WriteLine("---------------------------------"); _usedVars.Clear(); return impl; }
/// <summary> /// Debug method that prints a dot file of the /// current set of blocks in impl to filename. /// </summary> private void Impl2Dot(Implementation impl, string filename) { Contract.Requires(impl != null); Contract.Requires(filename != null); List<string> nodes = new List<string>(); List<string> edges = new List<string>(); string nodestyle = "[shape=box];"; foreach (Block b in impl.Blocks) { Contract.Assert(b != null); nodes.Add(string.Format("\"{0}\" {1}", b.Label, nodestyle)); GotoCmd gc = b.TransferCmd as GotoCmd; if (gc != null) { Contract.Assert(gc.labelTargets != null); foreach (Block b_ in gc.labelTargets) { Contract.Assert(b_ != null); edges.Add(String.Format("\"{0}\" -> \"{1}\";", b.Label, b_.Label)); } } //foreach (Block b_ in b.Predecessors) //{ // edges.Add(String.Format("\"{0}\" -> \"{1}\";", b.Label, b_.Label)); //} } using (StreamWriter sw = new StreamWriter(filename)) { sw.WriteLine(String.Format("digraph {0} {{", impl.Name)); // foreach (string! s in nodes) { // sw.WriteLine(s); // } foreach (string s in edges) { Contract.Assert(s != null); sw.WriteLine(s); } sw.WriteLine("}}"); sw.Close(); } }
private void addMethodCalling(Bpl.Procedure proc, Bpl.Program program, Sink sink) { Bpl.Procedure callingProc = new Bpl.Procedure(Bpl.Token.NoToken, "__BOOGIE_CALL_" + proc.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(), new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), new List <Bpl.Ensures>()); sink.TranslatedProgram.AddTopLevelDeclaration(callingProc); Bpl.StmtListBuilder codeBuilder = new Bpl.StmtListBuilder(); List <Bpl.Variable> localVars = new List <Bpl.Variable>(proc.InParams); List <Bpl.IdentifierExpr> identVars = new List <Bpl.IdentifierExpr>(); for (int i = 0; i < localVars.Count; i++) { identVars.Add(new Bpl.IdentifierExpr(Bpl.Token.NoToken, localVars[i])); } codeBuilder.Add(new Bpl.HavocCmd(Bpl.Token.NoToken, identVars)); // FEEDBACK TODO this is possibly too much, I'm guessing sometimes this args might well be null Bpl.Expr notNullExpr; foreach (Bpl.IdentifierExpr idExpr in identVars) { if (idExpr.Type.Equals(sink.Heap.RefType)) { notNullExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, idExpr, Bpl.Expr.Ident(sink.Heap.NullRef)); codeBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, notNullExpr)); } } List <Bpl.Expr> callParams = new List <Bpl.Expr>(); for (int i = 0; i < identVars.Count; i++) { callParams.Add(identVars[i]); } Bpl.CallCmd callCmd = new Bpl.CallCmd(Bpl.Token.NoToken, proc.Name, callParams, new List <Bpl.IdentifierExpr>()); codeBuilder.Add(callCmd); Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, callingProc.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(), localVars, codeBuilder.Collect(Bpl.Token.NoToken)); sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
// There is no default constructor, because these parameters are needed for most subclasses public DoomDetectionStrategy(Implementation imp, Block unifiedexit, List<Block> unreach) { m_BlockH = new BlockHierachy(imp, unifiedexit); __DEBUG_EQCLeaf = m_BlockH.Leaves.Count; //foreach (BlockHierachyNode bhn in m_BlockH.Leaves) //{ // if (bhn.Content.Count > 0) __DEBUG_minelements.Add(bhn.Content[0]); //} //if (imp.Blocks.Count>0) m_GatherInfo(imp.Blocks[0], 0, 0,0); if (__DEBUGOUT) { Console.WriteLine("MaBranchingDepth {0} MaxMinPP {1} ", m_MaxBranchingDepth, m_MaxK); Console.WriteLine("AvgLeaverPerPath {0} AvgPLen {1}", 0, 0); } MaxBlocks = imp.Blocks.Count; MinBlocks = imp.Blocks.Count; HACK_NewCheck = false; __DEBUG_BlocksTotal = imp.Blocks.Count; }
private List<List<Cmd>> CollectAndDesugarYields(Implementation impl, Dictionary<string, Variable> domainNameToInputVar, Dictionary<string, Variable> domainNameToLocalVar, Dictionary<Variable, Variable> ogOldGlobalMap) { // Collect the yield predicates and desugar yields List<List<Cmd>> yields = new List<List<Cmd>>(); List<Cmd> cmds = new List<Cmd>(); foreach (Block b in impl.Blocks) { YieldCmd yieldCmd = null; List<Cmd> newCmds = new List<Cmd>(); for (int i = 0; i < b.Cmds.Count; i++) { Cmd cmd = b.Cmds[i]; if (cmd is YieldCmd) { yieldCmd = (YieldCmd)cmd; continue; } if (yieldCmd != null) { PredicateCmd pcmd = cmd as PredicateCmd; if (pcmd == null) { DesugarYield(yieldCmd, cmds, newCmds, ogOldGlobalMap, domainNameToInputVar, domainNameToLocalVar); if (cmds.Count > 0) { yields.Add(cmds); cmds = new List<Cmd>(); } yieldCmd = null; } else { cmds.Add(pcmd); } } if (cmd is CallCmd) { CallCmd callCmd = cmd as CallCmd; if (yieldingProcs.Contains(callCmd.Proc)) { AddCallToYieldProc(callCmd.tok, newCmds, ogOldGlobalMap, domainNameToLocalVar); } if (callCmd.IsAsync) { if (!asyncAndParallelCallDesugarings.ContainsKey(callCmd.Proc.Name)) { asyncAndParallelCallDesugarings[callCmd.Proc.Name] = new Procedure(Token.NoToken, string.Format("DummyAsyncTarget_{0}", callCmd.Proc.Name), callCmd.Proc.TypeParameters, callCmd.Proc.InParams, callCmd.Proc.OutParams, callCmd.Proc.Requires, new List<IdentifierExpr>(), new List<Ensures>()); } var dummyAsyncTargetProc = asyncAndParallelCallDesugarings[callCmd.Proc.Name]; CallCmd dummyCallCmd = new CallCmd(callCmd.tok, dummyAsyncTargetProc.Name, callCmd.Ins, callCmd.Outs, callCmd.Attributes); dummyCallCmd.Proc = dummyAsyncTargetProc; newCmds.Add(dummyCallCmd); } else { newCmds.Add(callCmd); } if (yieldingProcs.Contains(callCmd.Proc)) { HashSet<Variable> availableLinearVars = new HashSet<Variable>(AvailableLinearVars(callCmd)); linearTypeChecker.AddAvailableVars(callCmd, availableLinearVars); if (!callCmd.IsAsync && globalMods.Count > 0 && pc != null) { // assume pc || alpha(i, g); Expr assumeExpr = Expr.Or(Expr.Ident(pc), alpha); assumeExpr.Type = Type.Bool; newCmds.Add(new AssumeCmd(Token.NoToken, assumeExpr)); } Dictionary<string, Expr> domainNameToExpr = ComputeAvailableExprs(availableLinearVars, domainNameToInputVar); AddUpdatesToOldGlobalVars(newCmds, ogOldGlobalMap, domainNameToLocalVar, domainNameToExpr); } } else if (cmd is ParCallCmd) { ParCallCmd parCallCmd = cmd as ParCallCmd; AddCallToYieldProc(parCallCmd.tok, newCmds, ogOldGlobalMap, domainNameToLocalVar); DesugarParallelCallCmd(newCmds, parCallCmd); HashSet<Variable> availableLinearVars = new HashSet<Variable>(AvailableLinearVars(parCallCmd)); linearTypeChecker.AddAvailableVars(parCallCmd, availableLinearVars); if (globalMods.Count > 0 && pc != null) { // assume pc || alpha(i, g); Expr assumeExpr = Expr.Or(Expr.Ident(pc), alpha); assumeExpr.Type = Type.Bool; newCmds.Add(new AssumeCmd(Token.NoToken, assumeExpr)); } Dictionary<string, Expr> domainNameToExpr = ComputeAvailableExprs(availableLinearVars, domainNameToInputVar); AddUpdatesToOldGlobalVars(newCmds, ogOldGlobalMap, domainNameToLocalVar, domainNameToExpr); } else { newCmds.Add(cmd); } } if (yieldCmd != null) { DesugarYield(yieldCmd, cmds, newCmds, ogOldGlobalMap, domainNameToInputVar, domainNameToLocalVar); if (cmds.Count > 0) { yields.Add(cmds); cmds = new List<Cmd>(); } } if (b.TransferCmd is ReturnCmd) { AddCallToYieldProc(b.TransferCmd.tok, newCmds, ogOldGlobalMap, domainNameToLocalVar); if (pc != null) { AssertCmd assertCmd = new AssertCmd(b.TransferCmd.tok, Expr.Ident(ok)); assertCmd.ErrorData = "Failed to execute atomic action before procedure return"; newCmds.Add(assertCmd); } } b.Cmds = newCmds; } return yields; }
private void AddYieldProcAndImpl(List<Declaration> decls) { if (yieldProc == null) return; Program program = linearTypeChecker.program; List<Variable> inputs = new List<Variable>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { var domain = linearTypeChecker.linearDomains[domainName]; Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "linear_" + domainName + "_in", new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { domain.elementType }, Type.Bool)), true); inputs.Add(f); } foreach (IdentifierExpr ie in globalMods) { Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", ie.Decl.Name), ie.Decl.TypedIdent.Type), true); inputs.Add(f); } List<Block> blocks = new List<Block>(); TransferCmd transferCmd = new ReturnCmd(Token.NoToken); if (yieldCheckerProcs.Count > 0) { List<Block> blockTargets = new List<Block>(); List<String> labelTargets = new List<String>(); int labelCount = 0; foreach (Procedure proc in yieldCheckerProcs) { List<Expr> exprSeq = new List<Expr>(); foreach (Variable v in inputs) { exprSeq.Add(Expr.Ident(v)); } CallCmd callCmd = new CallCmd(Token.NoToken, proc.Name, exprSeq, new List<IdentifierExpr>()); callCmd.Proc = proc; string label = string.Format("L_{0}", labelCount++); Block block = new Block(Token.NoToken, label, new List<Cmd> { callCmd }, new ReturnCmd(Token.NoToken)); labelTargets.Add(label); blockTargets.Add(block); blocks.Add(block); } transferCmd = new GotoCmd(Token.NoToken, labelTargets, blockTargets); } blocks.Insert(0, new Block(Token.NoToken, "enter", new List<Cmd>(), transferCmd)); var yieldImpl = new Implementation(Token.NoToken, yieldProc.Name, new List<TypeVariable>(), inputs, new List<Variable>(), new List<Variable>(), blocks); yieldImpl.Proc = yieldProc; yieldImpl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); decls.Add(yieldProc); decls.Add(yieldImpl); }
private void AddInitialBlock(Implementation impl, List<Variable> oldPcs, List<Variable> oldOks, Dictionary<string, Variable> domainNameToInputVar, Dictionary<string, Variable> domainNameToLocalVar, Dictionary<Variable, Variable> ogOldGlobalMap) { // Add initial block List<AssignLhs> lhss = new List<AssignLhs>(); List<Expr> rhss = new List<Expr>(); if (pc != null) { lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(pc))); rhss.Add(Expr.False); foreach (Variable oldPc in oldPcs) { lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(oldPc))); rhss.Add(Expr.False); } lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(ok))); rhss.Add(Expr.False); foreach (Variable oldOk in oldOks) { lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(oldOk))); rhss.Add(Expr.False); } } Dictionary<string, Expr> domainNameToExpr = new Dictionary<string, Expr>(); foreach (var domainName in linearTypeChecker.linearDomains.Keys) { domainNameToExpr[domainName] = Expr.Ident(domainNameToInputVar[domainName]); } for (int i = 0; i < impl.InParams.Count - linearTypeChecker.linearDomains.Count; i++) { Variable v = impl.InParams[i]; var domainName = linearTypeChecker.FindDomainName(v); if (domainName == null) continue; if (!linearTypeChecker.linearDomains.ContainsKey(domainName)) continue; var domain = linearTypeChecker.linearDomains[domainName]; if (!domain.collectors.ContainsKey(v.TypedIdent.Type)) continue; Expr ie = new NAryExpr(Token.NoToken, new FunctionCall(domain.collectors[v.TypedIdent.Type]), new List<Expr> { Expr.Ident(v) }); domainNameToExpr[domainName] = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapOrBool), new List<Expr> { ie, domainNameToExpr[domainName] }); } foreach (string domainName in linearTypeChecker.linearDomains.Keys) { lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(domainNameToLocalVar[domainName]))); rhss.Add(domainNameToExpr[domainName]); } foreach (Variable g in ogOldGlobalMap.Keys) { lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(ogOldGlobalMap[g]))); rhss.Add(Expr.Ident(g)); } if (lhss.Count > 0) { Block initBlock = new Block(Token.NoToken, "og_init", new List<Cmd> { new AssignCmd(Token.NoToken, lhss, rhss) }, new GotoCmd(Token.NoToken, new List<String> { impl.Blocks[0].Label }, new List<Block> { impl.Blocks[0] })); impl.Blocks.Insert(0, initBlock); } }
public override Procedure VisitProcedure(Procedure node) { if (!civlTypeChecker.procToActionInfo.ContainsKey(node)) return node; if (!procMap.ContainsKey(node)) { enclosingProc = node; Procedure proc = (Procedure)node.Clone(); proc.Name = string.Format("{0}_{1}", node.Name, layerNum); proc.InParams = this.VisitVariableSeq(node.InParams); proc.Modifies = this.VisitIdentifierExprSeq(node.Modifies); proc.OutParams = this.VisitVariableSeq(node.OutParams); ActionInfo actionInfo = civlTypeChecker.procToActionInfo[node]; if (actionInfo.createdAtLayerNum < layerNum) { proc.Requires = new List<Requires>(); proc.Ensures = new List<Ensures>(); Implementation impl; AtomicActionInfo atomicActionInfo = actionInfo as AtomicActionInfo; if (atomicActionInfo != null) { CodeExpr action = (CodeExpr)VisitCodeExpr(atomicActionInfo.action); List<Cmd> cmds = new List<Cmd>(); foreach (AssertCmd assertCmd in atomicActionInfo.gate) { cmds.Add(new AssumeCmd(Token.NoToken, (Expr)Visit(assertCmd.Expr))); } Block newInitBlock = new Block(Token.NoToken, "_init", cmds, new GotoCmd(Token.NoToken, new List<string>(new string[] { action.Blocks[0].Label }), new List<Block>(new Block[] { action.Blocks[0] }))); List<Block> newBlocks = new List<Block>(); newBlocks.Add(newInitBlock); newBlocks.AddRange(action.Blocks); impl = new Implementation(Token.NoToken, proc.Name, node.TypeParameters, node.InParams, node.OutParams, action.LocVars, newBlocks); } else { Block newInitBlock = new Block(Token.NoToken, "_init", new List<Cmd>(), new ReturnCmd(Token.NoToken)); List<Block> newBlocks = new List<Block>(); newBlocks.Add(newInitBlock); impl = new Implementation(Token.NoToken, proc.Name, node.TypeParameters, node.InParams, node.OutParams, new List<Variable>(), newBlocks); } impl.Proc = proc; impl.Proc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); impl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); impls.Add(impl); } else { yieldingProcs.Add(proc); proc.Requires = this.VisitRequiresSeq(node.Requires); proc.Ensures = this.VisitEnsuresSeq(node.Ensures); } procMap[node] = proc; proc.Modifies = new List<IdentifierExpr>(); civlTypeChecker.SharedVariables.Iter(x => proc.Modifies.Add(Expr.Ident(x))); } return procMap[node]; }
public override Implementation VisitImplementation(Implementation node) { enclosingImpl = node; dummyLocalVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "og_dummy", Type.Bool)); Implementation impl = base.VisitImplementation(node); implMap[impl] = node; impl.LocVars.Add(dummyLocalVar); impl.Name = impl.Proc.Name; return impl; }
public static void Predicate(Program p, Implementation impl) { try { new SmartBlockPredicator(p, impl, proc => false, null).PredicateImplementation(); } catch (Program.IrreducibleLoopException) { } }
/// <summary> /// /// </summary> public override void TraverseChildren(IMethodDefinition method) { if (method.IsStaticConstructor) { this.sawCctor = true; } bool isEventAddOrRemove = method.IsSpecialName && (method.Name.Value.StartsWith("add_") || method.Name.Value.StartsWith("remove_")); if (isEventAddOrRemove) { return; } Sink.ProcedureInfo procInfo; IMethodDefinition stubMethod = null; if (IsStubMethod(method, out stubMethod)) { procInfo = this.sink.FindOrCreateProcedure(stubMethod); } else { procInfo = this.sink.FindOrCreateProcedure(method); } if (method.IsAbstract || method.IsExternal) // we're done, just define the procedure { return; } this.sink.BeginMethod(method); var decl = procInfo.Decl; var proc = decl as Bpl.Procedure; var formalMap = procInfo.FormalMap; if (this.entryPoint != null && method.InternedKey == this.entryPoint.InternedKey) { decl.AddAttribute("entrypoint"); } // FEEDBACK inline handler methods to avoid more false alarms if (PhoneCodeHelper.instance().PhoneFeedbackToggled&& PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(method) && !PhoneCodeHelper.instance().isMethodIgnoredForFeedback(method)) { proc.AddAttribute("inline", new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.ONE)); PhoneCodeHelper.instance().trackCallableMethod(proc); } try { StatementTraverser stmtTraverser = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false); // FEEDBACK if this is a feedback method it will be plagued with false asserts. They will trigger if $Exception becomes other than null // FEEDBACK for modular analysis we need it to be non-null at the start // FEEDBACK also, callee is obviously non null IMethodDefinition translatedMethod = sink.getMethodBeingTranslated(); if (PhoneCodeHelper.instance().PhoneFeedbackToggled&& translatedMethod != null && PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(translatedMethod)) { // assign null to exception List <Bpl.AssignLhs> assignee = new List <Bpl.AssignLhs>(); Bpl.AssignLhs exceptionAssignee = new Bpl.SimpleAssignLhs(Bpl.Token.NoToken, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)); assignee.Add(exceptionAssignee); List <Bpl.Expr> value = new List <Bpl.Expr>(); value.Add(Bpl.Expr.Ident(this.sink.Heap.NullRef)); Bpl.Cmd exceptionAssign = new Bpl.AssignCmd(Bpl.Token.NoToken, assignee, value); stmtTraverser.StmtBuilder.Add(exceptionAssign); } #region Add assignments from In-Params to local-Params foreach (MethodParameter mparam in formalMap) { if (mparam.inParameterCopy != null) { Bpl.IToken tok = method.Token(); stmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, new Bpl.IdentifierExpr(tok, mparam.outParameterCopy), new Bpl.IdentifierExpr(tok, mparam.inParameterCopy))); } } #endregion #region For non-deferring ctors and all cctors, initialize all fields to null-equivalent values var inits = InitializeFieldsInConstructor(method); if (0 < inits.Count) { foreach (var s in inits) { stmtTraverser.Traverse(s); } } #endregion #region Translate method attributes // Don't need an expression translator because there is a limited set of things // that can appear as arguments to custom attributes // TODO: decode enum values try { foreach (var a in method.Attributes) { var attrName = TypeHelper.GetTypeName(a.Type); if (attrName.EndsWith("Attribute")) { attrName = attrName.Substring(0, attrName.Length - 9); } var args = new List <object>(); foreach (var c in a.Arguments) { var mdc = c as IMetadataConstant; if (mdc != null) { object o; if (mdc.Type.IsEnum) { var lit = Bpl.Expr.Literal((int)mdc.Value); lit.Type = Bpl.Type.Int; o = lit; } else { switch (mdc.Type.TypeCode) { case PrimitiveTypeCode.Boolean: o = (bool)mdc.Value ? Bpl.Expr.True : Bpl.Expr.False; break; case PrimitiveTypeCode.Int32: var lit = Bpl.Expr.Literal((int)mdc.Value); lit.Type = Bpl.Type.Int; o = lit; break; case PrimitiveTypeCode.String: o = mdc.Value; break; default: throw new InvalidCastException("Invalid metadata constant type"); } } args.Add(o); } } decl.AddAttribute(attrName, args.ToArray()); } } catch (InvalidCastException) { Console.WriteLine("Warning: Cannot translate custom attributes for method\n '{0}':", MemberHelper.GetMethodSignature(method, NameFormattingOptions.None)); Console.WriteLine(" >>Skipping attributes, continuing with method translation"); } #endregion #region Translate body var helperTypes = stmtTraverser.TranslateMethod(method); if (helperTypes != null) { this.privateTypes.AddRange(helperTypes); } #endregion #region Create Local Vars For Implementation List <Bpl.Variable> vars = new List <Bpl.Variable>(); foreach (MethodParameter mparam in formalMap) { if (!mparam.underlyingParameter.IsByReference) { vars.Add(mparam.outParameterCopy); } } foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) { vars.Add(v); } // LocalExcVariable holds the exception thrown by any method called from this method, even if this method swallows all exceptions if (0 < this.sink.Options.modelExceptions) { vars.Add(procInfo.LocalExcVariable); } vars.Add(procInfo.LabelVariable); List <Bpl.Variable> vseq = new List <Bpl.Variable>(vars.ToArray()); #endregion var translatedBody = stmtTraverser.StmtBuilder.Collect(Bpl.Token.NoToken); #region Add implementation to Boogie program if (proc != null) { Bpl.Implementation impl = new Bpl.Implementation(method.Token(), decl.Name, new List <Bpl.TypeVariable>(), decl.InParams, decl.OutParams, vseq, translatedBody); impl.Proc = proc; this.sink.TranslatedProgram.AddTopLevelDeclaration(impl); } else // method is translated as a function //var func = decl as Bpl.Function; //Contract.Assume(func != null); //var blocks = new List<Bpl.Block>(); //var counter = 0; //var returnValue = decl.OutParams[0]; //foreach (var bb in translatedBody.BigBlocks) { // var label = bb.LabelName ?? "L" + counter++.ToString(); // var newTransferCmd = (bb.tc is Bpl.ReturnCmd) // ? new Bpl.ReturnExprCmd(bb.tc.tok, Bpl.Expr.Ident(returnValue)) // : bb.tc; // var b = new Bpl.Block(bb.tok, label, bb.simpleCmds, newTransferCmd); // blocks.Add(b); //} //var localVars = new List<Bpl.Variable>(); //localVars.Add(returnValue); //func.Body = new Bpl.CodeExpr(localVars, blocks); { } #endregion } catch (TranslationException te) { Console.WriteLine("Translation error in body of \n '{0}':", MemberHelper.GetMethodSignature(method, NameFormattingOptions.None)); Console.WriteLine("\t" + te.Message); } catch (Exception e) { Console.WriteLine("Error encountered during translation of \n '{0}':", MemberHelper.GetMethodSignature(method, NameFormattingOptions.None)); Console.WriteLine("\t>>" + e.Message); } finally { } }
private void ProcessLoopHeaders(Implementation impl, Graph<Block> graph, HashSet<Block> yieldingHeaders, Dictionary<string, Variable> domainNameToInputVar, Dictionary<string, Variable> domainNameToLocalVar, Dictionary<Variable, Variable> ogOldGlobalMap, out List<Variable> oldPcs, out List<Variable> oldOks) { oldPcs = new List<Variable>(); oldOks = new List<Variable>(); foreach (Block header in yieldingHeaders) { LocalVariable oldPc = null; LocalVariable oldOk = null; if (pc != null) { oldPc = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("{0}_{1}", pc.Name, header.Label), Type.Bool)); oldPcs.Add(oldPc); oldOk = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("{0}_{1}", ok.Name, header.Label), Type.Bool)); oldOks.Add(oldOk); } Dictionary<string, Expr> domainNameToExpr = ComputeAvailableExprs(AvailableLinearVars(header), domainNameToInputVar); foreach (Block pred in header.Predecessors) { AddCallToYieldProc(header.tok, pred.Cmds, ogOldGlobalMap, domainNameToLocalVar); if (pc != null && !graph.BackEdgeNodes(header).Contains(pred)) { pred.Cmds.Add(new AssignCmd(Token.NoToken, new List<AssignLhs>( new AssignLhs[] { new SimpleAssignLhs(Token.NoToken, Expr.Ident(oldPc)), new SimpleAssignLhs(Token.NoToken, Expr.Ident(oldOk)) }), new List<Expr>(new Expr[] { Expr.Ident(pc), Expr.Ident(ok) }))); } AddUpdatesToOldGlobalVars(pred.Cmds, ogOldGlobalMap, domainNameToLocalVar, domainNameToExpr); } List<Cmd> newCmds = new List<Cmd>(); if (pc != null) { AssertCmd assertCmd; assertCmd = new AssertCmd(header.tok, Expr.Eq(Expr.Ident(oldPc), Expr.Ident(pc))); assertCmd.ErrorData = "Specification state must not change for transitions ending in loop headers"; newCmds.Add(assertCmd); assertCmd = new AssertCmd(header.tok, Expr.Imp(Expr.Ident(oldOk), Expr.Ident(ok))); assertCmd.ErrorData = "Specification state must not change for transitions ending in loop headers"; newCmds.Add(assertCmd); } foreach (string domainName in linearTypeChecker.linearDomains.Keys) { newCmds.Add(new AssumeCmd(Token.NoToken, Expr.Eq(Expr.Ident(domainNameToLocalVar[domainName]), domainNameToExpr[domainName]))); } foreach (Variable v in ogOldGlobalMap.Keys) { newCmds.Add(new AssumeCmd(Token.NoToken, Expr.Eq(Expr.Ident(v), Expr.Ident(ogOldGlobalMap[v])))); } newCmds.AddRange(header.Cmds); header.Cmds = newCmds; } }
private Graph<Block> ComputeYieldingLoopHeaders(Implementation impl, out HashSet<Block> yieldingHeaders) { Graph<Block> graph; impl.PruneUnreachableBlocks(); impl.ComputePredecessorsForBlocks(); graph = Program.GraphFromImpl(impl); graph.ComputeLoops(); if (!graph.Reducible) { throw new Exception("Irreducible flow graphs are unsupported."); } yieldingHeaders = new HashSet<Block>(); IEnumerable<Block> sortedHeaders = graph.SortHeadersByDominance(); foreach (Block header in sortedHeaders) { if (yieldingHeaders.Any(x => graph.DominatorMap.DominatedBy(x, header))) { yieldingHeaders.Add(header); } else if (IsYieldingHeader(graph, header)) { yieldingHeaders.Add(header); } else { continue; } } return graph; }
/// <summary> /// /// </summary> public override void TraverseChildren(IMethodDefinition method) { if (TranslationHelper.HasAttribute(method, "BCTOmitAttribute")) { return; } if (method.IsStaticConstructor) { this.sawCctor = true; } bool isEventAddOrRemove = method.IsSpecialName && (method.Name.Value.StartsWith("add_") || method.Name.Value.StartsWith("remove_")); if (isEventAddOrRemove) { return; } Sink.ProcedureInfo procInfo; IMethodDefinition stubMethod = null; if (IsStubMethod(method, out stubMethod)) { procInfo = this.sink.FindOrCreateProcedure(stubMethod); } else { procInfo = this.sink.FindOrCreateProcedure(method); } if (method.IsAbstract || method.IsExternal || TranslationHelper.HasAttribute(method, "BCTOmitImplementationAttribute") // CCI is currently hacked to skip decompiling all method bodies in // compiler-generated classes. This is nontrivial to test for here, so // just omit implementation of all methods whose bodies haven't been // decompiled, at risk of silently hiding other problems. || !(method.Body is ISourceMethodBody)) { // we're done, just define the procedure return; } this.sink.BeginMethod(method); var decl = procInfo.Decl; var proc = decl as Bpl.Procedure; var formalMap = procInfo.FormalMap; if (this.entryPoint != null && method.InternedKey == this.entryPoint.InternedKey) { decl.AddAttribute("entrypoint"); } try { StatementTraverser stmtTraverser = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false); // Manually set the beginning of the method as the source location for // BCT synthetic code until we traverse the first real statement, which // will automatically pick up its source location. Needed for record // calls to show up in the trace. stmtTraverser.EmitSourceContext(method); if (!method.IsStatic) { stmtTraverser.AddRecordCall("this", sink.CciTypeToBoogie(method.ContainingType), new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.ThisVariable)); } #region Add assignments from In-Params to local-Params foreach (MethodParameter mparam in formalMap) { if (mparam.inParameterCopy != null) { Bpl.IToken tok = method.Token(); Bpl.Expr rhs = new Bpl.IdentifierExpr(tok, mparam.inParameterCopy); stmtTraverser.AddRecordCall(mparam.underlyingParameter.Name.Value, mparam.inParameterCopy.TypedIdent.Type, rhs); stmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, new Bpl.IdentifierExpr(tok, mparam.outParameterCopy), rhs)); } } #endregion #region For non-deferring ctors and all cctors, initialize all fields to null-equivalent values var inits = InitializeFieldsInConstructor(method); if (0 < inits.Count) { foreach (var s in inits) { stmtTraverser.Traverse(s); } } #endregion #region Translate method attributes // Don't need an expression translator because there is a limited set of things // that can appear as arguments to custom attributes // TODO: decode enum values try { foreach (var a in method.Attributes) { var attrName = TypeHelper.GetTypeName(a.Type); if (attrName.EndsWith("Attribute")) { attrName = attrName.Substring(0, attrName.Length - 9); } var args = new List <object>(); foreach (var c in a.Arguments) { var mdc = c as IMetadataConstant; if (mdc != null) { object o; if (mdc.Type.IsEnum) { var lit = Bpl.Expr.Literal((int)mdc.Value); lit.Type = Bpl.Type.Int; o = lit; } else { switch (mdc.Type.TypeCode) { case PrimitiveTypeCode.Boolean: o = (bool)mdc.Value ? Bpl.Expr.True : Bpl.Expr.False; break; case PrimitiveTypeCode.Int32: var lit = Bpl.Expr.Literal((int)mdc.Value); lit.Type = Bpl.Type.Int; o = lit; break; case PrimitiveTypeCode.String: o = mdc.Value; break; default: throw new InvalidCastException("Invalid metadata constant type"); } } args.Add(o); } } decl.AddAttribute(attrName, args.ToArray()); } } catch (InvalidCastException) { Console.WriteLine("Warning: Cannot translate custom attributes for method\n '{0}':", MemberHelper.GetMethodSignature(method, NameFormattingOptions.None)); Console.WriteLine(" >>Skipping attributes, continuing with method translation"); } #endregion #region Translate body var helperTypes = stmtTraverser.TranslateMethod(method); if (helperTypes != null) { this.privateTypes.AddRange(helperTypes); } #endregion #region Create Local Vars For Implementation List <Bpl.Variable> vars = new List <Bpl.Variable>(); foreach (MethodParameter mparam in formalMap) { if (!mparam.underlyingParameter.IsByReference) { vars.Add(mparam.outParameterCopy); } } foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) { vars.Add(v); } // LocalExcVariable holds the exception thrown by any method called from this method, even if this method swallows all exceptions if (0 < this.sink.Options.modelExceptions) { vars.Add(procInfo.LocalExcVariable); } vars.Add(procInfo.LabelVariable); List <Bpl.Variable> vseq = new List <Bpl.Variable>(vars.ToArray()); #endregion var translatedBody = stmtTraverser.StmtBuilder.Collect(Bpl.Token.NoToken); #region Add implementation to Boogie program if (proc != null) { Bpl.Implementation impl = new Bpl.Implementation(method.Token(), decl.Name, new List <Bpl.TypeVariable>(), decl.InParams, decl.OutParams, vseq, translatedBody); impl.Proc = proc; this.sink.TranslatedProgram.AddTopLevelDeclaration(impl); } else // method is translated as a function //var func = decl as Bpl.Function; //Contract.Assume(func != null); //var blocks = new List<Bpl.Block>(); //var counter = 0; //var returnValue = decl.OutParams[0]; //foreach (var bb in translatedBody.BigBlocks) { // var label = bb.LabelName ?? "L" + counter++.ToString(); // var newTransferCmd = (bb.tc is Bpl.ReturnCmd) // ? new Bpl.ReturnExprCmd(bb.tc.tok, Bpl.Expr.Ident(returnValue)) // : bb.tc; // var b = new Bpl.Block(bb.tok, label, bb.simpleCmds, newTransferCmd); // blocks.Add(b); //} //var localVars = new List<Bpl.Variable>(); //localVars.Add(returnValue); //func.Body = new Bpl.CodeExpr(localVars, blocks); { } #endregion } catch (TranslationException te) { Console.WriteLine("Translation error in body of \n '{0}':", MemberHelper.GetMethodSignature(method, NameFormattingOptions.None)); Console.WriteLine("\t" + te.Message + "\n" + te.StackTrace); } catch (Exception e) { Console.WriteLine("Error encountered during translation of \n '{0}':", MemberHelper.GetMethodSignature(method, NameFormattingOptions.None)); Console.WriteLine("\t>>" + e.Message + "\n" + e.StackTrace); } finally { } }
private List<Expr> CreateAssertsExprs(Implementation queryImplementation, Implementation targetImplementation) { var result = new List<Expr>(); queryImplementation.LocVars.Iter(v => { var type = Utils.BoogieUtils.GetExprType(Expr.Ident(v)); if (type != null) targetImplementation.LocVars.Iter(v2 => { if (type.Equals(Utils.BoogieUtils.GetExprType(Expr.Ident(v2)))) result.Add(Expr.Eq(Expr.Ident(v), Expr.Ident(v2))); }); }); return result; }
public override Implementation VisitImplementation(Implementation node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Implementation>() != null); var impl = base.VisitImplementation((Implementation)node.Clone()); var blockDuplicationMapping = new Dictionary<Block, Block>(); // Compute the mapping between the blocks of the old implementation (node) // and the new implementation (impl). foreach (var blockPair in node.Blocks.Zip(impl.Blocks)) { blockDuplicationMapping.Add(blockPair.Item1, blockPair.Item2); } // The GotoCmds and blocks have now been duplicated. // Resolve GotoCmd targets to the duplicated blocks foreach (GotoCmd gotoCmd in impl.Blocks.Select( bb => bb.TransferCmd).OfType<GotoCmd>()) { var newLabelTargets = new List<Block>(); var newLabelNames = new List<string>(); for (int index = 0; index < gotoCmd.labelTargets.Count; ++index) { var newBlock = blockDuplicationMapping[gotoCmd.labelTargets[index]]; newLabelTargets.Add(newBlock); newLabelNames.Add(newBlock.Label); } gotoCmd.labelTargets = newLabelTargets; gotoCmd.labelNames = newLabelNames; } return impl; }
private void TransformImpl(Implementation impl) { HashSet<Block> yieldingHeaders; Graph<Block> graph = ComputeYieldingLoopHeaders(impl, out yieldingHeaders); List<Variable> newLocalVars; Dictionary<string, Variable> domainNameToInputVar, domainNameToLocalVar; Dictionary<Variable, Variable> ogOldGlobalMap; SetupRefinementCheck(impl, out newLocalVars, out domainNameToInputVar, out domainNameToLocalVar, out ogOldGlobalMap); List<List<Cmd>> yields = CollectAndDesugarYields(impl, domainNameToInputVar, domainNameToLocalVar, ogOldGlobalMap); List<Variable> oldPcs, oldOks; ProcessLoopHeaders(impl, graph, yieldingHeaders, domainNameToInputVar, domainNameToLocalVar, ogOldGlobalMap, out oldPcs, out oldOks); AddInitialBlock(impl, oldPcs, oldOks, domainNameToInputVar, domainNameToLocalVar, ogOldGlobalMap); CreateYieldCheckerImpl(impl, yields); impl.LocVars.AddRange(newLocalVars); impl.LocVars.AddRange(oldPcs); impl.LocVars.AddRange(oldOks); UnifyCallsToYieldProc(impl, ogOldGlobalMap, domainNameToLocalVar); }
public override bpl.Implementation VisitImplementation(bpl.Implementation node) { curProc = node.Name; callGraph[curProc] = new Dictionary <string, int>(); return(base.VisitImplementation(node)); }
private void CreateYieldCheckerImpl(Implementation impl, List<List<Cmd>> yields) { if (yields.Count == 0) return; Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); foreach (Variable local in impl.LocVars) { var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, local.Name, local.TypedIdent.Type)); map[local] = Expr.Ident(copy); } Program program = linearTypeChecker.program; List<Variable> locals = new List<Variable>(); List<Variable> inputs = new List<Variable>(); foreach (IdentifierExpr ie in map.Values) { locals.Add(ie.Decl); } for (int i = 0; i < impl.InParams.Count - linearTypeChecker.linearDomains.Count; i++) { Variable inParam = impl.InParams[i]; Variable copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type)); locals.Add(copy); map[impl.InParams[i]] = Expr.Ident(copy); } { int i = impl.InParams.Count - linearTypeChecker.linearDomains.Count; foreach (string domainName in linearTypeChecker.linearDomains.Keys) { Variable inParam = impl.InParams[i]; Variable copy = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type), true); inputs.Add(copy); map[impl.InParams[i]] = Expr.Ident(copy); i++; } } for (int i = 0; i < impl.OutParams.Count; i++) { Variable outParam = impl.OutParams[i]; var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, outParam.Name, outParam.TypedIdent.Type)); locals.Add(copy); map[impl.OutParams[i]] = Expr.Ident(copy); } Dictionary<Variable, Expr> ogOldLocalMap = new Dictionary<Variable, Expr>(); Dictionary<Variable, Expr> assumeMap = new Dictionary<Variable, Expr>(map); foreach (IdentifierExpr ie in globalMods) { Variable g = ie.Decl; var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_local_old_{0}", g.Name), g.TypedIdent.Type)); locals.Add(copy); ogOldLocalMap[g] = Expr.Ident(copy); Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", g.Name), g.TypedIdent.Type), true); inputs.Add(f); assumeMap[g] = Expr.Ident(f); } Substitution assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap); Substitution oldSubst = Substituter.SubstitutionFromHashtable(ogOldLocalMap); Substitution subst = Substituter.SubstitutionFromHashtable(map); List<Block> yieldCheckerBlocks = new List<Block>(); List<String> labels = new List<String>(); List<Block> labelTargets = new List<Block>(); Block yieldCheckerBlock = new Block(Token.NoToken, "exit", new List<Cmd>(), new ReturnCmd(Token.NoToken)); labels.Add(yieldCheckerBlock.Label); labelTargets.Add(yieldCheckerBlock); yieldCheckerBlocks.Add(yieldCheckerBlock); int yieldCount = 0; foreach (List<Cmd> cs in yields) { List<Cmd> newCmds = new List<Cmd>(); foreach (Cmd cmd in cs) { PredicateCmd predCmd = (PredicateCmd)cmd; newCmds.Add(new AssumeCmd(Token.NoToken, Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr))); } foreach (Cmd cmd in cs) { PredicateCmd predCmd = (PredicateCmd)cmd; var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr); if (predCmd is AssertCmd) { AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes); assertCmd.ErrorData = "Non-interference check failed"; newCmds.Add(assertCmd); } else { newCmds.Add(new AssumeCmd(Token.NoToken, newExpr)); } } newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False)); yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken)); labels.Add(yieldCheckerBlock.Label); labelTargets.Add(yieldCheckerBlock); yieldCheckerBlocks.Add(yieldCheckerBlock); } yieldCheckerBlocks.Insert(0, new Block(Token.NoToken, "enter", new List<Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets))); // Create the yield checker procedure var yieldCheckerName = string.Format("{0}_YieldChecker_{1}", "Impl", impl.Name); var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), new List<Requires>(), new List<IdentifierExpr>(), new List<Ensures>()); yieldCheckerProc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); yieldCheckerProcs.Add(yieldCheckerProc); // Create the yield checker implementation var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), locals, yieldCheckerBlocks); yieldCheckerImpl.Proc = yieldCheckerProc; yieldCheckerImpl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); yieldCheckerImpls.Add(yieldCheckerImpl); }
public Bpl.Procedure addHandlerStubCaller(Sink sink, IMethodDefinition def) { MethodBody callerBody = new MethodBody(); MethodDefinition callerDef = new MethodDefinition() { InternFactory = (def as MethodDefinition).InternFactory, ContainingTypeDefinition = def.ContainingTypeDefinition, IsStatic = true, Name = sink.host.NameTable.GetNameFor("BOOGIE_STUB_CALLER_" + def.Name.Value), Type = sink.host.PlatformType.SystemVoid, Body = callerBody, }; callerBody.MethodDefinition = callerDef; Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(def); Sink.ProcedureInfo callerInfo = sink.FindOrCreateProcedure(callerDef); Bpl.LocalVariable[] localVars = new Bpl.LocalVariable[procInfo.Decl.InParams.Count]; Bpl.IdentifierExpr[] varExpr = new Bpl.IdentifierExpr[procInfo.Decl.InParams.Count]; for (int i = 0; i < procInfo.Decl.InParams.Count; i++) { Bpl.LocalVariable loc = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, TranslationHelper.GenerateTempVarName(), procInfo.Decl.InParams[i].TypedIdent.Type)); localVars[i] = loc; varExpr[i] = new Bpl.IdentifierExpr(Bpl.Token.NoToken, loc); } Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder(); builder.Add(getResetNavigationCheck(sink)); string pageXaml = PhoneCodeHelper.instance().PhonePlugin.getXAMLForPage(def.ContainingTypeDefinition.ToString()); Bpl.Variable boogieCurrentURI = sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition); Bpl.Constant boogieXamlConstant; if (pageXaml != null) { boogieXamlConstant = sink.FindOrCreateConstant(pageXaml); } else { boogieXamlConstant = null; } // NAVIGATION TODO: For now just assume we are in this page to be able to call the handler, this is NOT true for any handler // NAVIGATION TODO: ie, a network event handler if (boogieXamlConstant != null) { Bpl.AssumeCmd assumeCurrentPage = new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI), new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant))); builder.Add(assumeCurrentPage); } // NAVIGATION TODO: have to do the pair generation all in one go instead of having different files that need to be sed'ed boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER); Bpl.AssumeCmd assumeStartPage = new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI), new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant))); builder.Add(assumeStartPage); builder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new List <Bpl.Expr>(varExpr), new List <Bpl.IdentifierExpr>())); boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER); Bpl.AssertCmd assertEndPage = new Bpl.AssertCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI), new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant))); Bpl.Expr guard = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool)); Bpl.StmtListBuilder thenBuilder = new Bpl.StmtListBuilder(); thenBuilder.Add(assertEndPage); Bpl.IfCmd ifNavigated = new Bpl.IfCmd(Bpl.Token.NoToken, guard, thenBuilder.Collect(Bpl.Token.NoToken), null, new Bpl.StmtListBuilder().Collect(Bpl.Token.NoToken)); builder.Add(ifNavigated); Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, callerInfo.Decl.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(localVars), builder.Collect(Bpl.Token.NoToken), null, new Bpl.Errors()); sink.TranslatedProgram.AddTopLevelDeclaration(impl); return(impl.Proc); }
private void SetupRefinementCheck(Implementation impl, out List<Variable> newLocalVars, out Dictionary<string, Variable> domainNameToInputVar, out Dictionary<string, Variable> domainNameToLocalVar, out Dictionary<Variable, Variable> ogOldGlobalMap) { pc = null; ok = null; alpha = null; beta = null; frame = null; newLocalVars = new List<Variable>(); Program program = linearTypeChecker.program; ogOldGlobalMap = new Dictionary<Variable, Variable>(); foreach (IdentifierExpr ie in globalMods) { Variable g = ie.Decl; LocalVariable l = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", g.Name), g.TypedIdent.Type)); ogOldGlobalMap[g] = l; newLocalVars.Add(l); } Procedure originalProc = implMap[impl].Proc; ActionInfo actionInfo = civlTypeChecker.procToActionInfo[originalProc]; if (actionInfo.createdAtLayerNum == this.layerNum) { pc = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "og_pc", Type.Bool)); newLocalVars.Add(pc); ok = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "og_ok", Type.Bool)); newLocalVars.Add(ok); Dictionary<Variable, Expr> alwaysMap = new Dictionary<Variable, Expr>(); for (int i = 0; i < originalProc.InParams.Count; i++) { alwaysMap[originalProc.InParams[i]] = Expr.Ident(impl.InParams[i]); } for (int i = 0; i < originalProc.OutParams.Count; i++) { alwaysMap[originalProc.OutParams[i]] = Expr.Ident(impl.OutParams[i]); } Substitution always = Substituter.SubstitutionFromHashtable(alwaysMap); Dictionary<Variable, Expr> foroldMap = new Dictionary<Variable, Expr>(); foreach (IdentifierExpr ie in globalMods) { foroldMap[ie.Decl] = Expr.Ident(ogOldGlobalMap[ie.Decl]); } Substitution forold = Substituter.SubstitutionFromHashtable(foroldMap); frame = new HashSet<Variable>(civlTypeChecker.SharedVariables); foreach (Variable v in civlTypeChecker.SharedVariables) { if (civlTypeChecker.globalVarToSharedVarInfo[v].hideLayerNum <= actionInfo.createdAtLayerNum || civlTypeChecker.globalVarToSharedVarInfo[v].introLayerNum > actionInfo.createdAtLayerNum) { frame.Remove(v); } } AtomicActionInfo atomicActionInfo = actionInfo as AtomicActionInfo; if (atomicActionInfo == null) { beta = Expr.True; foreach (var v in frame) { beta = Expr.And(beta, Expr.Eq(Expr.Ident(v), foroldMap[v])); } alpha = Expr.True; } else { Expr betaExpr = (new MoverCheck.TransitionRelationComputation(civlTypeChecker.program, atomicActionInfo, frame, new HashSet<Variable>())).TransitionRelationCompute(true); beta = Substituter.ApplyReplacingOldExprs(always, forold, betaExpr); Expr alphaExpr = Expr.True; foreach (AssertCmd assertCmd in atomicActionInfo.gate) { alphaExpr = Expr.And(alphaExpr, assertCmd.Expr); alphaExpr.Type = Type.Bool; } alpha = Substituter.Apply(always, alphaExpr); } foreach (Variable f in impl.OutParams) { LocalVariable copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_old_{0}", f.Name), f.TypedIdent.Type)); newLocalVars.Add(copy); ogOldGlobalMap[f] = copy; } } domainNameToInputVar = new Dictionary<string, Variable>(); domainNameToLocalVar = new Dictionary<string, Variable>(); { int i = impl.InParams.Count - linearTypeChecker.linearDomains.Count; foreach (string domainName in linearTypeChecker.linearDomains.Keys) { Variable inParam = impl.InParams[i]; domainNameToInputVar[domainName] = inParam; Variable l = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name + "_local", inParam.TypedIdent.Type)); domainNameToLocalVar[domainName] = l; newLocalVars.Add(l); i++; } } }
private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Contract.Assert(type.IsDelegate); IMethodDefinition invokeMethod = null; foreach (IMethodDefinition m in type.Methods) { if (m.Name.Value == "Invoke") { invokeMethod = m; break; } } try { IMethodDefinition unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod; Sink.ProcedureInfo invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod); Bpl.Procedure invokeProcedure = (Bpl.Procedure)invokeProcedureInfo.Decl; invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1)); Bpl.Formal delegateVariable = invokeProcedureInfo.ThisVariable; Bpl.IToken token = invokeMethod.Token(); List <Bpl.Variable> dispatchProcInExprs = new List <Bpl.Variable>(); for (int i = 1; i < invokeProcedure.InParams.Count; i++) { Bpl.Variable v = invokeProcedure.InParams[i]; dispatchProcInExprs.Add(v); } List <Bpl.Variable> dispatchProcOutExprs = new List <Bpl.Variable>(); foreach (Bpl.Variable v in invokeProcedure.OutParams) { dispatchProcOutExprs.Add(v); } List <Bpl.Variable> localVariables = new List <Bpl.Variable>(); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); int localCounter = 0; foreach (IMethodDefinition defn in delegates) { Bpl.Constant c = sink.FindOrCreateDelegateMethodConstant(defn); Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn); Bpl.Procedure delegateProcedure = (Bpl.Procedure)delegateProcedureInfo.Decl; Bpl.Formal thisVariable = delegateProcedureInfo.ThisVariable; int numArguments = defn.ParameterCount; List <Bpl.Variable> tempInputs = new List <Bpl.Variable>(); List <Bpl.Variable> tempOutputs = new List <Bpl.Variable>(); for (int i = 0; i < defn.ParameterCount; i++) { Bpl.Variable v = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i]; Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type)); localVariables.Add(localVariable); tempInputs.Add(localVariable); } for (int i = 0; i < delegateProcedure.OutParams.Count; i++) { Bpl.Variable v = delegateProcedure.OutParams[i]; Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type)); localVariables.Add(localVariable); tempOutputs.Add(localVariable); } List <Bpl.Expr> ins = new List <Bpl.Expr>(); List <Bpl.IdentifierExpr> outs = new List <Bpl.IdentifierExpr>(); if (!defn.IsStatic) { ins.Add(sink.ReadReceiver(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable))); } for (int i = 0; i < tempInputs.Count; i++) { ins.Add(Bpl.Expr.Ident(tempInputs[i])); } if (defn.IsGeneric) { for (int i = 0; i < defn.GenericParameterCount; i++) { ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)), new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) }))); } } if (defn.IsStatic) { int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType); for (int i = 0; i < numTypeParameters; i++) { ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)), new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) }))); } } for (int i = 0; i < tempOutputs.Count; i++) { outs.Add(Bpl.Expr.Ident(tempOutputs[i])); } Bpl.Expr bexpr = sink.ReadMethod(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)); Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder(); System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count); if (tempInputs.Count > 0) { BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs); } ifStmtBuilder.Add(EmitDummySourceContext()); ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs)); System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count); if (tempOutputs.Count > 0) { BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs); } stmtBuilder.Add(new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), null, null)); } Bpl.Implementation dispatchImpl = new Bpl.Implementation(token, invokeProcedure.Name, new List <Bpl.TypeVariable>(), invokeProcedure.InParams, invokeProcedure.OutParams, localVariables, stmtBuilder.Collect(token) ); dispatchImpl.Proc = invokeProcedure; dispatchImpl.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(dispatchImpl); } catch (TranslationException te) { throw new NotImplementedException(te.ToString()); } catch { throw; } finally { // Maybe this is a good place to add the procedure to the toplevel declarations } }
private void UnifyCallsToYieldProc(Implementation impl, Dictionary<Variable, Variable> ogOldGlobalMap, Dictionary<string, Variable> domainNameToLocalVar) { CallCmd yieldCallCmd = CallToYieldProc(Token.NoToken, ogOldGlobalMap, domainNameToLocalVar); Block yieldCheckBlock = new Block(Token.NoToken, "CallToYieldProc", new List<Cmd>(new Cmd[] { yieldCallCmd, new AssumeCmd(Token.NoToken, Expr.False) }), new ReturnCmd(Token.NoToken)); List<Block> newBlocks = new List<Block>(); foreach (Block b in impl.Blocks) { TransferCmd transferCmd = b.TransferCmd; List<Cmd> newCmds = new List<Cmd>(); for (int i = b.Cmds.Count-1; i >= 0; i--) { CallCmd callCmd = b.Cmds[i] as CallCmd; if (callCmd == null || callCmd.Proc != yieldProc) { newCmds.Insert(0, b.Cmds[i]); } else { Block newBlock = new Block(Token.NoToken, b.Label + i, newCmds, transferCmd); newCmds = new List<Cmd>(); transferCmd = new GotoCmd(Token.NoToken, new List<string>(new string[] { newBlock.Label, yieldCheckBlock.Label }), new List<Block>(new Block[] { newBlock, yieldCheckBlock })); newBlocks.Add(newBlock); } } b.Cmds = newCmds; b.TransferCmd = transferCmd; } impl.Blocks.AddRange(newBlocks); impl.Blocks.Add(yieldCheckBlock); }
private void CreateDefaultStructConstructor(ITypeDefinition typeDefinition) { Contract.Requires(typeDefinition.IsStruct); var proc = this.sink.FindOrCreateProcedureForDefaultStructCtor(typeDefinition); this.sink.BeginMethod(typeDefinition); var stmtTranslator = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false); var stmts = new List <IStatement>(); foreach (var f in typeDefinition.Fields) { if (f.IsStatic) { continue; } var s = new ExpressionStatement() { Expression = new Assignment() { Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, }, Target = new TargetExpression() { Definition = f, Instance = new ThisReference() { Type = typeDefinition, }, Type = f.Type, }, Type = f.Type, }, }; stmts.Add(s); } stmtTranslator.Traverse(stmts); var translatedStatements = stmtTranslator.StmtBuilder.Collect(Bpl.Token.NoToken); var lit = Bpl.Expr.Literal(1); lit.Type = Bpl.Type.Int; var args = new List <object> { lit }; var attrib = new Bpl.QKeyValue(typeDefinition.Token(), "inline", args, null); // TODO: Need to have it be {:inine 1} (and not just {:inline})? List <Bpl.Variable> vars = new List <Bpl.Variable>(); foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) { vars.Add(v); } List <Bpl.Variable> vseq = new List <Bpl.Variable>(vars.ToArray()); Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, proc.Name, new List <Bpl.TypeVariable>(), proc.InParams, proc.OutParams, vseq, translatedStatements, attrib, new Bpl.Errors() ); impl.Proc = (Bpl.Procedure)proc; // TODO: get rid of cast this.sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
private List<Block> CreateAssertsBlocks(Implementation queryImplementation, Implementation targetImplementation, List<Tuple<Variable, Expr, Expr>> assumeVars) { var exprs = CreateAssertsExprs(queryImplementation, targetImplementation); var assertsCmds = CreateAsserts(exprs); queryImplementation.InParams.Iter(iq => { targetImplementation.InParams.Iter(it => { if (Equals(iq.TypedIdent.Type, it.TypedIdent.Type)) { var eqVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, AssumeVarPrefix + "_" + _eqVarsCounter++, BType.Bool)); assumeVars.Add(new Tuple<Variable, Expr, Expr>(eqVar, Expr.Ident(iq), Expr.Ident(it))); queryImplementation.Blocks[0].Cmds.Insert(0, Utils.BoogieUtils.CreateAssignCmd(new List<IdentifierExpr>() { Expr.Ident(eqVar) }, new List<Expr>() { Expr.Eq(Expr.Ident(iq), Expr.Ident(it)) })); } }); }); // The equality vars are grouped according to lhs. This means that expressions like eq_0 = `rax == v2.rcx` and eq_13 = `rax == v2.p0` will be // grouped together, to make the assumes choosing algorithm more efficient (we won't select eq_0 and eq_13 for the same section) var eqVarsGroups = new Dictionary<string, List<Tuple<Variable, Expr, Expr>>>(); assumeVars.Iter(t => { var lhs = t.Item2.ToString(); if (!eqVarsGroups.ContainsKey(lhs)) eqVarsGroups[lhs] = new List<Tuple<Variable, Expr, Expr>>(); eqVarsGroups[lhs].Add(t); }); assumeVars.Iter(t => queryImplementation.LocVars.Add(t.Item1)); return CreateAssertsWithAssumes(eqVarsGroups.Values.ToList(), assertsCmds); }
private void CreateStructCopyConstructor(ITypeDefinition typeDefinition) { Contract.Requires(typeDefinition.IsStruct); var proc = this.sink.FindOrCreateProcedureForStructCopy(typeDefinition); var stmtBuilder = new Bpl.StmtListBuilder(); var tok = Bpl.Token.NoToken; var o = Bpl.Expr.Ident(proc.OutParams[0]); // other := Alloc(); stmtBuilder.Add(new Bpl.CallCmd(tok, this.sink.AllocationMethodName, new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { o }))); // assume DynamicType(other) == DynamicType(this); stmtBuilder.Add(new Bpl.AssumeCmd(tok, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, this.sink.Heap.DynamicType(o), this.sink.Heap.DynamicType(Bpl.Expr.Ident(proc.InParams[0]))))); var localVars = new List <Bpl.Variable>(); foreach (var f in typeDefinition.Fields) { if (f.IsStatic) { continue; } var fExp = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(f)); var boogieType = sink.CciTypeToBoogie(f.Type); if (TranslationHelper.IsStruct(f.Type)) { // generate a call to the copy constructor to copy the contents of f var proc2 = this.sink.FindOrCreateProcedureForStructCopy(f.Type); var e = this.sink.Heap.ReadHeap(Bpl.Expr.Ident(proc.InParams[0]), fExp, AccessType.Struct, boogieType); var bplLocal = this.sink.CreateFreshLocal(f.Type); var localExpr = Bpl.Expr.Ident(bplLocal); localVars.Add(bplLocal); var cmd = new Bpl.CallCmd(tok, proc2.Name, new List <Bpl.Expr> { e, }, new List <Bpl.IdentifierExpr> { localExpr, }); stmtBuilder.Add(cmd); this.sink.Heap.WriteHeap(tok, o, fExp, localExpr, AccessType.Struct, boogieType, stmtBuilder); } else { // just generate a normal assignment to the field f var e = this.sink.Heap.ReadHeap(Bpl.Expr.Ident(proc.InParams[0]), fExp, AccessType.Struct, boogieType); this.sink.Heap.WriteHeap(tok, o, fExp, e, AccessType.Struct, boogieType, stmtBuilder); } } var lit = Bpl.Expr.Literal(1); lit.Type = Bpl.Type.Int; var args = new List <object> { lit }; var attrib = new Bpl.QKeyValue(typeDefinition.Token(), "inline", args, null); Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, proc.Name, new List <Bpl.TypeVariable>(), proc.InParams, proc.OutParams, localVars, stmtBuilder.Collect(Bpl.Token.NoToken), attrib, new Bpl.Errors() ); impl.Proc = (Bpl.Procedure)proc; // TODO: get rid of cast this.sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
private void JoinImplementations(Implementation queryImplementation, Implementation targetImplementation) { queryImplementation.InParams.AddRange(targetImplementation.InParams); queryImplementation.Proc.InParams.AddRange(targetImplementation.InParams); queryImplementation.LocVars.AddRange(targetImplementation.LocVars); queryImplementation.LocVars.Add(_havocVar); queryImplementation.Blocks.Last().TransferCmd = new GotoCmd(Token.NoToken, new List<Block>() { targetImplementation.Blocks.First() }); queryImplementation.Blocks.AddRange(targetImplementation.Blocks); }
private void CreateStaticConstructor(ITypeDefinition typeDefinition) { var typename = TypeHelper.GetTypeName(typeDefinition, Microsoft.Cci.NameFormattingOptions.DocumentationId); typename = TranslationHelper.TurnStringIntoValidIdentifier(typename); var proc = new Bpl.Procedure(Bpl.Token.NoToken, typename + ".#cctor", new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(), // in new List <Bpl.Variable>(), // out new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), // modifies new List <Bpl.Ensures>() ); this.sink.TranslatedProgram.AddTopLevelDeclaration(proc); this.sink.BeginMethod(typeDefinition); var stmtTranslator = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false); var stmts = new List <IStatement>(); foreach (var f in typeDefinition.Fields) { if (!f.IsStatic) { continue; } stmts.Add( new ExpressionStatement() { Expression = new Assignment() { Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, }, Target = new TargetExpression() { Definition = f, Instance = null, Type = f.Type, }, Type = f.Type, } }); } stmtTranslator.Traverse(stmts); var translatedStatements = stmtTranslator.StmtBuilder.Collect(Bpl.Token.NoToken); List <Bpl.Variable> vars = new List <Bpl.Variable>(); foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) { vars.Add(v); } List <Bpl.Variable> vseq = new List <Bpl.Variable>(vars.ToArray()); Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, proc.Name, new List <Bpl.TypeVariable>(), proc.InParams, proc.OutParams, vseq, translatedStatements ); impl.Proc = proc; this.sink.TranslatedProgram.AddTopLevelDeclaration(impl); }