public override Expr VisitNAryExpr(NAryExpr node)
 {
     if (isBvOp(node.Fun.FunctionName))
     {
         if (!node.Fun.FunctionName.Contains("bv"))
         {
             int length;
             if (int.TryParse(node.Fun.FunctionName.Split('.')[1].Split('i')[1], out length))
             {
                 if (length > 1)
                 {
                     Console.WriteLine("Catch a bv op at " + node.ToString());
                     maybeImprecise = true;
                 }
             }
             else
             {
                 Console.WriteLine("Cannot parse int: " + node.Fun.FunctionName.Split('.')[1].Split('i')[1]);
             }
         }
     }
     if (isLoadStore(node.Fun.FunctionName))
     {
         int width;
         if (node.Fun.FunctionName.Contains("ref"))
         {
             width = -2;
         }
         else if (node.Fun.FunctionName.Contains("float"))
         {
             width = 32;
         }
         else
         {
             var type   = node.Fun.FunctionName.Contains("bytes")? node.Fun.FunctionName.Split('.')[2] : node.Fun.FunctionName.Split('.')[1];
             var prefix = type.StartsWith("i") ? "i" : "bv";
             if (int.TryParse(type.Substring(prefix.Length), out width))
             {
                 // pass
             }
             else
             {
                 Console.WriteLine("Cannot parse int: " + node.Fun.FunctionName.Split('.')[1].Split('i')[1]);
                 return(base.VisitNAryExpr(node));
             }
         }
         var map  = node.Args.Where(arg => mapSizes.Keys.Contains(arg.ToString())).First().ToString();
         var size = mapSizes[map];
         if (size == 0)
         {
             mapSizes[map] = width;
         }
         else
         {
             if (size != width)
             {
                 mapSizes[map] = -1;
             }
         }
     }
     return(base.VisitNAryExpr(node));
 }
Exemple #2
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            if (node.Fun is UnaryOperator)
            {
                var op = (UnaryOperator)node.Fun;
                if (op.Op == UnaryOperator.Opcode.Not)
                {
                    if (isLiteral(node.Args[0]))
                    {
                        add(node.Args[0]);
                    }
                }
                else if (op.Op == UnaryOperator.Opcode.Neg)
                {
                    throw new Exception(string.Format("We should not see any Neg expression during the atom collection: {0}", node.ToString()));
                }
            }
            else if (node.Fun is BinaryOperator)
            {
                var op = (BinaryOperator)node.Fun;
                switch (op.Op)
                {
                case BinaryOperator.Opcode.And:
                case BinaryOperator.Opcode.Or:
                case BinaryOperator.Opcode.Imp:
                case BinaryOperator.Opcode.Iff:
                    var left  = node.Args[0];
                    var right = node.Args[1];
                    if (isLiteral(left))
                    {
                        add(left);
                    }
                    if (isLiteral(right))
                    {
                        add(right);
                    }
                    break;

                default:
                    break;
                }
            }
            else if (node.Fun is MapSelect || node.Fun is MapStore)
            {
                return(base.VisitNAryExpr(node));
            }
            else
            {
                throw new Exception(string.Format("This expression is not supported yet during the atom collection: {0}", node.ToString()));
            }
            return(base.VisitNAryExpr(node));
        }
