private bool TryComputeNAryExprs(IdentifierExpr id) { var toRemove = new HashSet <Expr>(); foreach (var expr in this.ExpressionMap[id].Keys.ToList()) { if (!(expr is NAryExpr)) { continue; } int ixs = 0; if (((expr as NAryExpr).Args[0] is IdentifierExpr) && ((expr as NAryExpr).Args[0] as IdentifierExpr).Name.StartsWith("$M.")) { toRemove.Add(expr); continue; } if (PointerArithmeticAnalyser.ShouldSkipFromAnalysis(expr as NAryExpr)) { toRemove.Add(expr); continue; } if (PointerArithmeticAnalyser.IsArithmeticExpression(expr as NAryExpr)) { toRemove.Add(expr); continue; } Expr p = (expr as NAryExpr).Args[0]; Expr i = (expr as NAryExpr).Args[1]; Expr s = (expr as NAryExpr).Args[2]; if (!(i is LiteralExpr && s is LiteralExpr)) { toRemove.Add(expr); continue; } ixs = (i as LiteralExpr).asBigNum.ToInt * (s as LiteralExpr).asBigNum.ToInt; this.ExpressionMap[id].Add(p, this.ExpressionMap[id][expr] + ixs); toRemove.Add(expr); } foreach (var expr in toRemove) { this.ExpressionMap[id].Remove(expr); } if (this.ExpressionMap[id].Any(val => val.Key is NAryExpr)) { return(false); } return(true); }
/// <summary> /// Performs pointer analysis to identify and create unique locks. /// </summary> private void IdentifyAndCreateUniqueLocks() { var initialImpl = this.AC.GetImplementation(DeviceDriver.InitEntryPoint); foreach (var block in initialImpl.Blocks) { for (int idx = 0; idx < block.Cmds.Count; idx++) { if (!(block.Cmds[idx] is CallCmd)) { continue; } if (!(block.Cmds[idx] as CallCmd).callee.Contains("mutex_init") && !(block.Cmds[idx] as CallCmd).callee.Contains("spin_lock_init")) { continue; } Expr lockExpr = PointerArithmeticAnalyser.ComputeRootPointer(initialImpl, block.Label, (block.Cmds[idx] as CallCmd).Ins[0]); Lock newLock = new Lock(new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "lock$" + this.AC.Locks.Count, Microsoft.Boogie.Type.Int), true), lockExpr); newLock.Id.AddAttribute("lock", new object[] { }); this.AC.TopLevelDeclarations.Add(newLock.Id); this.AC.Locks.Add(newLock); } } foreach (var l in AnalysisContext.GlobalLocks) { if (!this.AC.Locks.Any(val => val.Id.Name.Equals(l.Id.Name))) { this.AC.TopLevelDeclarations.Add(l.Id); this.AC.Locks.Add(l); } } }
private void ComputeMapsForIdentifierExpr(IdentifierExpr id) { if (PointerArithmeticAnalyser.Cache[this.EP][this.Implementation].ContainsKey(id)) { return; } if (!this.ExpressionMap.ContainsKey(id)) { this.ExpressionMap.Add(id, new Dictionary <Expr, int>()); } if (!this.AssignmentMap.ContainsKey(id)) { this.AssignmentMap.Add(id, new HashSet <Expr>()); } if (!this.CallMap.ContainsKey(id)) { this.CallMap.Add(id, new HashSet <CallCmd>()); } foreach (var block in this.Implementation.Blocks) { for (int i = block.Cmds.Count - 1; i >= 0; i--) { if (block.Cmds[i] is AssignCmd) { var assign = block.Cmds[i] as AssignCmd; if (!assign.Lhss[0].DeepAssignedIdentifier.Name.Equals(id.Name)) { continue; } if (this.AssignmentMap[id].Contains(assign.Rhss[0])) { continue; } var expr = assign.Rhss[0]; PointerArithmeticAnalyser.TryPerformCast(ref expr); this.AssignmentMap[id].Add(expr); if (expr.ToString().StartsWith("$pa(")) { this.ExpressionMap[id].Add(expr, 0); } if (expr is IdentifierExpr && this.InParams.Any(val => val.Name.Equals((expr as IdentifierExpr).Name))) { this.ExpressionMap[id].Add(expr, 0); } if (expr is IdentifierExpr && this.AC.TopLevelDeclarations.OfType <Constant>(). Any(val => val.Name.Equals((expr as IdentifierExpr).Name))) { this.ExpressionMap[id].Add(expr, 0); } if (expr is LiteralExpr) { this.ExpressionMap[id].Add(expr, 0); } } else if (block.Cmds[i] is CallCmd) { var call = block.Cmds[i] as CallCmd; if (call.callee.Equals("$alloca")) { if (!call.Outs[0].Name.Equals(id.Name)) { continue; } this.CallMap[id].Add(call); } } } } }
/// <summary> /// Compute $pa(p, i, s) == p + i * s); /// </summary> /// <returns>The root pointer.</returns> /// <param name="impl">Implementation</param> /// <param name="label">Root block label</param> /// <param name="id">Identifier expression</param> public static Expr ComputeRootPointer(Implementation impl, string label, Expr id) { if (id is LiteralExpr) { return(id); } if (id is NAryExpr && (id as NAryExpr).Args.Count == 1 && (id as NAryExpr).Fun.FunctionName.Equals("-")) { return(id); } NAryExpr root = PointerArithmeticAnalyser.GetPointerArithmeticExpr(impl, id) as NAryExpr; if (root == null) { return(id); } Expr result = root; Expr resolution = result; int ixs = 0; var alreadyVisited = new HashSet <Tuple <string, Expr> >(); do { if (result is NAryExpr) { if (((result as NAryExpr).Args[0] is IdentifierExpr) && ((result as NAryExpr).Args[0] as IdentifierExpr).Name.StartsWith("$M.")) { return(id); } if (PointerArithmeticAnalyser.TryPerformCast(ref result)) { continue; } if (PointerArithmeticAnalyser.ShouldSkipFromAnalysis(result as NAryExpr)) { return(id); } if (alreadyVisited.Any(v => v.Item1.Equals(label) && v.Item2.Equals(result))) { return(id); } alreadyVisited.Add(new Tuple <string, Expr>(label, result)); if (PointerArithmeticAnalyser.IsArithmeticExpression(result as NAryExpr)) { return(id); } Expr p = (result as NAryExpr).Args[0]; Expr i = (result as NAryExpr).Args[1]; Expr s = (result as NAryExpr).Args[2]; if ((i is LiteralExpr) && (s is LiteralExpr)) { ixs += (i as LiteralExpr).asBigNum.ToInt * (s as LiteralExpr).asBigNum.ToInt; } else { return(id); } result = p; } else { resolution = PointerArithmeticAnalyser.GetPointerArithmeticExpr(impl, result); if (resolution != null) { result = resolution; } } }while (resolution != null); return(Expr.Add(result, new LiteralExpr(Token.NoToken, BigNum.FromInt(ixs)))); }