示例#1
0
            private AssignCmd VisitMapAssignment(AssignLhs lhs, Expr rhs)
            {
                Debug.Assert(lhs.DeepAssignedVariable.TypedIdent.Type.IsMap);
                var ac = new AssignCmd(Token.NoToken, new List <AssignLhs>()
                {
                    lhs
                }, new List <Expr>()
                {
                    rhs
                });

                if (lhs.Type.IsMap)
                {
                    ac = VisitEntireMapAssignment(lhs, rhs);
                    return(ac);
                }
                var index = (lhs.AsExpr as NAryExpr).Args[1];
                var l     = VisitMapStore(lhs.DeepAssignedIdentifier, index, rhs);

                if (l != null)
                {
                    ac = new AssignCmd(Token.NoToken, new List <AssignLhs>(), new List <Expr>()); //overwrite
                    //to generate M'[x] := y
                    ac.Lhss = l
                              .Select(x => new MapAssignLhs(Token.NoToken, new SimpleAssignLhs(Token.NoToken, x.Item1), new List <Expr>()
                    {
                        index
                    }))
                              .ToList <AssignLhs>();
                    ac.Rhss = l
                              .Select(x => x.Item2)
                              .ToList();
                }
                return(ac);
            }
示例#2
0
            /// <summary>
            /// M := E
            /// </summary>
            /// <param name="lhs"></param>
            /// <param name="rhs"></param>
            /// <returns></returns>
            private AssignCmd VisitEntireMapAssignment(AssignLhs lhs, Expr rhs)
            {
                Debug.Assert(lhs.DeepAssignedVariable.TypedIdent.Type.IsMap);
                var ac = new AssignCmd(Token.NoToken, new List <AssignLhs>()
                {
                    lhs
                }, new List <Expr>()
                {
                    rhs
                });

                //M := old(M)
                if (!
                    (rhs is OldExpr &&
                     ((OldExpr)rhs).Expr is IdentifierExpr &&
                     ((IdentifierExpr)((OldExpr)rhs).Expr).Decl == lhs.DeepAssignedVariable)
                    )
                {
                    Console.WriteLine("Don't handle direct stores M := e yet, found {0}", ac.ToString());
                    unhandledCommands.Add(ac);
                    return(ac);
                }
                var splitVars = allAllocSites
                                .Select(x => GetOrCreateSplitMap(lhs.DeepAssignedVariable, x))
                                .ToList();

                ac.Lhss = splitVars.Select(x => (AssignLhs) new SimpleAssignLhs(Token.NoToken, IdentifierExpr.Ident(x))).ToList();
                ac.Rhss = splitVars.Select(x => (Expr) new OldExpr(Token.NoToken, (Expr)IdentifierExpr.Ident(x))).ToList();
                return(ac);
            }
示例#3
0
 public static Expr SelectOfAssignLhs(AssignLhs lhs)
 {
     if (lhs is MapAssignLhs)
     {
         return(Expr.Select(SelectOfAssignLhs(((MapAssignLhs)lhs).Map), ((MapAssignLhs)lhs).Indexes));
     }
     else
     {
         return(Expr.Ident(lhs.DeepAssignedVariable));
     }
 }
示例#4
0
        public override Block VisitBlock(Block node)
        {
            foreach (Cmd c in node.Cmds)
            {
                AssignCmd ac = c as AssignCmd;
                if (ac == null)
                {
                    continue;
                }
                Utils.Assert(ac.Lhss.Count == 1 && ac.Rhss.Count == 1, "Expected assignments to have 1 lhs and 1 rhs");
                AssignLhs lhs = ac.Lhss.ElementAt(0);
                Expr      rhs = ac.Rhss.ElementAt(0);

                if (!(lhs.Type.IsBv && lhs.DeepAssignedIdentifier.Name.Equals("RSP")))
                {
                    continue;
                }                                                                                    //lhs is RSP
                if (!(rhs is NAryExpr))
                {
                    continue;
                }                                     //rhs is function application
                if (!((NAryExpr)rhs).Fun.FunctionName.Equals("MINUS_64"))
                {
                    continue;
                }                                                                       //rhs is a minus operation
                if (!(((NAryExpr)rhs).Args.ElementAt(0) is IdentifierExpr))
                {
                    continue;
                }                                                                         //1st argument is a id like RHS
                if (!(((NAryExpr)rhs).Args.ElementAt(0) as IdentifierExpr).Name.Equals("RSP"))
                {
                    continue;
                }                                                                                            //1st argument is a id like RHS
                if (!(((NAryExpr)rhs).Args.ElementAt(1) is LiteralExpr))
                {
                    continue;
                }                                                                      //2nd argument is a constant like 384bv64
                if (!((((NAryExpr)rhs).Args.ElementAt(1) as LiteralExpr).Type == BType.GetBvType(64)))
                {
                    continue;
                }                                                                                                    //2nd argument is bitvector literal

                int operand = ((((NAryExpr)rhs).Args.ElementAt(1) as LiteralExpr).asBvConst).Value.ToInt;

                Utils.Assert(blocksWithinNautralLoops.All(x => x.Label != node.Label),
                             "Setting RSP within a loop: " + ac + " at label " + node.Label);

                rsp_subtractions.Add(operand);
            }

            return(base.VisitBlock(node));
        }
