private void UnsuppressToken(AssertToken token) { var location = tokenLocation[token]; var p = BoogieUtil.findProcedureImpl(currProg.TopLevelDeclarations, location.Item1); var block = p.Blocks.Where(blk => blk.Label == location.Item2).FirstOrDefault(); // disable assignment to assertsPassed var ncmds = new List <Cmd>(); foreach (var cmd in block.Cmds) { if (!Options.DeepAsserts && cmd is AssumeCmd && QKeyValue.FindIntAttribute((cmd as AssumeCmd).Attributes, "suppressAssert", -1) == token.id) { ncmds.Add(BoogieAstFactory.MkVarEqExpr(assertsPassed, (cmd as AssumeCmd).Expr)); } else if (Options.DeepAsserts && cmd is AssumeCmd && QKeyValue.FindIntAttribute((cmd as AssumeCmd).Attributes, "avn", -1) == token.id) { ncmds.Add(new AssertCmd(Token.NoToken, (cmd as AssertCmd).Expr, (cmd as AssertCmd).Attributes)); } else { ncmds.Add(cmd); } } block.Cmds = ncmds; }
// precondition: pathProgram has a single implementation // Suppress an assertion (that failed in the pathProgram) and // return its token public AssertToken SuppressAssert(Program pathProgram) { var impl = pathProgram.TopLevelDeclarations.OfType <Implementation>() .First(); var tokenId = -1; foreach (var acmd in impl.Blocks[0].Cmds.OfType <PredicateCmd>()) { tokenId = QKeyValue.FindIntAttribute(acmd.Attributes, "avn", -1); if (tokenId == -1) { continue; } break; } Debug.Assert(tokenId != -1); var token = new AssertToken(tokenId); SuppressToken(token); BoogieUtil.DoModSetAnalysis(currProg); suppressedTokens.Add(token); return(token); }
public void SuppressToken(AssertToken token) { var location = tokenLocation[token]; if (Options.DeepAsserts) { location = Tuple.Create((output as PersistentProgram).mainProcName, location.Item2); } var p = BoogieUtil.findProcedureImpl(currProg.TopLevelDeclarations, location.Item1); var block = p.Blocks.Where(blk => blk.Label == location.Item2).FirstOrDefault(); // disable assignment to assertsPassed var ncmds = new List <Cmd>(); foreach (var cmd in block.Cmds) { if (!Options.DeepAsserts && (cmd is AssignCmd) && (cmd as AssignCmd).Lhss[0].DeepAssignedVariable.Name == assertsPassedName) { var acmd = BoogieAstFactory.MkAssume((cmd as AssignCmd).Rhss[0]) as AssumeCmd; acmd.Attributes = new QKeyValue(Token.NoToken, "suppressAssert", new List <object> { Expr.Literal(token.id) }, null); ncmds.Add(acmd); } else if (Options.DeepAsserts && (cmd is AssertCmd) && QKeyValue.FindIntAttribute((cmd as AssertCmd).Attributes, "avn", -1) == token.id) { var acmd = new AssumeCmd(Token.NoToken, (cmd as AssertCmd).Expr, (cmd as AssertCmd).Attributes); ncmds.Add(acmd); } else { ncmds.Add(cmd); } } block.Cmds = ncmds; }
// Location where the assertion lived public string GetFailingAssertProcName(AssertToken token) { return(tokenLocation[token].Item1); }
// The assertion corresponding to the given token public AssertCmd GetFailingAssert(AssertToken token) { return(originalAssertions[token]); }
public override CBAProgram runCBAPass(CBAProgram program) { // Add blanks blanksInfo = AddBlanks(program); // Remove unreachable procedures BoogieUtil.pruneProcs(program, program.mainProcName); if (!Options.TraceSlicing) { // Remove source line annotations sourceInfo = cba.PrintSdvPath.DeleteSourceInfo(program); } else { sourceInfo = null; } // Remove print info //printInfo = cba.PrintSdvPath.DeletePrintCmds(program); // Compress compressBlocks.VisitProgram(program); // name Ebasic NameEnvironmentConstraints(program); // Instrument assertions int tokenId = 0; origMainName = program.mainProcName; CBAProgram ret = null; if (!Options.DeepAsserts) { // Do error-bit instrumentation var impls = BoogieUtil.nameImplMapping(program); var pwa = cba.SequentialInstrumentation.procsWithAsserts(program); foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { var instrumented = new List <Block>(); foreach (var blk in impl.Blocks) { var currCmds = new List <Cmd>(); var currLabel = blk.Label; assertInstrInfo.addTrans(impl.Name, blk.Label, blk.Label); var incnt = -1; foreach (Cmd cmd in blk.Cmds) { incnt++; // instrument assert if (cmd is AssertCmd && !BoogieUtil.isAssertTrue(cmd)) { currCmds.Add(BoogieAstFactory.MkVarEqExpr(assertsPassed, (cmd as AssertCmd).Expr)); var token = new AssertToken(tokenId); originalAssertions.Add(token, cmd as AssertCmd); tokenLocation.Add(token, Tuple.Create(impl.Name, currLabel)); procToTokens.InitAndAdd(impl.Name, token); addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds); currLabel = addInstr(instrumented, currCmds, currLabel, tokenId); tokenId++; currCmds = new List <Cmd>(); continue; } // procedure call if (cmd is CallCmd && pwa.Contains((cmd as CallCmd).callee)) { currCmds.Add(cmd); addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds); currLabel = addInstr(instrumented, currCmds, currLabel, -1); currCmds = new List <Cmd>(); continue; } currCmds.Add(cmd); addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds); } instrumented.Add(new Block(Token.NoToken, currLabel, currCmds, blk.TransferCmd)); } impl.Blocks = instrumented; } program.AddTopLevelDeclaration(assertsPassed); var newMain = addMain(program); BoogieUtil.DoModSetAnalysis(program); // Set inline attribute // free requires assertsPassed == true; foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { impl.Proc.Requires.Add(new Requires(true, Expr.Ident(assertsPassed))); } // convert free ensures e to: // free ensures assertsPassed == false || e foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>() .Where(impl => pwa.Contains(impl.Name))) { foreach (Ensures ens in impl.Proc.Ensures) { ens.Condition = Expr.Or(Expr.Not(Expr.Ident(assertsPassed)), ens.Condition); } } currProg = program; ret = new CBAProgram(program, newMain, 0); } else { // Use Deep-assert instrumentation da = new cba.DeepAssertRewrite(); // First, tag assertions with tokens foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { foreach (var blk in impl.Blocks) { foreach (var cmd in blk.Cmds.OfType <AssertCmd>()) { if (BoogieUtil.isAssertTrue(cmd)) { continue; } var token = new AssertToken(tokenId); cmd.Attributes = new QKeyValue(Token.NoToken, "avn", new List <object> { Expr.Literal(tokenId) }, cmd.Attributes); originalAssertions.Add(token, cmd); tokenLocation.Add(token, Tuple.Create(impl.Name, blk.Label)); procToTokens.InitAndAdd(impl.Name, token); tokenId++; } } } // Second, do the rewrite var t1 = new PersistentProgram(program, program.mainProcName, program.contextBound); var t2 = da.run(t1); var daprog = t2.getCBAProgram(); // Third, revisit the assertions and remember their location // in the output program. This is a bit of a hack. The "tokenLocation" // of a token is the pair (p1,b1) where p1 is the procedure the assertion // originally came from and b1 is the block in the new main that contains // that assertion. var main = BoogieUtil.findProcedureImpl(daprog.TopLevelDeclarations, daprog.mainProcName); foreach (var block in main.Blocks) { foreach (var cmd in block.Cmds.OfType <AssertCmd>()) { var tok = QKeyValue.FindIntAttribute(cmd.Attributes, "avn", -1); if (tok < 0) { continue; } var token = new AssertToken(tok); Debug.Assert(tokenLocation.ContainsKey(token)); var oldloc = tokenLocation[token]; tokenLocation[token] = Tuple.Create(oldloc.Item1, block.Label); } } currProg = daprog; ret = daprog; } return(ret); }