// // ValueAnalysis.cs // // Authors: // Alexander Chebaturkin (chebaturkin@gmail.com) // // Copyright (C) 2012 Alexander Chebaturkin // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using Mono.CodeContracts.Static.AST.Visitors; using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Expressions; using Mono.CodeContracts.Static.ControlFlow; using Mono.CodeContracts.Static.DataFlowAnalysis; using Mono.CodeContracts.Static.DataStructures; using Mono.CodeContracts.Static.Lattices; namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis { class ValueAnalysis : IAnalysis, IILVisitor, ExprDomain>, EdgeData> where SymbolicValue : IEquatable where Context : IValueContextProvider where EdgeData : IImmutableMap> { private readonly ExpressionAnalysisFacade parent; public ValueAnalysis (ExpressionAnalysisFacade parent) { this.parent = parent; } #region Implementation of IAnalysis.Domain,IILVisitor.Domain,ExpressionAnalysis.Domain>,EdgeData> public ExprDomain EdgeConversion (APC @from, APC to, bool isJoinPoint, EdgeData sourceTargetMap, ExprDomain originalState) { if (sourceTargetMap == null) return originalState; if (DebugOptions.Debug) { Console.WriteLine ("====Expression analysis Parallel assign===="); DumpMap (sourceTargetMap); DumpExpressions ("original expressions", originalState); } ExprDomain result = originalState.Empty (); ExprDomain domain = originalState.Empty (); foreach (SymbolicValue sv in originalState.Keys) { Expr expression = originalState [sv].Value.Substitute (sourceTargetMap); if (expression != null) domain = domain.Add (sv, expression); } foreach (SymbolicValue sv in sourceTargetMap.Keys) { FlatDomain> expressionDomain = domain [sv]; if (expressionDomain.IsNormal()) { Expr expression = expressionDomain.Value; foreach (SymbolicValue sub in sourceTargetMap [sv].AsEnumerable ()) result = result.Add (sub, expression); } } if (DebugOptions.Debug) { DumpExpressions ("new expressions", result); } return result; } public IILVisitor, ExprDomain> GetVisitor () { return new AnalysisDecoder (); } public ExprDomain Join (Pair edge, ExprDomain newstate, ExprDomain prevstate, out bool weaker, bool widen) { return prevstate.Join (newstate, widen, out weaker); } public ExprDomain ImmutableVersion (ExprDomain arg) { return arg; } public ExprDomain MutableVersion (ExprDomain arg) { return arg; } public bool IsBottom (APC pc, ExprDomain state) { return state.IsBottom; } public Predicate SaveFixPointInfo (IFixPointInfo> fixPointInfo) { this.parent.SaveFixPointInfo (fixPointInfo); return pc => true; } public void Dump (Pair, TextWriter> pair) { pair.Key.Dump (pair.Value); } private void DumpMap (IImmutableMap> sourceTargetMap) { Console.WriteLine ("Source-Target assignment"); foreach (SymbolicValue key in sourceTargetMap.Keys) { foreach (SymbolicValue value in sourceTargetMap [key].AsEnumerable ()) Console.Write ("{0} ", value); Console.WriteLine (" := {0}", key); } } private void DumpExpressions (string header, ExprDomain state) { Console.WriteLine ("--- {0} ---", header); foreach (SymbolicValue index in state.Keys) { FlatDomain> domain = state [index]; if (domain.IsNormal()) Console.WriteLine ("{0} -> {1}", index, domain.Value); else if (domain.IsTop) Console.WriteLine ("{0} -> (Top)", index); else if (domain.IsBottom) Console.WriteLine ("{0} -> (Bot)", index); } } #endregion } }