示例#5
0
        /* returns (mem, rcx, rdi, al) */
        public static Tuple <Variable, Expr, Expr, Expr> getRepStosbArgs(AssignCmd c)
        {
            Utils.Assert(getSlashVerifyCmdType(c) == SlashVerifyCmdType.RepStosB, "getRepStosbArgs not a RepStosb command");
            Utils.Assert(c.Lhss.Count == 1 && c.Rhss.Count == 1, "getRepStosbArgs not handling parallel assignCmds");
            AssignLhs lhs = c.Lhss[0];
            Expr      rhs = c.Rhss[0];

            Utils.Assert(((NAryExpr)rhs).Args.Count == 4, "RepStosb must have 4 arguments");
            return(Tuple.Create <Variable, Expr, Expr, Expr>((((NAryExpr)rhs).Args[0] as IdentifierExpr).Decl,
                                                             ((NAryExpr)rhs).Args[1],
                                                             ((NAryExpr)rhs).Args[2],
                                                             ((NAryExpr)rhs).Args[3]));
        }
示例#6
0
 ////////////////////////////////////////////////////////////////////////////////////
 internal ReferenceExpression makeReferenceExpression(AssignLhs assignLhs)
 {
     if (assignLhs is SimpleAssignLhs)
     {
         return(makeReferenceExpression((SimpleAssignLhs)assignLhs));
     }
     else if (assignLhs is MapAssignLhs)
     {
         return(makeReferenceExpression((MapAssignLhs)assignLhs));
     }
     else
     {
         throw new Exception("Unsupported Boogie LHS type:" + assignLhs.ToString());
     }
 }
示例#7
0
 /////////////////////////////////////////////////////////////////////////////////////
 private Expression getAssignmentSourceExpression(AssignLhs target, Expression source)
 {
     if (target is SimpleAssignLhs)
     {
         return(getAssignmentSourceExpression((SimpleAssignLhs)target, source));
     }
     else if (target is MapAssignLhs)
     {
         return(getAssignmentSourceExpression((MapAssignLhs)target, source));
     }
     else
     {
         throw new NotImplementedException();
     }
 }
示例#8
0
    public override Cmd VisitAssignCmd(AssignCmd node)
    {
      HashSet<Variable> rhsVars = new HashSet<Variable>();
      for (int i = 0; i < node.Lhss.Count; i++)
      {
        AssignLhs lhs = node.Lhss[i];
        Variable lhsVar = lhs.DeepAssignedVariable;
        string domainName = FindDomainName(lhsVar);
        if (domainName == null) continue;
        if (!(lhs is SimpleAssignLhs))
        {
          Error(node, $"Only simple assignment allowed on linear variable {lhsVar.Name}");
          continue;
        }

        IdentifierExpr rhs = node.Rhss[i] as IdentifierExpr;
        if (rhs == null)
        {
          Error(node, $"Only variable can be assigned to linear variable {lhsVar.Name}");
          continue;
        }

        string rhsDomainName = FindDomainName(rhs.Decl);
        if (rhsDomainName == null)
        {
          Error(node, $"Only linear variable can be assigned to linear variable {lhsVar.Name}");
          continue;
        }

        if (domainName != rhsDomainName)
        {
          Error(node,
            $"Linear variable of domain {rhsDomainName} cannot be assigned to linear variable of domain {domainName}");
          continue;
        }

        if (rhsVars.Contains(rhs.Decl))
        {
          Error(node, $"Linear variable {rhs.Decl.Name} can occur only once in the right-hand-side of an assignment");
          continue;
        }

        rhsVars.Add(rhs.Decl);
      }

      return base.VisitAssignCmd(node);
    }
