Exemplo n.º 1
0
        public override Cmd VisitHavocCmd(HavocCmd node)
        {
            Block        currBlock    = worklist.cmdBlocks[node];
            Dependencies dependencies = worklist.GatherPredecessorsState(node, currBlock);

            // Havoc x translates to x <- *
            foreach (var v in node.Vars.Select(x => x.Decl))
            {
                dependencies[v] = new VarSet();
                dependencies[v].Add(Utils.VariableUtils.NonDetVar);

                InferDominatorDependency(currBlock, dependencies[v]);

                if (changedProcs.Contains(nodeToImpl[node].Proc) || changedBlocks.Contains(currBlock)) // native taint
                {
                    if (Analysis.DacMerged == null || IsImpactedSummary(nodeToImpl[node].Proc, v))
                    {
                        dependencies[v].Add(Utils.VariableUtils.BottomUpTaintVar);
                    }
                }
            }

            if (worklist.Assign(node, dependencies))
            {
                worklist.Propagate(node);
            }
            return(node);
        }
Exemplo n.º 2
0
        private void m_HavocLoopBody(Loop l)
        {
            List <Block> loopblocks = new List <Block>();

            foreach (GraphNode g in l.LoopNodes)
            {
                loopblocks.Add(g.Label);
            }
            HavocCmd hcmd = m_ComputHavocCmd(loopblocks, l.Cutpoint.Label.tok);

            //Add Havoc before and after the loop body
            foreach (GraphNode g in l.Cutpoint.Suc) // before
            {
                if (l.LoopNodes.Contains(g))
                {
                    m_AddHavocCmdToFront(g.Label, hcmd);
                }
            }
            foreach (GraphNode g in l.Cutpoint.Pre) // and after
            {
                if (l.LoopNodes.Contains(g))
                {
                    m_AddHavocCmdToFront(g.Label, hcmd);
                }
            }
        }
Exemplo n.º 3
0
        private ConstantProp ApplyHavoc(HavocCmd cmd)
        {
            var ret = new Dictionary <string, Value>();

            // Deep copy
            val.Iter(kvp => ret.Add(kvp.Key, new Value(kvp.Value)));

            foreach (var v in cmd.Vars.OfType <IdentifierExpr>())
            {
                if (!val.ContainsKey(v.Name))
                {
                    continue;
                }

                if (!ret.ContainsKey(v.Name))
                {
                    ret.Add(v.Name, Value.GetTop());
                }
                else
                {
                    ret[v.Name] = Value.GetTop();
                }
            }

            return(new ConstantProp(ret, impl));
        }
Exemplo n.º 4
0
        private void m_AddHavocCmdToFront(Block b, HavocCmd hcmd)
        {
            List <Cmd> cs = new List <Cmd>();

            cs.Add(hcmd); cs.AddRange(b.Cmds);
            b.Cmds = cs;
        }
Exemplo n.º 5
0
 public virtual Cmd VisitHavocCmd(HavocCmd node)
 {
     Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <Cmd>() != null);
     node.Vars = this.VisitIdentifierExprSeq(node.Vars);
     return(node);
 }
Exemplo n.º 6
0
            private void AddPath()
            {
                HashSet <Variable>          existsVars = new HashSet <Variable>();
                Dictionary <Variable, Expr> varToExpr  = new Dictionary <Variable, Expr>();

                foreach (Variable v in frame)
                {
                    varToExpr[v] = Expr.Ident(v);
                }
                if (first != null)
                {
                    foreach (Variable v in first.thatOutParams)
                    {
                        varToExpr[v] = Expr.Ident(v);
                    }
                }
                foreach (Variable v in second.thisOutParams)
                {
                    varToExpr[v] = Expr.Ident(v);
                }
                List <Expr> pathExprs          = new List <Expr>();
                int         boundVariableCount = 0;

                foreach (Cmd cmd in cmdStack)
                {
                    if (cmd is AssumeCmd)
                    {
                        AssumeCmd assumeCmd = cmd as AssumeCmd;
                        FlattenAnd(assumeCmd.Expr, pathExprs);
                    }
                    else if (cmd is AssignCmd)
                    {
                        AssignCmd assignCmd             = (cmd as AssignCmd).AsSimpleAssignCmd;
                        Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>();
                        for (int k = 0; k < assignCmd.Lhss.Count; k++)
                        {
                            map[assignCmd.Lhss[k].DeepAssignedVariable] = assignCmd.Rhss[k];
                        }
                        Substitute(map, ref pathExprs, ref varToExpr);
                    }
                    else if (cmd is HavocCmd)
                    {
                        HavocCmd havocCmd = cmd as HavocCmd;
                        Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>();
                        foreach (IdentifierExpr ie in havocCmd.Vars)
                        {
                            BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "#tmp_" + boundVariableCount++, ie.Decl.TypedIdent.Type));
                            map[ie.Decl] = Expr.Ident(bv);
                            existsVars.Add(bv);
                        }
                        Substitute(map, ref pathExprs, ref varToExpr);
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
                paths.Add(new PathInfo(existsVars, varToExpr, pathExprs));
            }
Exemplo n.º 7
0
 public override Cmd VisitHavocCmd(HavocCmd node)
 {
     if (node.Vars.All(x => !x.Type.IsMap))
     {
         return(base.VisitHavocCmd(node));
     }
     throw new Exception(string.Format("Do not allow havoc over map variables, found {0}", node.ToString()));
 }
Exemplo n.º 8
0
        public override Cmd VisitHavocCmd(HavocCmd node)
        {
            var dispatchedVars = new List <IdentifierExpr>();

            foreach (var x in node.Vars)
            {
                dispatchedVars.Add(VisitIdentifierExpr(x) as IdentifierExpr);
            }
            return(new HavocCmd(Token.NoToken, dispatchedVars));
        }
Exemplo n.º 9
0
        public SymbolicVariable(string name, HavocCmd cmd, int varsIndex) : base(Token.NoToken, CopyAndRename(cmd.Vars[varsIndex].Decl.TypedIdent, name))
        {
            Expr        = new IdentifierExpr(Token.NoToken, this, /*immutable=*/ true);
            this.Origin = cmd.GetProgramLocation();
            Debug.Assert(this.Origin.IsCmd && (this.Origin.AsCmd is HavocCmd), "Expected ProgramLocation to be a HavocCmd");
            this.Name = name;
            Debug.WriteLine("Creating Symbolic " + this);

            // Should we record VarsIndex?
        }
Exemplo n.º 10
0
        //desugar into single havoc commands
        private IList <Term> TranslateHavocCmd(HavocCmd node)
        {
            var varResults = node.Vars.Select(var => TranslateIdentifierExpr(var));

            IList <Term> results = new List <Term>();

            foreach (var v in varResults)
            {
                results.Add(IsaBoogieTerm.Havoc(v));
            }

            return(results);
        }
