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));
                }
Beispiel #2
0
        void Desugar(Variable lhs, Expr cond, Expr then, Expr els, ref List <Cmd> currCmds, ref Block currBlock, List <Block> newBlocks)
        {
            // create three new blocks
            var lab1 = GetNewLabel();
            var lab2 = GetNewLabel();
            var lab3 = GetNewLabel();

            var tmp = CreateTmp(btype.Bool);

            currCmds.Add(BoogieAstFactory.MkVarEqExpr(tmp, cond));

            // end current block
            currBlock.Cmds        = currCmds;
            currBlock.TransferCmd = new GotoCmd(Token.NoToken, new List <string> {
                lab1, lab2
            });
            newBlocks.Add(currBlock);


            var blk1 = new Block(Token.NoToken, lab1, new List <Cmd>(), BoogieAstFactory.MkGotoCmd(lab3));
            var blk2 = new Block(Token.NoToken, lab2, new List <Cmd>(), BoogieAstFactory.MkGotoCmd(lab3));

            blk1.Cmds.AddRange(
                new List <Cmd> {
                BoogieAstFactory.MkAssume(Expr.Ident(tmp)),
                BoogieAstFactory.MkVarEqExpr(lhs, then)
            });

            blk2.Cmds.AddRange(
                new List <Cmd> {
                BoogieAstFactory.MkAssume(Expr.Not(Expr.Ident(tmp))),
                BoogieAstFactory.MkVarEqExpr(lhs, els)
            });

            newBlocks.Add(blk1);
            newBlocks.Add(blk2);

            currBlock = new Block(Token.NoToken, lab3, new List <Cmd>(), null);
            currCmds  = new List <Cmd>();
        }
        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;
        }
        // This is to avoid a corner-case with ModifyTrans where some statements
        // that are deleted by the transformation are picked up at the end of the
        // trace while mapping back.
        // We avoid this by adding "assume true" right after procedure calls
        private cba.InsertionTrans AddBlanks(Program program)
        {
            var tinfo = new cba.InsertionTrans();

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                foreach (var blk in impl.Blocks)
                {
                    var currCmds = new List <Cmd>();

                    tinfo.addTrans(impl.Name, blk.Label, blk.Label);
                    var incnt = -1;
                    foreach (Cmd cmd in blk.Cmds)
                    {
                        incnt++;

                        // procedure call
                        if (cmd is CallCmd)
                        {
                            currCmds.Add(cmd);
                            tinfo.addTrans(impl.Name, blk.Label, incnt, cmd, blk.Label, currCmds.Count - 1, new List <Cmd> {
                                currCmds.Last()
                            });
                            currCmds.Add(BoogieAstFactory.MkAssume(Expr.True));
                            continue;
                        }

                        currCmds.Add(cmd);
                        tinfo.addTrans(impl.Name, blk.Label, incnt, cmd, blk.Label, currCmds.Count - 1, new List <Cmd> {
                            currCmds.Last()
                        });
                    }
                    blk.Cmds = currCmds;
                }
            }

            return(tinfo);
        }