示例#9
0
 // Return the variable that is being assigned to in the LHS of an assignment.
 //    id := ...  then id
 //    m[...] := ... then m
 private static IdentifierExpr getAssignedVariable(AssignLhs lhs)
 {
     if (lhs is SimpleAssignLhs)
     {
         SimpleAssignLhs sl = (SimpleAssignLhs)lhs;
         return(sl.AssignedVariable);
     }
     else if (lhs is MapAssignLhs)
     {
         MapAssignLhs ml = (MapAssignLhs)lhs;
         return(getAssignedVariable(ml.Map));
     }
     else
     {
         lhs.Emit(new TokenTextWriter(Console.Out));
         throw new InternalError("Unknown type of AssignLhs");
     }
 }
示例#10
0
        /* returns (mem, addr, data) */
        public static Tuple <Variable, Expr, Expr> getStoreArgs(AssignCmd c)
        {
            Func <Expr, string, bool> RhsMatch = delegate(Expr x, String s)
            {
                return(x is NAryExpr && ((NAryExpr)x).Fun.FunctionName.Equals(s));
            };

            Utils.Assert(c.Lhss.Count == 1 && c.Rhss.Count == 1, "getStoreArgs not handling parallel assignCmds");
            AssignLhs lhs = c.Lhss[0];
            Expr      rhs = c.Rhss[0];

            Utils.Assert(RhsMatch(rhs, "STORE_LE_8") || RhsMatch(rhs, "STORE_LE_16") || RhsMatch(rhs, "STORE_LE_32") || RhsMatch(rhs, "STORE_LE_64"),
                         "Expected store expression");

            Utils.Assert(((NAryExpr)rhs).Args.Count == 3, "Store must have 3 arguments");
            return(Tuple.Create <Variable, Expr, Expr>((((NAryExpr)rhs).Args[0] as IdentifierExpr).Decl,
                                                       ((NAryExpr)rhs).Args[1],
                                                       ((NAryExpr)rhs).Args[2]));
        }
示例#11
0
        public static Duple <StoreLhs, Expr> Make(AssignLhs alhs, Expr e)
        {
            if (alhs is SimpleAssignLhs)
            {
                return(new Duple <StoreLhs, Expr>(new StoreLhs(alhs.DeepAssignedVariable), e));
            }
            if (alhs is MapAssignLhs)
            {
                var mlhs = alhs as MapAssignLhs;
                var var  = mlhs.DeepAssignedVariable;

                var curLhs  = mlhs.Map;
                var curExpr = Expr.Store(SelectOfAssignLhs(curLhs), mlhs.Indexes, e);
                if (curLhs is MapAssignLhs)
                {
                    return(Make(curLhs, curExpr));
                }
                return(new Duple <StoreLhs, Expr>(new StoreLhs(var), curExpr));
            }

            return(null); //impossible!
        }
示例#12
0
        /////////////////
        // here begin the visit overrides that are only necessary for the cloning, and have nothing to do with the substitution itself
        // --> one might move them to a clone visitor..
        /////////////////

        public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
        {
            var dispatchedIndices = new List <Expr>();

            foreach (var ind in node.Indexes)
            {
                dispatchedIndices.Add(VisitExpr(ind));
            }

            AssignLhs newAssignLhs = null;

            if (node.Map is MapAssignLhs)
            {
                newAssignLhs = VisitMapAssignLhs(node.Map as MapAssignLhs);
            }
            else if (node.Map is SimpleAssignLhs)
            {
                newAssignLhs = VisitSimpleAssignLhs(node.Map as SimpleAssignLhs);
            }


            return(new MapAssignLhs(node.tok, newAssignLhs, dispatchedIndices));
        }