Exemplo n.º 11
0
        private void AbstractReadAccesses(InstrumentationRegion region)
        {
            foreach (var b in region.Blocks())
            {
                for (int k = 0; k < b.Cmds.Count; k++)
                {
                    if (!(b.Cmds[k] is AssignCmd))
                    {
                        continue;
                    }

                    foreach (var rhs in (b.Cmds[k] as AssignCmd).Rhss.OfType <NAryExpr>())
                    {
                        if (!(rhs.Fun is MapSelect) || rhs.Args.Count != 2 ||
                            !((rhs.Args[0] as IdentifierExpr).Name.StartsWith("$M.")))
                        {
                            continue;
                        }

                        Variable v     = (b.Cmds[k] as AssignCmd).Lhss[0].DeepAssignedVariable;
                        HavocCmd havoc = new HavocCmd(Token.NoToken,
                                                      new List <IdentifierExpr> {
                            new IdentifierExpr(v.tok, v)
                        });
                        b.Cmds[k] = havoc;
                    }

                    if (!(b.Cmds[k] is AssignCmd))
                    {
                        continue;
                    }
                    foreach (var rhs in (b.Cmds[k] as AssignCmd).Rhss.OfType <IdentifierExpr>())
                    {
                        if (!(rhs.Name.StartsWith("$M.")))
                        {
                            continue;
                        }

                        Variable v     = (b.Cmds[k] as AssignCmd).Lhss[0].DeepAssignedVariable;
                        HavocCmd havoc = new HavocCmd(Token.NoToken,
                                                      new List <IdentifierExpr> {
                            new IdentifierExpr(v.tok, v)
                        });
                        b.Cmds[k] = havoc;
                    }
                }
            }
        }
Exemplo n.º 12
0
        public override Cmd VisitHavocCmd(HavocCmd node)
        {
            var cmd     = base.VisitHavocCmd(node) as HavocCmd;
            var newVars = new List <IdentifierExpr>();
            var seen    = new HashSet <string>();

            foreach (IdentifierExpr ie in cmd.Vars)
            {
                if (!seen.Contains(ie.Name))
                {
                    newVars.Add(ie);
                    seen.Add(ie.Name);
                }
            }
            cmd.Vars = newVars;

            return(cmd);
        }
Exemplo n.º 13
0
            private void TransitionRelationComputationHelper(Program program, AtomicActionInfo first, AtomicActionInfo second)
            {
                this.program  = program;
                this.first    = first;
                this.second   = second;
                this.cmdStack = new Stack <Cmd>();
                this.paths    = new List <PathInfo>();
                List <IdentifierExpr> havocVars = new List <IdentifierExpr>();

                this.second.thisOutParams.ForEach(v => havocVars.Add(Expr.Ident(v)));
                this.second.thisAction.LocVars.ForEach(v => havocVars.Add(Expr.Ident(v)));
                if (havocVars.Count > 0)
                {
                    HavocCmd havocCmd = new HavocCmd(Token.NoToken, havocVars);
                    cmdStack.Push(havocCmd);
                }
                Search(this.second.thisAction.Blocks[0], false);
            }
Exemplo n.º 14
0
        public SymbolicVariable GetFreshSymbolic(HavocCmd havocCmd, int varsIndex, ExecutionState owner)
        {
            ++Requests;
            SymbolicVariableStack havocVarStack = null;
            var key = Tuple.Create(havocCmd, varsIndex);

            try
            {
                havocVarStack = HavocCmdStacks[key];
            }
            catch (KeyNotFoundException)
            {
                // XXX: This is a little misleading the "Pool" doesn't use the owner argument
                // so the SymbolicVariableStack doesn't known about this owner
                havocVarStack = new SymbolicVariableStack(() => Pool.GetFreshSymbolic(havocCmd, varsIndex, null));
                HavocCmdStacks.Add(key, havocVarStack);
            }

            return(havocVarStack.GetVariable(owner));
        }
Exemplo n.º 15
0
            private void Search(Block b, bool inFirst)
            {
                int pathSizeAtEntry = cmdStack.Count;

                foreach (Cmd cmd in b.Cmds)
                {
                    cmdStack.Push(cmd);
                }
                if (b.TransferCmd is ReturnCmd)
                {
                    if (first == null || inFirst)
                    {
                        AddPath();
                    }
                    else
                    {
                        List <IdentifierExpr> havocVars = new List <IdentifierExpr>();
                        first.thatOutParams.ForEach(v => havocVars.Add(Expr.Ident(v)));
                        first.thatAction.LocVars.ForEach(v => havocVars.Add(Expr.Ident(v)));
                        if (havocVars.Count > 0)
                        {
                            HavocCmd havocCmd = new HavocCmd(Token.NoToken, havocVars);
                            cmdStack.Push(havocCmd);
                        }
                        Search(first.thatAction.Blocks[0], true);
                    }
                }
                else
                {
                    GotoCmd gotoCmd = b.TransferCmd as GotoCmd;
                    foreach (Block target in gotoCmd.labelTargets)
                    {
                        Search(target, inFirst);
                    }
                }
                Debug.Assert(cmdStack.Count >= pathSizeAtEntry);
                while (cmdStack.Count > pathSizeAtEntry)
                {
                    cmdStack.Pop();
                }
            }
Exemplo n.º 16
0
        public override Cmd VisitHavocCmd(HavocCmd node)
        {
            // gather state from all predecesors
            Block currBlock    = worklist.cmdBlocks[node];
            var   predTaintSet = worklist.GatherPredecessorsState(node, currBlock);
            var   taintSet     = new TaintSet(predTaintSet);

            // the assignment has the potential to cleanse the taint
            taintSet.RemoveWhere(v => node.Vars.Exists(o => o.Decl == v));

            if (changedProcs.Contains(nodeToImpl[node].Proc) || changedBlocks.Contains(currBlock) || // native taint
                InferDominatorTaint(currBlock))    // control taint
            {
                node.Vars.Iter(v => taintSet.Add(v.Decl));
            }

            if (worklist.Assign(node, taintSet))
            {
                worklist.Propagate(node);
            }
            return(node);
        }
Exemplo n.º 17
0
 public override Cmd VisitHavocCmd(HavocCmd node)
 {
     add(node);
     return(base.VisitHavocCmd(node));
 }
Exemplo n.º 18
0
 public override Cmd VisitHavocCmd(HavocCmd node)
 {
     return(base.VisitHavocCmd((HavocCmd)node.Clone()));
 }
Exemplo n.º 19
0
 public override Cmd VisitHavocCmd(HavocCmd node)
 {
     node.Vars.Iter(v => createdVars.Add(v.Name));
     return(node);
 }
Exemplo n.º 20
0
        private bool Analyse(Implementation impl, List<Cmd> cmdSeq, bool ControlFlowIsUniform)
        {
            foreach (Cmd c in cmdSeq)
            {
                if (c is AssignCmd)
                {
                    AssignCmd assignCmd = c as AssignCmd;
                    foreach (var a in assignCmd.Lhss.Zip(assignCmd.Rhss))
                    {

                        if (a.Item1 is SimpleAssignLhs)
                        {
                            SimpleAssignLhs lhs = a.Item1 as SimpleAssignLhs;
                            Expr rhs = a.Item2;
                            if (IsUniform(impl.Name, lhs.AssignedVariable.Name) &&
                                (!ControlFlowIsUniform || !IsUniform(impl.Name, rhs)))
                            {
                                SetNonUniform(impl.Name, lhs.AssignedVariable.Name);
                            }

                        }
                    }
                }
                else if (c is HavocCmd)
                {
                    HavocCmd havocCmd = c as HavocCmd;
                    foreach(IdentifierExpr ie in havocCmd.Vars)
                    {
                        if(IsUniform(impl.Name, ie.Decl.Name)) {
                            SetNonUniform(impl.Name, ie.Decl.Name);
                        }
                    }
                }
                else if (c is CallCmd)
                {
                    CallCmd callCmd = c as CallCmd;
                    DeclWithFormals Callee = GetProcedure(callCmd.callee);
                    Debug.Assert(Callee != null);

                    if (!ControlFlowIsUniform)
                    {
                        if (IsUniform(callCmd.callee))
                        {
                            SetNonUniform(callCmd.callee);
                        }
                    }
                    for (int i = 0; i < Callee.InParams.Count; i++)
                    {
                        if (IsUniform(callCmd.callee, Callee.InParams[i].Name)
                            && !IsUniform(impl.Name, callCmd.Ins[i]))
                        {
                            SetNonUniform(callCmd.callee, Callee.InParams[i].Name);
                        }
                    }

                    for (int i = 0; i < Callee.OutParams.Count; i++)
                    {
                        if (IsUniform(impl.Name, callCmd.Outs[i].Name)
                        && !IsUniform(callCmd.callee, Callee.OutParams[i].Name))
                        {
                            SetNonUniform(impl.Name, callCmd.Outs[i].Name);
                        }
                    }

                }
                else if (c is AssumeCmd)
                {
                    var ac = (AssumeCmd)c;
                    if (ControlFlowIsUniform && QKeyValue.FindBoolAttribute(ac.Attributes, "partition") &&
                        !IsUniform(impl.Name, ac.Expr))
                    {
                      ControlFlowIsUniform = false;
                    }
                }
            }

            return ControlFlowIsUniform;
        }
