Ejemplo n.º 1
0
        private void collectBoogieCmds(BoogieCmd cmd, List <BoogieCmd> cmds)
        {
            if (cmd is BoogieStructuredCmd)
            {
                if (cmd is BoogieIfCmd)
                {
                    BoogieIfCmd ifCmd = (BoogieIfCmd)cmd;
                    foreach (var c in ifCmd.ThenBody.BigBlocks[0].SimpleCmds)
                    {
                        collectBoogieCmds(c, cmds);
                    }

                    if (ifCmd.ElseBody != null)
                    {
                        foreach (var c in ifCmd.ElseBody.BigBlocks[0].SimpleCmds)
                        {
                            collectBoogieCmds(c, cmds);
                        }
                    }
                }
                else if (cmd is BoogieWhileCmd)
                {
                    BoogieWhileCmd whileCmd = (BoogieWhileCmd)cmd;
                    foreach (var c in whileCmd.Body.BigBlocks[0].SimpleCmds)
                    {
                        collectBoogieCmds(c, cmds);
                    }
                }
                else
                {
                    cmds.Add(cmd);
                }
            }
            else
            {
                cmds.Add(cmd);
            }
        }
Ejemplo n.º 2
0
        private void generateRevertLogicForCmd(BoogieCmd cmd, BoogieStmtList parent, bool isFail, bool inHarness)
        {
            List <BoogieExpr> dupAndReplaceExprList(List <BoogieExpr> exprs)
            {
                return(exprs.Select(e => dupAndReplaceExpr(e, isFail, inHarness)).ToList());
            }

            BoogieStmtList dupAndReplaceStmList(BoogieStmtList stmtList)
            {
                if (stmtList == null)
                {
                    return(null);
                }

                BoogieStmtList newList = new BoogieStmtList();

                stmtList.BigBlocks[0].SimpleCmds.ForEach(c => generateRevertLogicForCmd(c, newList, isFail, inHarness));
                return(newList);
            }

            if (cmd is BoogieAssignCmd assignCmd)
            {
                parent.AddStatement(new BoogieAssignCmd(dupAndReplaceExpr(assignCmd.Lhs, isFail, inHarness),
                                                        dupAndReplaceExpr(assignCmd.Rhs, isFail, inHarness)));
            }
            else if (cmd is BoogieCallCmd callCmd)
            {
                string calleeName           = callCmd.Callee;
                bool   emitCheckRevertLogic = false;
                if (!isHarnessProcudure(calleeName) && procsWiltImplNames.Contains(calleeName))
                {
                    if (!inHarness || !isPublic(proceduresInProgram[calleeName]))
                    {
                        calleeName           = calleeName + (isFail ? "__fail" : "__success");
                        emitCheckRevertLogic = !inHarness;
                    }
                }

                var newIns = callCmd.Ins != null?dupAndReplaceExprList(callCmd.Ins) : null;

                var newOuts = callCmd.Outs != null?callCmd.Outs.Select(e => (BoogieIdentifierExpr)dupAndReplaceExpr(e, isFail, inHarness)).ToList() : null;

                parent.AddStatement(new BoogieCallCmd(calleeName, newIns, newOuts));

                if (emitCheckRevertLogic)
                {
                    BoogieStmtList thenBody = new BoogieStmtList();
                    thenBody.AddStatement(new BoogieReturnCmd());

                    parent.AddStatement(new BoogieIfCmd(new BoogieIdentifierExpr("revert"), thenBody, null));
                }
            }
            else if (cmd is BoogieAssertCmd assertCmd)
            {
                if (!isFail)
                {
                    parent.AddStatement(new BoogieAssertCmd(dupAndReplaceExpr(assertCmd.Expr, false, inHarness), assertCmd.Attributes));
                }
            }
            else if (cmd is BoogieAssumeCmd assumeCmd)
            {
                parent.AddStatement(new BoogieAssumeCmd(dupAndReplaceExpr(assumeCmd.Expr, isFail, inHarness)));
            }
            else if (cmd is BoogieLoopInvCmd loopInvCmd)
            {
                parent.AddStatement(new BoogieLoopInvCmd(dupAndReplaceExpr(loopInvCmd.Expr, isFail, inHarness)));
            }
            else if (cmd is BoogieReturnExprCmd returnExprCmd)
            {
                // This one does not seem to be used.
                parent.AddStatement(new BoogieReturnExprCmd(dupAndReplaceExpr(returnExprCmd.Expr, isFail, inHarness)));
            }
            else if (cmd is BoogieHavocCmd havocCmd)
            {
                parent.AddStatement(new BoogieHavocCmd(havocCmd.Vars.Select(id => (BoogieIdentifierExpr)dupAndReplaceExpr(id, isFail, inHarness)).ToList()));
            }
            else if (cmd is BoogieIfCmd ifCmd)
            {
                parent.AddStatement(new BoogieIfCmd(dupAndReplaceExpr(ifCmd.Guard, isFail, inHarness),
                                                    dupAndReplaceStmList(ifCmd.ThenBody),
                                                    dupAndReplaceStmList(ifCmd.ElseBody)));
            }
            else if (cmd is BoogieWhileCmd whileCmd)
            {
                var            body           = dupAndReplaceStmList(whileCmd.Body);
                BoogieStmtList invsAsStmtList = new BoogieStmtList();
                whileCmd.Invariants.ForEach(i => generateRevertLogicForCmd(i, invsAsStmtList, isFail, inHarness));
                List <BoogiePredicateCmd> invs = invsAsStmtList.BigBlocks[0].SimpleCmds.Select(c => (BoogiePredicateCmd)c).ToList();
                parent.AddStatement(new BoogieWhileCmd(dupAndReplaceExpr(whileCmd.Guard, isFail, inHarness), body, invs));
            }
            else
            {
                parent.AddStatement(cmd);
            }
        }