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)); }
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)); }
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)); }