protected void Visit(APC pc, AElement pre, int depth) { APC lastPC; AElement preConditionAtTheBlockEntry; if (ShoudStopTheVisit(pc, pre, depth, out lastPC, out preConditionAtTheBlockEntry)) { return; } pre = preConditionAtTheBlockEntry; pc = lastPC; var md = this.Mdriver; foreach (var prePC in CFG.Predecessors(lastPC)) { // nothing to do if (md.BasicFacts.IsUnreachable(prePC)) { continue; } // Widening: stop after one iteration if (this.underVisit.Contains(lastPC)) { this.LoopHit = true; Trace("Applying simple 1-iteration widening", pre); return; } if (CFG.IsForwardBackEdgeTarget(pc)) { Trace("Reached the target of a forward backedge", pre); this.LoopHit = true; this.underVisit.Add(lastPC); Visit(prePC, md.BackwardTransfer(pc, prePC, pre, this), depth + 1); this.underVisit.Remove(lastPC); } else { var newPre = md.BackwardTransfer(pc, prePC, pre, this); Visit(prePC, newPre, depth + 1); } } }
private void FixpointComputation(APC entry, Postconditions initialState) { var todo = new List <Tuple <APC, Preconditions> >() { new Tuple <APC, Preconditions>(entry, initialState) }; var stable = new Set <APC>(); while (todo.Count != 0) { this.timeout.CheckTimeOut("backwards postcondition propagation"); var next = todo.ExtractFirst(); var nextPC = next.Item1; var nextState = next.Item2; var newPre = nextState; // do the block { APC pred; while (CFG.HasSinglePredecessor(nextPC, out pred) && !CFG.IsJoinPoint(nextPC)) { this.timeout.CheckTimeOut("backwards postcondition propagation (block)"); //var post = CFG.Predecessors(nextPC).First(); newPre = this.Mdriver.BackwardTransfer(nextPC, pred, newPre, this); // no pre, killing the path if (newPre == null) { break; } // TODO: check for contraddictions nextPC = pred; } } if (nextPC.Equals(CFG.EntryAfterRequires) || nextPC.Equals(CFG.Entry)) { this.invariants = newPre; continue; } var fixpointReached = false; if (CFG.IsJoinPoint(nextPC)) { Preconditions prev; if (this.joinPoints.TryGetValue(nextPC, out prev)) { newPre = Join(prev, newPre, CFG.IsForwardBackEdgeTarget(nextPC.Block.First), out fixpointReached); if (fixpointReached) { stable.Add(nextPC.Block.First); } } joinPoints[nextPC] = newPre; } // Split in the backwards analysis foreach (var pred in CFG.Predecessors(nextPC)) { if (fixpointReached && CFG.IsForwardBackEdge(pred, nextPC)) { continue; } if (this.Mdriver.IsUnreachable(nextPC)) { continue; } var transf = this.Mdriver.BackwardTransfer(nextPC, pred, newPre, this); if (transf != null) { todo.Add(new Tuple <APC, Preconditions>(pred, transf)); } } } }
public bool IsForwardBackEdgeTarget(APC ppoint) { return(underlying.IsForwardBackEdgeTarget(ppoint)); }