Exemplo n.º 21
0
 public SymbolicVariable GetFreshSymbolic(HavocCmd cmd, int varsIndex, ExecutionState owner)
 {
     ++Count;
     return(new SymbolicVariable(GetNewSymbolicVariableName(cmd, varsIndex), cmd, varsIndex));
 }
Exemplo n.º 22
0
        private HashSet <Variable> PropagateAvailableLinearVarsAcrossBlock(Block b)
        {
            HashSet <Variable> start = new HashSet <Variable>(availableLinearVars[b]);

            foreach (Cmd cmd in b.Cmds)
            {
                if (cmd is AssignCmd)
                {
                    AssignCmd assignCmd = (AssignCmd)cmd;
                    for (int i = 0; i < assignCmd.Lhss.Count; i++)
                    {
                        if (FindDomainName(assignCmd.Lhss[i].DeepAssignedVariable) == null)
                        {
                            continue;
                        }
                        IdentifierExpr ie = assignCmd.Rhss[i] as IdentifierExpr;
                        if (start.Contains(ie.Decl))
                        {
                            start.Remove(ie.Decl);
                        }
                        else
                        {
                            Error(ie, "unavailable source for a linear read");
                        }
                    }
                    foreach (AssignLhs assignLhs in assignCmd.Lhss)
                    {
                        if (FindDomainName(assignLhs.DeepAssignedVariable) == null)
                        {
                            continue;
                        }
                        start.Add(assignLhs.DeepAssignedVariable);
                    }
                }
                else if (cmd is CallCmd)
                {
                    foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(start))
                    {
                        Error(cmd, string.Format("Global variable {0} must be available at a call", g.Name));
                    }
                    CallCmd callCmd = (CallCmd)cmd;
                    for (int i = 0; i < callCmd.Proc.InParams.Count; i++)
                    {
                        if (FindDomainName(callCmd.Proc.InParams[i]) == null)
                        {
                            continue;
                        }
                        IdentifierExpr ie = callCmd.Ins[i] as IdentifierExpr;
                        if (start.Contains(ie.Decl))
                        {
                            start.Remove(ie.Decl);
                        }
                        else
                        {
                            Error(ie, "unavailable source for a linear read");
                        }
                    }
                    availableLinearVars[callCmd] = new HashSet <Variable>(start);
                    foreach (IdentifierExpr ie in callCmd.Outs)
                    {
                        if (FindDomainName(ie.Decl) == null)
                        {
                            continue;
                        }
                        start.Add(ie.Decl);
                    }
                }
                else if (cmd is ParCallCmd)
                {
                    foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(start))
                    {
                        Error(cmd, string.Format("Global variable {0} must be available at a call", g.Name));
                    }
                    ParCallCmd parCallCmd = (ParCallCmd)cmd;
                    foreach (CallCmd callCmd in parCallCmd.CallCmds)
                    {
                        for (int i = 0; i < callCmd.Proc.InParams.Count; i++)
                        {
                            if (FindDomainName(callCmd.Proc.InParams[i]) == null)
                            {
                                continue;
                            }
                            IdentifierExpr ie = callCmd.Ins[i] as IdentifierExpr;
                            if (start.Contains(ie.Decl))
                            {
                                start.Remove(ie.Decl);
                            }
                            else
                            {
                                Error(ie, "unavailable source for a linear read");
                            }
                        }
                    }
                    availableLinearVars[parCallCmd] = new HashSet <Variable>(start);
                    foreach (CallCmd callCmd in parCallCmd.CallCmds)
                    {
                        foreach (IdentifierExpr ie in callCmd.Outs)
                        {
                            if (FindDomainName(ie.Decl) == null)
                            {
                                continue;
                            }
                            start.Add(ie.Decl);
                        }
                    }
                }
                else if (cmd is HavocCmd)
                {
                    HavocCmd havocCmd = (HavocCmd)cmd;
                    foreach (IdentifierExpr ie in havocCmd.Vars)
                    {
                        if (FindDomainName(ie.Decl) == null)
                        {
                            continue;
                        }
                        start.Remove(ie.Decl);
                    }
                }
                else if (cmd is YieldCmd)
                {
                    foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(start))
                    {
                        Error(cmd, string.Format("Global variable {0} must be available at a yield", g.Name));
                    }
                    availableLinearVars[cmd] = new HashSet <Variable>(start);
                }
            }
            return(start);
        }
Exemplo n.º 23
0
 protected string GetNewSymbolicVariableName(HavocCmd havocCmd, int varsIndex)
 {
     return(GetNewSymbolicVariableName(havocCmd.Vars[varsIndex].Decl));
 }