Exemple #3
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            if (node.Fun.FunctionName == "==" || node.Fun.FunctionName == "!=")
            {
                if (node.Args.Any(arg => arg is LiteralExpr && !(arg as LiteralExpr).isBool))
                {
                    int noLit = 0;
                    int lit   = 1;
                    if (node.Args[noLit] is LiteralExpr)
                    {
                        noLit = 1;
                        lit   = 0;
                    }
                    if (node.Args[noLit] is LiteralExpr)
                    {
                        return(node);
                    }
                    if (!getType(node.Args[noLit].ToString()).ToString().Contains("bv"))
                    {
                        return(node);
                    }
                    node.Args[lit] = TTUtil.intLit2bvLit(node.Args[lit],
                                                         getWidthFromType(getType(node.Args[noLit].ToString()).ToString()));
                    VisitExpr(node.Args[noLit]);
                    return(node);
                }
            }
            else if (node.Fun.FunctionName.Contains("$"))
            {
                bool bv = false;
                if (node.Fun.FunctionName.Contains("$bv2int"))
                {
                    for (int i = 0; i < node.Args.Count; ++i)
                    {
                        node.Args[i] = VisitExpr(node.Args[i]);
                    }
                    return(node);
                }
                bool isLoadStore = node.Fun.FunctionName.Contains("$load") || node.Fun.FunctionName.Contains("$store");
                if (isLoadStore)
                {
                    bv = getType(node.Args[0].ToString()).AsMap.Result.IsBv;
                }
                else
                {
                    bv = getType(node.ToString()).ToString().Contains("bv");
                }

                if (!bv && !isLoadStore)
                {
                    return(node);
                }

                var funcName  = node.Fun.FunctionName.Split('(')[0];
                var inputType = funcName.Split('.')[1];

                for (int i = 0; i < node.Args.Count; ++i)
                {
                    var arg = node.Args[i];
                    if (!(isLoadStore && i == 1) && bv && TTUtil.isNumber(arg))
                    {
                        int size = getWidthFromType(inputType);
                        node.Args[i] = TTUtil.intLit2bvLit(arg, size);
                        continue;
                    }

                    if (isLoadStore && i == 1 && !(arg is LiteralExpr))
                    {
                        if (procTypes.Keys.Contains(arg.ToString()) && getType(arg.ToString()).IsBv)
                        {
                            node.Args[i] = new NAryExpr(Token.NoToken,
                                                        new FunctionCall(prog.TopLevelDeclarations.OfType <Function>().Where(f => f.Name.StartsWith("$bv2int")).FirstOrDefault()),
                                                        new List <Expr>()
                            {
                                arg
                            });
                        }
                    }

                    if (!bv && isLoadStore)
                    {
                        node.Args[i] = VisitExpr(node.Args[i]);
                    }
                }

                if (!bv)
                {
                    return(node);
                }

                if (node.Fun.FunctionName.Equals("$i2p.i64.ref") || node.Fun.FunctionName.Equals("$i2p.i32.ref") || node.Fun.FunctionName.Equals("$p2i.ref.i64") || node.Fun.FunctionName.Equals("$bitcast.ref.ref"))
                {
                    return(VisitExpr(node.Args[0]));
                }
                if (node.Fun.FunctionName.Equals("$p2i.ref.i32"))
                {
                    if (refWidth == 64)
                    {
                        var newArgs = new List <Expr>()
                        {
                            VisitExpr(node.Args[0])
                        };
                        return(new NAryExpr(Token.NoToken, new FunctionCall(prog.TopLevelDeclarations.OfType <Function>().Where(func => func.Name.Equals("$trunc.bv64.bv32")).FirstOrDefault()), newArgs));
                    }
                    else
                    {
                        return(VisitExpr(node.Args[0]));
                    }
                }
                // build a bv expression
                var bvFuncName = string.Join(".", funcName.Split('.').Select(elem => !elem.Contains("$") && !elem.Contains("bool")? "bv" + elem.Substring("i".Length) : elem));
                if (!isLoadStore && node.Fun.FunctionName.Split('.').Any(s => s.Contains("ef")))
                {
                    bvFuncName = string.Join(".", bvFuncName.Split('.').Select(s => s.Contains("ef")? "bv" + refWidth : s));
                }
                else if (node.Fun.FunctionName.Contains("$load") || node.Fun.FunctionName.Contains("$store"))
                {
                    var mapSize = getType(node.Args[0].ToString()).AsMap.Result.BvBits;
                    int opSize  = getWidthFromType(inputType);
                    //if (inputType.Equals("ref"))
                    //    opSize = 64;
                    //else if (int.TryParse(inputType.Substring("i".Length), out opSize))
                    //{
                    //    //pass
                    //}
                    //else
                    //{
                    //    Console.Write("Having trouble parsing numbers in expr: " + node.ToString());
                    //}
                    if (mapSize != opSize)
                    {
                        bvFuncName = bvFuncName.Split('.')[0] + ".bytes." + "bv" + opSize;
                    }
                    else
                    {
                        bvFuncName = bvFuncName.Split('.')[0] + ".bv" + opSize;
                    }
                }
                node = new NAryExpr(Token.NoToken, new FunctionCall(prog.TopLevelDeclarations.OfType <Function>().Where(func => func.Name.Equals(bvFuncName)).FirstOrDefault()), node.Args);

                for (int i = 0; i < node.Args.Count; ++i)
                {
                    node.Args[i] = VisitExpr(node.Args[i]);
                }
                return(node);
            }

            return(base.VisitNAryExpr(node));
        }