Beispiel #5
0
            private void CreateMainProcedure(Function reach)
            {
                //blocks
                List <Block>    mainBlocks = new List <Block>();
                List <Variable> locals     = new List <Variable>();

                HashSet <Constant> blockCallConsts = new HashSet <Constant>();

                foreach (Implementation impl in prog.TopLevelDeclarations.Where(x => x is Implementation))
                {
                    // skip this impl if it is not marked as an entrypoint
                    if (useProvidedEntryPoints && !QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "entrypoint"))
                    {
                        continue;
                    }

                    impl.Attributes      = BoogieUtil.removeAttr("entrypoint", impl.Attributes);
                    impl.Proc.Attributes = BoogieUtil.removeAttr("entrypoint", impl.Proc.Attributes);

                    // skip initialization procedure
                    if (QKeyValue.FindBoolAttribute(impl.Attributes, AvnAnnotations.InitialializationProcAttr) ||
                        QKeyValue.FindBoolAttribute(impl.Proc.Attributes, AvnAnnotations.InitialializationProcAttr))
                    {
                        continue;
                    }

                    entrypoints.Add(impl.Name);

                    //allocate params
                    var args = new List <Variable>();
                    var rets = new List <Variable>();


                    impl.OutParams.ForEach(v => rets.Add(BoogieAstFactory.MkLocal(v.Name + "_" + impl.Name, v.TypedIdent.Type)));
                    if (Options.allocateParameters)
                    {
                        // use impl.Proc here to pickup scalar/pointer attributes
                        impl.Proc.InParams.ForEach(v =>
                        {
                            var l = BoogieAstFactory.MkLocal(v.Name + "_" + impl.Name, v.TypedIdent.Type);
                            // We are delibrately dropping the attributes so that
                            // all parameters are initialized by allocation
                            //l.Attributes = v.Attributes;
                            args.Add(l);
                        });
                        locals.AddRange(args);
                    }
                    else
                    {
                        impl.Proc.InParams.ForEach(v =>
                        {
                            var g = BoogieAstFactory.MkGlobal(v.Name + "_" + impl.Name, v.TypedIdent.Type);
                            //g.Attributes = v.Attributes;
                            args.Add(g);
                        });
                        globalParams.AddRange(args);
                    }


                    locals.AddRange(rets);

                    //call
                    var blockCallConst = new Constant(Token.NoToken,
                                                      new TypedIdent(Token.NoToken, "__block_call_" + impl.Name, btype.Bool), false);
                    blockCallConsts.Add(blockCallConst);
                    blockEntryPointConstants[blockCallConst.Name] = impl.Name;
                    impl2BlockingConstant[impl.Name] = blockCallConst;
                    var blockCallAssumeCmd = new AssumeCmd(Token.NoToken, IdentifierExpr.Ident(blockCallConst));

                    var cmds = new List <Cmd>();
                    cmds.Add(blockCallAssumeCmd);
                    if (Options.allocateParameters) // allocate parameters if option is enabled
                    {
                        var argMallocCmds = AllocatePointersAsUnknowns(args);
                        cmds.AddRange(argMallocCmds);
                    }

                    // The beginning of an entry point must be reachable: assume reach(true);
                    cmds.Add(new AssumeCmd(Token.NoToken, new NAryExpr(Token.NoToken,
                                                                       new FunctionCall(reach), new List <Expr> {
                        Expr.True
                    })));

                    var callCmd = new CallCmd(Token.NoToken, impl.Name, args.ConvertAll(x => (Expr)IdentifierExpr.Ident(x)),
                                              rets.ConvertAll(x => IdentifierExpr.Ident(x)));
                    callCmd.Attributes = new QKeyValue(Token.NoToken, AvUtil.AvnAnnotations.AvhEntryPointAttr, new List <object>(), callCmd.Attributes);

                    cmds.Add(callCmd);
                    //succ
                    var txCmd = new ReturnCmd(Token.NoToken);
                    var blk   = BoogieAstFactory.MkBlock(cmds, txCmd);
                    mainBlocks.Add(blk);
                }
                foreach (Procedure proc in prog.TopLevelDeclarations.OfType <Procedure>())
                {
                    proc.Attributes = BoogieUtil.removeAttr("entrypoint", proc.Attributes);
                }
                // add global variables to prog
                // globals.Iter(x => prog.AddTopLevelDeclaration(x));
                //add the constants to the prog
                blockCallConsts.Iter(x => prog.AddTopLevelDeclaration(x));
                //TODO: get globals of type refs/pointers and maps
                var initCmd = (AssumeCmd)BoogieAstFactory.MkAssume(Expr.True);

                var globalCmds = new List <Cmd>()
                {
                    initCmd
                };
                //add call to corralExtraInit
                var init = Instrumentations.GetEnvironmentAssumptionsProc(prog);

                if (init != null && !Options.DelayInitialization)
                {
                    globalCmds.Add(BoogieAstFactory.MkCall(init, new List <Expr>(), new List <Variable>()));
                }

                // Dont initialize Boogie instrumentation variables
                prog.GlobalVariables
                .Where(g => g.Name == "alloc" || BoogieUtil.checkAttrExists(AvnAnnotations.AllocatorVarAttr, g.Attributes))
                .Where(g => !BoogieUtil.checkAttrExists("scalar", g.Attributes))
                .Iter(g => g.AddAttribute("scalar"));

                // initialize globals
                prog.GlobalVariables
                .Where(g => g.Name != "alloc" && !BoogieUtil.checkAttrExists(AvnAnnotations.AllocatorVarAttr, g.Attributes))
                .Iter(g => g.Attributes = BoogieUtil.removeAttrs(new HashSet <string> {
                    "scalar", "pointer"
                }, g.Attributes));

                globalCmds.AddRange(AllocatePointersAsUnknowns(prog.GlobalVariables.Select(x => (Variable)x).ToList()));

                if (init != null && Options.DelayInitialization)
                {
                    globalCmds.Add(BoogieAstFactory.MkCall(init, new List <Expr>(), new List <Variable>()));
                }

                // globals for parameters
                prog.AddTopLevelDeclarations(globalParams);

                //first block
                var transferCmd =
                    mainBlocks.Count > 0 ? (TransferCmd)(new GotoCmd(Token.NoToken, mainBlocks)) : (TransferCmd)(new ReturnCmd(Token.NoToken));
                Block blkStart = new Block(Token.NoToken, "CorralMainStart", globalCmds, transferCmd);
                var   blocks   = new List <Block>();

                blocks.Add(blkStart);
                blocks.AddRange(mainBlocks);
                var mainProcImpl = BoogieAstFactory.MkImpl(AvnAnnotations.CORRAL_MAIN_PROC, new List <Variable>(), new List <Variable>(), locals, blocks);

                mainProcImpl[0].AddAttribute("entrypoint");
                prog.AddTopLevelDeclarations(mainProcImpl);
            }