Exemplo n.º 24
0
        // This procedure carries out variable slicing for all commands in the block. It will add more
        // local variables (needed for slicing) if impl is not null. The flag onlyGlobals restricts attention
        // to only slicing global variables
        private Block sliceBlock(Block block)
        {
            // The new list of commands that we will construct
            List <Cmd> sliced = new List <Cmd>();

            foreach (Cmd cmd in block.Cmds)
            {
                // Eliminate trivial statements like assume true
                if (isAssumeTrue(cmd))
                {
                    // This is an assume true, don't put it in the final program
                    if (tinfo != null)
                    {
                        tinfo.add(currImplementation.Name, block.Label, new InstrTrans(cmd, new List <Cmd>()));
                    }
                    continue;
                }

                // if cmd does not refer to a un-tracked global variable, then don't
                // bother, and move on to the next cmd
                if (isTracked(cmd))
                {
                    sliced.Add(cmd);
                    if (tinfo != null)
                    {
                        tinfo.add(currImplementation.Name, block.Label, new InstrTrans(cmd, cmd));
                    }
                    continue;
                }

                List <Cmd> newcmd = new List <Cmd>();

                // Now we need to look at what sort of a command are we dealing with
                if (cmd is AssignCmd)
                {
                    newcmd = AbstractAssign(cmd as AssignCmd);
                }
                else if (cmd is AssertCmd)
                {
                    Log.WriteLine(Log.Debug, "\nWarning: An assert has an untracked variable: it'll become assert false");
                    newcmd.Add(new AssertCmd(Token.NoToken, Expr.Literal(false)));
                }
                else if (cmd is AssumeCmd)
                {
                    // Do Nothing.
                }
                else if (cmd is CallCmd)
                {
                    CallCmd ccmd = (CallCmd)cmd;

                    // Process the call arguments: if anything is untracked, then
                    // convert to a dummy variable
                    var newIns = new List <Expr>();
                    foreach (var exp in ccmd.Ins)
                    {
                        if (exp == null)
                        {
                            newIns.Add(null);
                        }
                        else if (!isTracked(exp))
                        {
                            Debug.Assert(currImplementation != null);
                            var dvar = getNewLocal(exp.Type, currImplementation);
                            newcmd.Add(new HavocCmd(Token.NoToken, new List <IdentifierExpr>(new IdentifierExpr[] { Expr.Ident(dvar) })));
                            newIns.Add(Expr.Ident(dvar));
                        }
                        else
                        {
                            newIns.Add(exp);
                        }
                    }

                    // Process the returns: if anything is untracked then simply call
                    // the procedure, without storing its return value
                    var newOuts = new List <IdentifierExpr>();
                    foreach (var exp in ccmd.Outs)
                    {
                        if (exp == null)
                        {
                            newOuts.Add(null);
                        }
                        else if (!isTracked(exp))
                        {
                            Debug.Assert(currImplementation != null);
                            var dvar = getNewLocal(exp.Type, currImplementation);
                            newOuts.Add(Expr.Ident(dvar));
                        }
                        else
                        {
                            newOuts.Add(exp);
                        }
                    }

                    CallCmd tmp = new CallCmd(ccmd.tok, ccmd.Proc.Name, newIns, newOuts, ccmd.Attributes, ccmd.IsAsync);
                    tmp.Proc = ccmd.Proc; // just to keep the proc declarations in sync

                    newcmd.Add(tmp);
                }
                else if (cmd is HavocCmd)
                {
                    // Remove the havoced variables that are not tracked.
                    HavocCmd hcmd    = (HavocCmd)cmd;
                    var      newvars = new List <IdentifierExpr>();

                    foreach (IdentifierExpr ie in hcmd.Vars)
                    {
                        if (isTrackedVariable(ie.Decl))
                        {
                            newvars.Add(ie);
                        }
                    }

                    if (newvars.Count != 0)
                    {
                        newcmd.Add(new HavocCmd(hcmd.tok, newvars));
                    }
                }
                else
                {
                    cmd.Emit(new TokenTextWriter(Console.Out), 0);
                    throw new InternalError("Unkown Cmd type encountered during variable slicing");
                }

                sliced.AddRange(newcmd);
                if (tinfo != null)
                {
                    tinfo.add(currImplementation.Name, block.Label, new InstrTrans(cmd, newcmd));
                }
            }

            return(new Block(block.tok, block.Label, sliced, block.TransferCmd));
        }
Exemplo n.º 25
0
            private Expr CalculatePathCondition()
            {
                Expr returnExpr = Expr.True;

                foreach (Variable v in program.GlobalVariables())
                {
                    var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                    returnExpr = Expr.And(eqExpr, returnExpr);
                }
                if (first != null)
                {
                    foreach (Variable v in first.thisOutParams)
                    {
                        var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                        returnExpr = Expr.And(eqExpr, returnExpr);
                    }
                }
                foreach (Variable v in second.thatOutParams)
                {
                    var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                    returnExpr = Expr.And(eqExpr, returnExpr);
                }
                Block[] dfsStackAsArray = dfsStack.Reverse().ToArray();
                for (int i = dfsStackAsArray.Length - 1; i >= 0; i--)
                {
                    Block b = dfsStackAsArray[i];
                    for (int j = b.Cmds.Count - 1; j >= 0; j--)
                    {
                        Cmd cmd = b.Cmds[j];
                        if (cmd is AssumeCmd)
                        {
                            AssumeCmd assumeCmd = cmd as AssumeCmd;
                            returnExpr = Expr.And(new OldExpr(Token.NoToken, assumeCmd.Expr), returnExpr);
                        }
                        else if (cmd is AssignCmd)
                        {
                            AssignCmd assignCmd             = (cmd as AssignCmd).AsSimpleAssignCmd;
                            Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>();
                            for (int k = 0; k < assignCmd.Lhss.Count; k++)
                            {
                                map[assignCmd.Lhss[k].DeepAssignedVariable] = assignCmd.Rhss[k];
                            }
                            Substitution subst    = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>());
                            Substitution oldSubst = Substituter.SubstitutionFromHashtable(map);
                            returnExpr = (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr);
                        }
                        else if (cmd is HavocCmd)
                        {
                            HavocCmd                    havocCmd  = cmd as HavocCmd;
                            List <Variable>             existVars = new List <Variable>();
                            Dictionary <Variable, Expr> map       = new Dictionary <Variable, Expr>();
                            foreach (IdentifierExpr ie in havocCmd.Vars)
                            {
                                BoundVariable bv = GetBoundVariable(ie.Decl.TypedIdent.Type);
                                map[ie.Decl] = new IdentifierExpr(Token.NoToken, bv);
                                existVars.Add(bv);
                            }
                            Substitution subst    = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>());
                            Substitution oldSubst = Substituter.SubstitutionFromHashtable(map);
                            returnExpr = new ExistsExpr(Token.NoToken, existVars, (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr));
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                    }
                }
                return(returnExpr);
            }