示例#13
0
        private AssignLhs TransformLhs(AssignLhs lhs)
        {
            var mapLhs = lhs as MapAssignLhs;

            if (mapLhs == null ||
                !(mapLhs.Map is SimpleAssignLhs) ||
                mapLhs.Indexes.Count() != 1)
            {
                return((AssignLhs)Visit(lhs));
            }

            var map = (mapLhs.Map as SimpleAssignLhs).AssignedVariable;

            if (!Arrays.ContainsKey(map.Name))
            {
                return((AssignLhs)Visit(lhs));
            }

            Debug.Assert(mapLhs.Indexes[0] is LiteralExpr);

            return(new SimpleAssignLhs(
                       lhs.tok, new IdentifierExpr(Token.NoToken,
                                                   Eliminator.MakeVariableForArrayIndex(map.Decl, mapLhs.Indexes[0].ToString()))));
        }
        private Block Abstract(Block b)
        {
            var newCmds = new List <Cmd>();

            foreach (Cmd c in b.Cmds)
            {
                if (c is CallCmd)
                {
                    var call = c as CallCmd;

                    if (QKeyValue.FindBoolAttribute(call.Attributes, "atomic"))
                    {
                        // Discard the call
                        Debug.Assert(call.Ins.Count >= 1);
                        var ie = call.Ins[0] as IdentifierExpr;
                        Debug.Assert(ie != null);
                        Debug.Assert(verifier.ArrayModelledAdversarially(ie.Decl));
                        continue;
                    }

                    for (int i = 0; i < call.Ins.Count; i++)
                    {
                        ReadCollector rc = new ReadCollector(verifier.KernelArrayInfo);
                        rc.Visit(call.Ins[i]);
                        bool foundAdversarial = false;
                        foreach (AccessRecord ar in rc.NonPrivateAccesses)
                        {
                            if (verifier.ArrayModelledAdversarially(ar.V))
                            {
                                foundAdversarial = true;
                                break;
                            }
                        }

                        if (foundAdversarial)
                        {
                            LocalVariable lv = new LocalVariable(
                                Token.NoToken,
                                new TypedIdent(Token.NoToken, "_abstracted_call_arg_" + abstractedCallArgCounter, call.Ins[i].Type));
                            abstractedCallArgCounter++;
                            newLocalVars.Add(lv);
                            newCmds.Add(new HavocCmd(
                                            Token.NoToken,
                                            new List <IdentifierExpr>(new IdentifierExpr[] { new IdentifierExpr(Token.NoToken, lv) })));
                            call.Ins[i] = new IdentifierExpr(Token.NoToken, lv);
                        }
                    }
                }

                if (c is AssignCmd)
                {
                    AssignCmd assign = c as AssignCmd;

                    var lhss = new List <AssignLhs>();
                    var rhss = new List <Expr>();

                    foreach (var lhsRhs in assign.Lhss.Zip(assign.Rhss))
                    {
                        AssignLhs     lhs = lhsRhs.Item1;
                        Expr          rhs = lhsRhs.Item2;
                        ReadCollector rc  = new ReadCollector(verifier.KernelArrayInfo);
                        rc.Visit(rhs);

                        bool foundAdversarial = false;
                        foreach (AccessRecord ar in rc.NonPrivateAccesses)
                        {
                            if (verifier.ArrayModelledAdversarially(ar.V))
                            {
                                foundAdversarial = true;
                                break;
                            }
                        }

                        if (foundAdversarial)
                        {
                            Debug.Assert(lhs is SimpleAssignLhs);
                            newCmds.Add(new HavocCmd(c.tok, new List <IdentifierExpr>(new IdentifierExpr[] { (lhs as SimpleAssignLhs).AssignedVariable })));
                            continue;
                        }

                        WriteCollector wc = new WriteCollector(verifier.KernelArrayInfo);
                        wc.Visit(lhs);
                        if (wc.FoundNonPrivateWrite())
                        {
                            if (verifier.ArrayModelledAdversarially(wc.GetAccess().V))
                            {
                                continue; // Just remove the write
                            }
                        }

                        lhss.Add(lhs);
                        rhss.Add(rhs);
                    }

                    if (lhss.Count != 0)
                    {
                        newCmds.Add(new AssignCmd(assign.tok, lhss, rhss));
                    }

                    continue;
                }

                newCmds.Add(c);
            }

            b.Cmds = newCmds;
            return(b);
        }
示例#15
0
 /////////////////////////////////////////////////////////////////////////////////////
 private ProgramVariable getAssignmentTarget(BasicBlock current, AssignLhs target)
 {
     return(scope.findVariable(scope.getVarUName(target.DeepAssignedVariable)));
 }