Exemplo n.º 26
0
    // perform in place update of liveSet
    public static void Propagate(Cmd cmd, HashSet <Variable /*!*/> /*!*/ liveSet, bool allGlobalsAreLive)
    {
        Contract.Requires(cmd != null);
        Contract.Requires(cce.NonNullElements(liveSet));
        if (cmd is AssignCmd)
        {
            AssignCmd /*!*/ assignCmd = (AssignCmd)cce.NonNull(cmd);
            // I must first iterate over all the targets and remove the live ones.
            // After the removals are done, I must add the variables referred on
            // the right side of the removed targets

            AssignCmd     simpleAssignCmd = assignCmd.AsSimpleAssignCmd;
            HashSet <int> indexSet        = new HashSet <int>();
            int           index           = 0;
            foreach (AssignLhs /*!*/ lhs in simpleAssignCmd.Lhss)
            {
                Contract.Assert(lhs != null);
                SimpleAssignLhs salhs = lhs as SimpleAssignLhs;
                Contract.Assert(salhs != null);
                Variable var = salhs.DeepAssignedVariable;
                if (var != null && (liveSet.Contains(var) || (allGlobalsAreLive && var is GlobalVariable)))
                {
                    indexSet.Add(index);
                    liveSet.Remove(var);
                }
                index++;
            }
            index = 0;
            foreach (Expr /*!*/ expr in simpleAssignCmd.Rhss)
            {
                Contract.Assert(expr != null);
                if (indexSet.Contains(index))
                {
                    VariableCollector /*!*/ collector = new VariableCollector();
                    collector.Visit(expr);
                    if (allGlobalsAreLive)
                    {
                        liveSet.UnionWith(collector.usedVars.Where(v => v is LocalVariable || v is Formal));
                    }
                    else
                    {
                        liveSet.UnionWith(collector.usedVars);
                    }
                }
                index++;
            }
        }
        else if (cmd is HavocCmd)
        {
            HavocCmd /*!*/ havocCmd = (HavocCmd)cmd;
            foreach (IdentifierExpr /*!*/ expr in havocCmd.Vars)
            {
                Contract.Assert(expr != null);
                if (expr.Decl != null)
                {
                    liveSet.Remove(expr.Decl);
                }
            }
        }
        else if (cmd is PredicateCmd)
        {
            Contract.Assert((cmd is AssertCmd || cmd is AssumeCmd));
            PredicateCmd /*!*/ predicateCmd = (PredicateCmd)cce.NonNull(cmd);
            if (predicateCmd.Expr is LiteralExpr)
            {
                LiteralExpr le = (LiteralExpr)predicateCmd.Expr;
                if (le.IsFalse)
                {
                    liveSet.Clear();
                }
            }
            else
            {
                VariableCollector /*!*/ collector = new VariableCollector();
                collector.Visit(predicateCmd.Expr);
                if (allGlobalsAreLive)
                {
                    liveSet.UnionWith(collector.usedVars.Where(v => v is LocalVariable || v is Formal));
                }
                else
                {
                    liveSet.UnionWith(collector.usedVars);
                }
            }
        }
        else if (cmd is CommentCmd)
        {
            // comments are just for debugging and don't affect verification
        }
        else if (cmd is SugaredCmd)
        {
            SugaredCmd /*!*/ sugCmd = (SugaredCmd)cce.NonNull(cmd);
            Propagate(sugCmd.Desugaring, liveSet, allGlobalsAreLive);
        }
        else if (cmd is StateCmd)
        {
            StateCmd /*!*/   stCmd = (StateCmd)cce.NonNull(cmd);
            List <Cmd> /*!*/ cmds  = cce.NonNull(stCmd.Cmds);
            int len = cmds.Count;
            for (int i = len - 1; i >= 0; i--)
            {
                Propagate(cmds[i], liveSet, allGlobalsAreLive);
            }
            foreach (Variable /*!*/ v in stCmd.Locals)
            {
                Contract.Assert(v != null);
                liveSet.Remove(v);
            }
        }
        else
        {
            {
                Contract.Assert(false);
                throw new cce.UnreachableException();
            }
        }
    }
Exemplo n.º 27
0
        public static Duple <Procedure, Implementation> EqualityReduction(Implementation i1, Implementation i2, ParamMap argMap, HashSet <Variable> ignoreSet, out List <Variable> outputVarsForVFTask)
        {
            //map ins1
            //map outs1
            //save globals (1)
            //...
            //call
            //...
            //save outs
            //save globals (2)
            //restore globals (1)
            //...
            //call
            //...
            //compare

            Procedure
                d1 = i1.Proc,
                d2 = i2.Proc;

            var globals = new List <Variable>();

            foreach (IdentifierExpr ie in d1.Modifies)
            {
                globals.Add(ie.Decl);
            }
            foreach (IdentifierExpr ie in d2.Modifies)
            {
                if (!globals.Contains(ie.Decl))
                {
                    globals.Add(ie.Decl);
                }
            }

            /***** Produce mapped list of identifiers *****/

            string
                d1n = d1.Name,
                d2n = d2.Name;

            List <Variable>
            outs1     = FreshVariables(d1.OutParams, B.Factory.MakeLocal),
                outs2 = FreshVariables(d2.OutParams, B.Factory.MakeLocal),
                ins1  = FreshVariables(d1.InParams, (x, y) => B.Factory.MakeFormal(x, y, true)),
                ins2  = FreshVariables(d2.InParams, (x, y) => B.Factory.MakeFormal(x, y, true));

            /***** Compute correspondence between d1's ins/outs and d2's ins/outs *****/

            List <Variable>
            unionIns,
                unionOuts,
                newIns1,
                newOuts1,
                interIns,
                interOuts;

            MergeVariableSequencesByMap(ins1, ins2, argMap, out newIns1, out unionIns, out interIns);
            MergeVariableSequencesByMap(outs1, outs2, argMap, out newOuts1, out unionOuts, out interOuts);

            ins1  = newIns1;
            outs1 = newOuts1;

            /***** Map ignore set to the new variables *****/

            for (int i = 0; i < i2.OutParams.Count; i++)
            {
                if (ignoreSet.Contains(i2.OutParams[i]))
                {
                    Log.Out(Log.Warning, "Equality reduction ignoring variable: " + outs2[i].Name);
                    ignoreSet.Add(outs2[i]);
                }
            }

            /***** Emit instructions for saving and restoring *****/

            SaveBlock savedInitialGlobals = new SaveBlock(globals.Count);
            SaveBlock savedc1Globals      = new SaveBlock(globals.Count);
            SaveBlock savedOutputs        = new SaveBlock(interOuts.Count);

            var globalsArr = B.U.VariablesOfVariableSeq(globals);

            Cmd[]
            prec1Copy = savedInitialGlobals.EmitSave(globalsArr),
            postc1Copy    = savedc1Globals.EmitSave(globalsArr),
            postc1Restore = savedInitialGlobals.EmitRestore(globalsArr),
            prec2Copy     = savedOutputs.EmitSave(B.U.VariablesOfVariableSeq(interOuts));


            /***** Emit function calls *****/

            var c1Ins  = B.U.ExprSeqOfVariableSeq(ins1);
            var c1Outs = B.U.IdentifierExprSeqOfVariableSeq(outs1);
            var c2Ins  = B.U.ExprSeqOfVariableSeq(ins2);
            var c2Outs = B.U.IdentifierExprSeqOfVariableSeq(outs2);

            CallCmd
                c1 = new CallCmd(Token.NoToken, d1n, c1Ins, c1Outs),
                c2 = new CallCmd(Token.NoToken, d2n, c2Ins, c2Outs);

            /***** Emit comparison, outputVars *****/
            var outputVars     = new List <Duple <string, Variable> >();
            int numComparables = savedOutputs.Count + savedc1Globals.Count;

            //wait! if there aren't any comparable values, don't bother emitting a comparator
            if (numComparables == 0)
            {
                Log.Out(Log.Verifier, "No outputs: skipping (" + d1n + ", " + d2n + ")");
                outputVarsForVFTask = null;
                return(null);
            }

            if (Options.CheckOutputsForMaps)
            {
                foreach (Variable v in savedOutputs.Decls)
                {
                    if (v.TypedIdent.Type is MapType)
                    {
                        Log.Out(Log.MapEquivs, v.Name + " in " + i1.Name + " is a map comparable!");
                    }
                }
                foreach (Variable v in savedc1Globals.Decls)
                {
                    if (v.TypedIdent.Type is MapType || v.TypedIdent.Type is TypeSynonymAnnotation)
                    {
                        Log.Out(Log.MapEquivs, v.Name + " global is a map comparable!");
                    }
                }
            }

            StateBlock outputEqualityState = new StateBlock(numComparables, StateBlock.StateKind.FormalOut);

            Tuple <Expr, Variable>[] outputEqualityExprs = new Tuple <Expr, Variable> [numComparables];
            outputEqualityState.Initialize(Microsoft.Boogie.Type.Bool);

            IdentifierExpr[]
            comparisonPostc1Vars = savedc1Globals.Idents,
            comparisonPrec2Vars = savedOutputs.Idents;

            List <IdentifierExpr>
            comparisonOutIds      = B.U.IdentifierExprSeqOfVariableSeq(outs2),
                comparisonGlobals = B.U.IdentifierExprSeqOfVariableSeq(globals);

            for (int i = 0; i < savedOutputs.Count; i++)
            {
                outputEqualityExprs[i] = Tuple.Create(EmitEq(comparisonPrec2Vars[i], comparisonOutIds[i], ignoreSet), comparisonOutIds[i].Decl);
                outputVars.Add(new Duple <string, Variable>("Output_of_" + d1.Name + "_" + outs1[i].Name, savedOutputs.Decls[i]));
                outputVars.Add(new Duple <string, Variable>("Output_of_" + d2.Name + "_" + outs2[i].Name, outs2[i]));
            }
            for (int i = 0; i < savedc1Globals.Count; i++)
            {
                outputEqualityExprs[savedOutputs.Count + i] = Tuple.Create(EmitEq(comparisonPostc1Vars[i], comparisonGlobals[i], ignoreSet), comparisonGlobals[i].Decl);
                outputVars.Add(new Duple <string, Variable>("Output_of_" + d1.Name + "_" + globals[i].Name, savedc1Globals.Decls[i]));
                outputVars.Add(new Duple <string, Variable>("Output_of_" + d2.Name + "_" + globals[i].Name, globals[i]));
            }
            //new: we translate equalities as havoc lhs; lhs := lhs || x == x'; to enable diff counterexamples for each equality
            //havoc all lhs
            HavocCmd    hcmd = new HavocCmd(Token.NoToken, outputEqualityState.Idents.ToList());
            List <Expr> rhs  = new List <Expr>(outputEqualityExprs.Map(i => i.Item1));

            for (int i = 0; i < rhs.Count; ++i)
            {
                rhs[i] = Expr.Or(outputEqualityState.Idents[i], rhs[i]);
            }
            List <AssignLhs> lhs =
                new List <AssignLhs>(outputEqualityState.Idents.Map(x => new SimpleAssignLhs(Token.NoToken, x)));
            Cmd assgnCmd = new AssignCmd(Token.NoToken, lhs, rhs);

            /***** Save outputVars as globals (outputVarsForVFTask) *****/
            //note that this list is order dependent. later code will assume that variables are paired

            SaveBlock leftRightOutputs = new SaveBlock(outputVars.Count, StateBlock.StateKind.Global);

            leftRightOutputs.Initialize(outputVars.Map(x => new Duple <string, Microsoft.Boogie.Type>(x.fst, x.snd.TypedIdent.Type)));
            Cmd[] saveOutputsIntoGlobals = leftRightOutputs.EmitSave(outputVars.Map(x => x.snd).ToArray());
            outputVarsForVFTask = leftRightOutputs.Decls.ToList();

            /***** Compile procedure body ****/

            List <Cmd> body = new List <Cmd>();

            foreach (Cmd c in prec1Copy)
            {
                body.Add(c);
            }
            body.Add(c1);
            foreach (Cmd c in postc1Copy)
            {
                body.Add(c);
            }
            foreach (Cmd c in postc1Restore)
            {
                body.Add(c);
            }
            foreach (Cmd c in prec2Copy)
            {
                body.Add(c);
            }
            body.Add(c2);
            foreach (Cmd c in saveOutputsIntoGlobals)
            {
                body.Add(c);
            }
            body.Add(hcmd);
            body.Add(assgnCmd);

            //special hack to limit outvar to {:stmtTaintCollectorGlobalVar}
            if (Options.refinedStmtTaint)
            {
                Options.OutputVars.Clear();
                globals.Where(x => QKeyValue.FindBoolAttribute(x.Attributes, "stmtTaintCollectorGlobalVar")).Iter(x => Options.OutputVars.Add(x.ToString()));
            }

            List <Ensures> outputPostConditions = new List <Ensures>();

            if (Options.splitOutputEqualities)
            {
                outputPostConditions.AddRange(outputEqualityState.Idents.Map(y => new Ensures(false, y)));
                System.Diagnostics.Debug.Assert(outputEqualityState.Count == outputEqualityExprs.Length);
                for (int i = 0; i < outputPostConditions.Count; ++i)
                {
                    var name = outputEqualityExprs[i].Item2.Name;
                    //check if name matches with at least one of the outputVars patterns
                    if (Options.OutputVars.Count() > 0 && !Options.OutputVars.Any(x => name.Contains(x)))
                    {
                        outputPostConditions[i] = new Ensures(true, outputPostConditions[i].Condition);
                    }
                    outputPostConditions[i].Attributes =
                        new QKeyValue(Token.NoToken, "EqVar", new List <object>()
                    {
                        name
                    }, null);
                }
            }
            else if (!Options.EnumerateAllPaths)
            {
                outputPostConditions.Add(new Ensures(false, B.U.BigAnd(outputEqualityState.Idents)));
            }
            else //assert(false) causes all the paths to be enumerated
            {
                outputPostConditions.Add(new Ensures(false, Expr.False)); //to get exhaustive paths
            }
            var eqModifiesDupe = new List <IdentifierExpr>(d1.Modifies);

            eqModifiesDupe.AddRange(d2.Modifies);
            foreach (var v in leftRightOutputs.Decls)
            {
                eqModifiesDupe.Add(Expr.Ident(v));
            }

            //uniqueify eqModifies
            var eqModifiesUn   = new List <IdentifierExpr>();
            var eqModifiesVars = new HashSet <Variable>();
            var eqModifies     = new List <IdentifierExpr>();

            foreach (IdentifierExpr ie in eqModifiesDupe)
            {
                if (!eqModifiesVars.Contains(ie.Decl))
                {
                    eqModifies.Add(ie);
                }
                eqModifiesVars.Add(ie.Decl);
            }


            //var procName = "EQ_" + d1.Name + "__xx__" + d2.Name;
            var procName = mkEqProcName(d1.Name, d2.Name);

            Procedure eqProc =
                new Procedure(Token.NoToken, procName, B.C.empTypeVariableSeq, unionIns,
                              new List <Variable>(outputEqualityState.Decls),
                              B.C.empRequiresSeq, eqModifies, new List <Ensures>(outputPostConditions));

            BigBlock bl =
                new BigBlock(Token.NoToken, "AA_INSTR_EQ_BODY", body, null, B.C.dmyTransferCmd);
            List <BigBlock> bll = new List <BigBlock>();

            bll.Add(bl);

            List <Variable> locals = new List <Variable>();

            foreach (Variable v in savedOutputs.Decls)
            {
                locals.Add(v);
            }
            foreach (Variable v in savedc1Globals.Decls)
            {
                locals.Add(v);
            }
            foreach (Variable v in savedInitialGlobals.Decls)
            {
                locals.Add(v);
            }
            locals.AddRange(unionOuts);

            Implementation eqImp =
                new Implementation(Token.NoToken, procName, B.C.empTypeVariableSeq, unionIns,
                                   new List <Variable>(outputEqualityState.Decls),
                                   locals, new StmtList(bll, Token.NoToken));

            List <Declaration> l = new List <Declaration>();

            return(new Duple <Procedure, Implementation>(eqProc, eqImp));
        }
Exemplo n.º 28
0
 public override Cmd VisitHavocCmd(HavocCmd node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <Cmd>() != null);
     return(base.VisitHavocCmd((HavocCmd)node.Clone()));
 }