示例#16
0
        private List <Cmd> AbstractAssign(AssignCmd acmd)
        {
            var newcmd = new List <Cmd>();

            // !KeepSimple: then map indices are given special treatment
            var KeepSimple = UseSimpleSlicing || (currImplementation == null) || (acmd.Lhss.Count != 1);

            if (acmd.Lhss.Count != 1)
            {
                EncounteredParallelAssignment = true;
            }

            var newLhss     = new List <AssignLhs>();
            var newRhss     = new List <Expr>();
            var varsToHavoc = new HashSet <Variable>();

            for (int i = 0; i < acmd.Lhss.Count; i++)
            {
                AssignLhs lhs = acmd.Lhss[i];
                Expr      rhs = acmd.Rhss[i];

                //IdentifierExpr assignedVar = getAssignedVariable(lhs);
                IdentifierExpr assignedVar = lhs.DeepAssignedIdentifier;

                if (isTrackedVariable(assignedVar.Decl))
                {
                    if (lhs is MapAssignLhs && !indicesAreTracked((MapAssignLhs)lhs))
                    {
                        // convert to assignedVar := *
                        varsToHavoc.Add(assignedVar.Decl);
                    }
                    else if (!isTracked(rhs))
                    {
                        // Convert to lhs := *
                        if (KeepSimple || lhs is SimpleAssignLhs)
                        {
                            varsToHavoc.Add(assignedVar.Decl);
                        }
                        else
                        {
                            // convert to "havoc lhs" as follows:
                            // havoc dummy; lhs := dummy;
                            // This is done when lhs is Mem[x]. We're not
                            // allowed to say "havoc Mem[x]".

                            // We should be doing this only when we can add new
                            // local variables
                            Debug.Assert(currImplementation != null);

                            // Get new local variable dummy
                            LocalVariable dummy = getNewLocal(lhs.Type, currImplementation);

                            // havoc dummy
                            newcmd.Add(BoogieAstFactory.MkHavocVar(dummy));

                            // lhs := dummy
                            newLhss.Add(lhs);
                            newRhss.Add(Expr.Ident(dummy));
                        }
                    }
                    else
                    {
                        // It is possible to come here because a variable may be untracked in this scope,
                        // yet tracked globally because it is on the lhs
                        newLhss.Add(lhs);
                        newRhss.Add(rhs);
                    }
                }
            }

            if (newLhss.Count != 0)
            {
                newcmd.Add(new AssignCmd(Token.NoToken, newLhss, newRhss));
            }

            if (varsToHavoc.Count != 0)
            {
                var ieseq = new List <IdentifierExpr>();
                varsToHavoc.Iter(v => ieseq.Add(Expr.Ident(v)));
                newcmd.Add(new HavocCmd(Token.NoToken, ieseq));
            }

            return(newcmd);
        }
示例#17
0
        /* looks at the function used in the NAryExpr to determine the type: LOAD8, LOAD16,...,STORE64 */
        public static SlashVerifyCmdType getSlashVerifyCmdType(Cmd c)
        {
            Func <Expr, string, bool> RhsMatch = delegate(Expr x, String s)
            {
                return(x is NAryExpr && ((NAryExpr)x).Fun.FunctionName.Equals(s));
            };

            if (c is AssignCmd)
            {
                AssignCmd ac = c as AssignCmd;

                Utils.Assert(ac.Lhss.Count == 1 && ac.Rhss.Count == 1, "getSlashVerifyCmdType not handling parallel assignCmds");
                AssignLhs lhs = ac.Lhss[0];
                Expr      rhs = ac.Rhss[0];

                if (lhs.Type.IsMap && RhsMatch(rhs, "STORE_LE_8"))
                {
                    return(SlashVerifyCmdType.Store8);
                }
                else if (lhs.Type.IsMap && RhsMatch(rhs, "STORE_LE_16"))
                {
                    return(SlashVerifyCmdType.Store16);
                }
                else if (lhs.Type.IsMap && RhsMatch(rhs, "STORE_LE_32"))
                {
                    return(SlashVerifyCmdType.Store32);
                }
                else if (lhs.Type.IsMap && RhsMatch(rhs, "STORE_LE_64"))
                {
                    return(SlashVerifyCmdType.Store64);
                }
                else if (lhs.Type.IsMap && RhsMatch(rhs, "REP_STOSB"))
                {
                    return(SlashVerifyCmdType.RepStosB);
                }
                else if (lhs.Type.IsBv && lhs.DeepAssignedIdentifier.Name.Equals("RSP"))
                {
                    return(SlashVerifyCmdType.SetRSP);
                }
            }
            else if (c is AssertCmd)
            {
                AssertCmd ac = c as AssertCmd;

                //extract instruction type
                string attribute_cmdtype   = QKeyValue.FindStringAttribute(ac.Attributes, "SlashVerifyCommandType");
                string attribute_jmptarget = QKeyValue.FindStringAttribute(ac.Attributes, "SlashVerifyJmpTarget");

                if (attribute_cmdtype != null &&
                    attribute_cmdtype.Equals("ret"))
                {
                    return(SlashVerifyCmdType.Ret);
                }
                else if (attribute_cmdtype != null &&
                         attribute_cmdtype.Equals("call"))
                {
                    return(SlashVerifyCmdType.Call);
                }
                else if (attribute_cmdtype != null && attribute_jmptarget != null &&
                         attribute_cmdtype.Equals("remotejmp"))
                {
                    return(SlashVerifyCmdType.RemoteJmp);
                }
                else if (attribute_cmdtype != null && attribute_jmptarget != null &&
                         attribute_cmdtype.Equals("indirectjmp") && attribute_jmptarget.Equals("remote"))
                {
                    return(SlashVerifyCmdType.RemoteIndirectJmp);
                }
            }

            return(SlashVerifyCmdType.None);
        }