Exemplo n.º 29
0
        private void MakeDual(List <Cmd> cs, Cmd c)
        {
            if (c is CallCmd)
            {
                CallCmd Call = c as CallCmd;

                if (QKeyValue.FindBoolAttribute(Call.Proc.Attributes, "barrier_invariant"))
                {
                    // There may be a predicate, and there must be an invariant expression and at least one instantiation
                    Debug.Assert(Call.Ins.Count >= (2 + (verifier.uniformityAnalyser.IsUniform(Call.callee) ? 0 : 1)));
                    var BIDescriptor = new UnaryBarrierInvariantDescriptor(
                        verifier.uniformityAnalyser.IsUniform(Call.callee) ? Expr.True : Call.Ins[0],
                        Expr.Neq(Call.Ins[verifier.uniformityAnalyser.IsUniform(Call.callee) ? 0 : 1],
                                 verifier.Zero(1)),
                        Call.Attributes,
                        this, procName, verifier);
                    for (var i = 1 + (verifier.uniformityAnalyser.IsUniform(Call.callee) ? 0 : 1); i < Call.Ins.Count; i++)
                    {
                        BIDescriptor.AddInstantiationExpr(Call.Ins[i]);
                    }
                    BarrierInvariantDescriptors.Add(BIDescriptor);
                    return;
                }

                if (QKeyValue.FindBoolAttribute(Call.Proc.Attributes, "binary_barrier_invariant"))
                {
                    // There may be a predicate, and there must be an invariant expression and at least one pair of
                    // instantiation expressions
                    Debug.Assert(Call.Ins.Count >= (3 + (verifier.uniformityAnalyser.IsUniform(Call.callee) ? 0 : 1)));
                    var BIDescriptor = new BinaryBarrierInvariantDescriptor(
                        verifier.uniformityAnalyser.IsUniform(Call.callee) ? Expr.True : Call.Ins[0],
                        Expr.Neq(Call.Ins[verifier.uniformityAnalyser.IsUniform(Call.callee) ? 0 : 1],
                                 verifier.Zero(1)),
                        Call.Attributes,
                        this, procName, verifier);
                    for (var i = 1 + (verifier.uniformityAnalyser.IsUniform(Call.callee) ? 0 : 1); i < Call.Ins.Count; i += 2)
                    {
                        BIDescriptor.AddInstantiationExprPair(Call.Ins[i], Call.Ins[i + 1]);
                    }
                    BarrierInvariantDescriptors.Add(BIDescriptor);
                    return;
                }


                if (GPUVerifier.IsBarrier(Call.Proc))
                {
                    // Assert barrier invariants
                    foreach (var BIDescriptor in BarrierInvariantDescriptors)
                    {
                        QKeyValue SourceLocationInfo = BIDescriptor.GetSourceLocationInfo();
                        cs.Add(BIDescriptor.GetAssertCmd());
                        var vd = new VariableDualiser(1, verifier.uniformityAnalyser, procName);
                        if (GPUVerifyVCGenCommandLineOptions.BarrierAccessChecks)
                        {
                            foreach (Expr AccessExpr in BIDescriptor.GetAccessedExprs())
                            {
                                var Assert = new AssertCmd(Token.NoToken, AccessExpr, MakeThreadSpecificAttributes(SourceLocationInfo, 1));
                                Assert.Attributes = new QKeyValue(Token.NoToken, "barrier_invariant_access_check",
                                                                  new List <object> {
                                    Expr.True
                                }, Assert.Attributes);
                                cs.Add(vd.VisitAssertCmd(Assert));
                            }
                        }
                    }
                }

                List <Expr> uniformNewIns    = new List <Expr>();
                List <Expr> nonUniformNewIns = new List <Expr>();

                for (int i = 0; i < Call.Ins.Count; i++)
                {
                    if (verifier.uniformityAnalyser.knowsOf(Call.callee) && verifier.uniformityAnalyser.IsUniform(Call.callee, verifier.uniformityAnalyser.GetInParameter(Call.callee, i)))
                    {
                        uniformNewIns.Add(Call.Ins[i]);
                    }
                    else if (!verifier.OnlyThread2.Contains(Call.callee))
                    {
                        nonUniformNewIns.Add(new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(Call.Ins[i]));
                    }
                }
                for (int i = 0; i < Call.Ins.Count; i++)
                {
                    if (
                        !(verifier.uniformityAnalyser.knowsOf(Call.callee) && verifier.uniformityAnalyser.IsUniform(Call.callee, verifier.uniformityAnalyser.GetInParameter(Call.callee, i))) &&
                        !verifier.OnlyThread1.Contains(Call.callee))
                    {
                        nonUniformNewIns.Add(new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(Call.Ins[i]));
                    }
                }

                List <Expr> newIns = uniformNewIns;
                newIns.AddRange(nonUniformNewIns);

                List <IdentifierExpr> uniformNewOuts    = new List <IdentifierExpr>();
                List <IdentifierExpr> nonUniformNewOuts = new List <IdentifierExpr>();
                for (int i = 0; i < Call.Outs.Count; i++)
                {
                    if (verifier.uniformityAnalyser.knowsOf(Call.callee) && verifier.uniformityAnalyser.IsUniform(Call.callee, verifier.uniformityAnalyser.GetOutParameter(Call.callee, i)))
                    {
                        uniformNewOuts.Add(Call.Outs[i]);
                    }
                    else
                    {
                        nonUniformNewOuts.Add(new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitIdentifierExpr(Call.Outs[i].Clone() as IdentifierExpr) as IdentifierExpr);
                    }
                }
                for (int i = 0; i < Call.Outs.Count; i++)
                {
                    if (!(verifier.uniformityAnalyser.knowsOf(Call.callee) && verifier.uniformityAnalyser.IsUniform(Call.callee, verifier.uniformityAnalyser.GetOutParameter(Call.callee, i))))
                    {
                        nonUniformNewOuts.Add(new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitIdentifierExpr(Call.Outs[i].Clone() as IdentifierExpr) as IdentifierExpr);
                    }
                }

                List <IdentifierExpr> newOuts = uniformNewOuts;
                newOuts.AddRange(nonUniformNewOuts);

                CallCmd NewCallCmd = new CallCmd(Call.tok, Call.callee, newIns, newOuts);

                NewCallCmd.Proc = Call.Proc;

                NewCallCmd.Attributes = Call.Attributes;

                if (NewCallCmd.callee.StartsWith("_LOG_ATOMIC"))
                {
                    QKeyValue curr = NewCallCmd.Attributes;
                    if (curr.Key.StartsWith("arg"))
                    {
                        NewCallCmd.Attributes = new QKeyValue(Token.NoToken, curr.Key, new List <object>(new object[] { Dualise(curr.Params[0] as Expr, 1) }), curr.Next);
                    }
                    for (curr = NewCallCmd.Attributes; curr.Next != null; curr = curr.Next)
                    {
                        if (curr.Next.Key.StartsWith("arg"))
                        {
                            curr.Next = new QKeyValue(Token.NoToken, curr.Next.Key, new List <object>(new object[] { Dualise(curr.Next.Params[0] as Expr, 1) }), curr.Next.Next);
                        }
                    }
                }
                else if (NewCallCmd.callee.StartsWith("_CHECK_ATOMIC"))
                {
                    QKeyValue curr = NewCallCmd.Attributes;
                    if (curr.Key.StartsWith("arg"))
                    {
                        NewCallCmd.Attributes = new QKeyValue(Token.NoToken, curr.Key, new List <object>(new object[] { Dualise(curr.Params[0] as Expr, 2) }), curr.Next);
                    }
                    for (curr = NewCallCmd.Attributes; curr.Next != null; curr = curr.Next)
                    {
                        if (curr.Next.Key.StartsWith("arg"))
                        {
                            curr.Next = new QKeyValue(Token.NoToken, curr.Next.Key, new List <object>(new object[] { Dualise(curr.Next.Params[0] as Expr, 2) }), curr.Next.Next);
                        }
                    }
                }

                cs.Add(NewCallCmd);

                if (GPUVerifier.IsBarrier(Call.Proc))
                {
                    foreach (var BIDescriptor in BarrierInvariantDescriptors)
                    {
                        foreach (var Instantiation in BIDescriptor.GetInstantiationCmds())
                        {
                            cs.Add(Instantiation);
                        }
                    }
                    BarrierInvariantDescriptors.Clear();
                }
            }
            else if (c is AssignCmd)
            {
                AssignCmd assign = c as AssignCmd;

                var vd1 = new VariableDualiser(1, verifier.uniformityAnalyser, procName);
                var vd2 = new VariableDualiser(2, verifier.uniformityAnalyser, procName);

                List <AssignLhs> lhss1 = new List <AssignLhs>();
                List <AssignLhs> lhss2 = new List <AssignLhs>();

                List <Expr> rhss1 = new List <Expr>();
                List <Expr> rhss2 = new List <Expr>();

                foreach (var pair in assign.Lhss.Zip(assign.Rhss))
                {
                    if (pair.Item1 is SimpleAssignLhs &&
                        verifier.uniformityAnalyser.IsUniform(procName,
                                                              (pair.Item1 as SimpleAssignLhs).AssignedVariable.Name))
                    {
                        lhss1.Add(pair.Item1);
                        rhss1.Add(pair.Item2);
                    }
                    else
                    {
                        lhss1.Add(vd1.Visit(pair.Item1.Clone() as AssignLhs) as AssignLhs);
                        lhss2.Add(vd2.Visit(pair.Item1.Clone() as AssignLhs) as AssignLhs);
                        rhss1.Add(vd1.VisitExpr(pair.Item2.Clone() as Expr));
                        rhss2.Add(vd2.VisitExpr(pair.Item2.Clone() as Expr));
                    }
                }

                Debug.Assert(lhss1.Count > 0);
                cs.Add(new AssignCmd(Token.NoToken, lhss1, rhss1));

                if (lhss2.Count > 0)
                {
                    cs.Add(new AssignCmd(Token.NoToken, lhss2, rhss2));
                }
            }
            else if (c is HavocCmd)
            {
                HavocCmd havoc = c as HavocCmd;
                Debug.Assert(havoc.Vars.Count() == 1);

                HavocCmd newHavoc;

                newHavoc = new HavocCmd(havoc.tok, new List <IdentifierExpr>(new IdentifierExpr[] {
                    (IdentifierExpr)(new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitIdentifierExpr(havoc.Vars[0].Clone() as IdentifierExpr)),
                    (IdentifierExpr)(new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitIdentifierExpr(havoc.Vars[0].Clone() as IdentifierExpr))
                }));

                cs.Add(newHavoc);
            }
            else if (c is AssertCmd)
            {
                AssertCmd a = c as AssertCmd;

                if (QKeyValue.FindBoolAttribute(a.Attributes, "sourceloc") ||
                    QKeyValue.FindBoolAttribute(a.Attributes, "block_sourceloc") ||
                    QKeyValue.FindBoolAttribute(a.Attributes, "array_bounds"))
                {
                    // This is just a location marker, so we do not dualise it
                    cs.Add(new AssertCmd(Token.NoToken, new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(a.Expr.Clone() as Expr),
                                         (QKeyValue)a.Attributes.Clone()));
                }
                else
                {
                    var isUniform = verifier.uniformityAnalyser.IsUniform(procName, a.Expr);
                    cs.Add(MakeThreadSpecificAssert(a, 1));
                    if (!GPUVerifyVCGenCommandLineOptions.AsymmetricAsserts && !ContainsAsymmetricExpression(a.Expr) && !isUniform)
                    {
                        cs.Add(MakeThreadSpecificAssert(a, 2));
                    }
                }
            }
            else if (c is AssumeCmd)
            {
                AssumeCmd ass = c as AssumeCmd;

                if (QKeyValue.FindStringAttribute(ass.Attributes, "captureState") != null)
                {
                    cs.Add(c);
                }
                else if (QKeyValue.FindBoolAttribute(ass.Attributes, "backedge"))
                {
                    AssumeCmd newAss = new AssumeCmd(c.tok, Expr.Or(new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr),
                                                                    new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr)));
                    newAss.Attributes = ass.Attributes;
                    cs.Add(newAss);
                }
                else if (QKeyValue.FindBoolAttribute(ass.Attributes, "atomic_refinement"))
                {
                    // Generate the following:
                    // havoc v$1, v$2;
                    // assume !_USED[offset$1][v$1];
                    // _USED[offset$1][v$1] := true;
                    // assume !_USED[offset$2][v$2];
                    // _USED[offset$2][v$2] := true;

                    Expr variable = QKeyValue.FindExprAttribute(ass.Attributes, "variable");
                    Expr offset   = QKeyValue.FindExprAttribute(ass.Attributes, "offset");

                    List <Expr>    offsets  = (new int[] { 1, 2 }).Select(x => new VariableDualiser(x, verifier.uniformityAnalyser, procName).VisitExpr(offset.Clone() as Expr)).ToList();
                    List <Expr>    vars     = (new int[] { 1, 2 }).Select(x => new VariableDualiser(x, verifier.uniformityAnalyser, procName).VisitExpr(variable.Clone() as Expr)).ToList();
                    IdentifierExpr arrayref = new IdentifierExpr(Token.NoToken, verifier.FindOrCreateUsedMap(QKeyValue.FindStringAttribute(ass.Attributes, "arrayref"), vars[0].Type));

                    foreach (int i in (new int[] { 0, 1 }))
                    {
                        AssumeCmd newAss = new AssumeCmd(c.tok, Expr.Not(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1),
                                                                                      new List <Expr> {
                            new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1),
                                         new List <Expr> {
                                arrayref, offsets[i]
                            }),
                            vars[i]
                        })));

                        cs.Add(newAss);

                        var lhs = new MapAssignLhs(Token.NoToken, new MapAssignLhs(Token.NoToken, new SimpleAssignLhs(Token.NoToken, arrayref),
                                                                                   new List <Expr> {
                            offsets[i]
                        }), new List <Expr> {
                            vars[i]
                        });
                        AssignCmd assign = new AssignCmd(c.tok,
                                                         new List <AssignLhs> {
                            lhs
                        },
                                                         new List <Expr> {
                            Expr.True
                        });

                        cs.Add(assign);
                    }
                }
                else
                {
                    var       isUniform = verifier.uniformityAnalyser.IsUniform(procName, ass.Expr);
                    AssumeCmd newAss    = new AssumeCmd(c.tok, new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr));
                    if (!ContainsAsymmetricExpression(ass.Expr) && !isUniform)
                    {
                        newAss.Expr = Expr.And(newAss.Expr, new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr));
                    }
                    newAss.Attributes = ass.Attributes;
                    cs.Add(newAss);
                }
            }
            else
            {
                Debug.Assert(false);
            }
        }
Exemplo n.º 30
0
 //not implemented cmds
 public override Cmd VisitHavocCmd(HavocCmd node)
 {
     //handled elsewhere, since havoc of multiple variables is desugared into multiple basic havoc commands
     throw new NotImplementedException();
 }