/// <summary> /// Inclusion check for two PointsToAndWriteEffects /// </summary> /// <param name="ptgWe"></param> public override bool Includes(PointsToState cState2) { bool includes = base.Includes(cState2); ConsistencyState pE = (ConsistencyState)cState2; includes = includes && IncludesConsistency(pE.consistency); return(includes); }
/// <summary> /// Join two PointsToAndWriteEffects /// </summary> /// <param name="ptgWe"></param> public override void Join(PointsToState ptg) { base.Join(ptg); if (ptg != null) { ConsistencyState ptgE = (ConsistencyState)ptg; if (consistency != ptgE.consistency) { JoinConsistencyNodes(ptgE.consistency); } //if (exposedNodes != ptgE.exposedNodes) // exposedNodes.AddRange(ptgE.exposedNodes); } }
// Get the least elements representing the bottom for the lattice of m //public static Reentrancy BottomFor(Method m) //{ // return new Reentrancy(m); //} #endregion protected override void BeforeBindCallWithCallee(PointsToState callerPTS, PointsToState calleePTS, Variable receiver, ExpressionList arguments, Variable vr, Label lb, InterProcMapping ipm) { base.BeforeBindCallWithCallee(callerPTS, calleePTS, receiver, arguments, vr, lb, ipm); Reentrancy reentrancyCalleeState = (Reentrancy)calleePTS; Receivers potentialReceivers = Receivers.Empty; // ** FOR REENTRANCY ANALYSIS if (receiver != null) { Nodes values = pointsToGraph.GetValuesIfEmptyLoadNode(receiver, lb); potentialReceivers.AddNodes(values); } bool isReentrant = false; // Check Exposure por every parameters if (!IsMethodToIgnoreForReentrancy(reentrancyCalleeState.Method)) { //isReentrant = ReentrancyAnalysisForAnalyzableCalls(reentrancyCalleeState.Method, reentrancyCalleeState, lb, // potentialReceivers, ipm); isReentrant = false; CheckExposureForCall(calleePTS, receiver, arguments, lb, isReentrant); } }
/// <summary> /// Inclusion check for two PointsToAndWriteEffects /// </summary> /// <param name="ptgWe"></param> public override bool Includes(PointsToState cState2) { bool includes = base.Includes(cState2); ConsistencyState pE = (ConsistencyState)cState2; includes = includes && IncludesConsistency(pE.consistency); return includes; }
public override void ApplyAnalyzableCall(Variable vr, Method callee, Variable receiver, ExpressionList arguments, PointsToState calleecState, Label lb, out InterProcMapping ipm) { Nodes receiverValues = Nodes.Empty; bool IsReceiverConsistent = false; if (receiver != null) { receiverValues = Values(receiver); IsReceiverConsistent = IsExposable(receiver); } base.ApplyAnalyzableCall(vr, callee, receiver, arguments, calleecState, lb, out ipm); if (receiver == null) { return; } BeforeUpdateConsystency(vr, callee, receiver, arguments, calleecState, lb, ipm); ConsistencyForCalls(callee, lb, receiverValues, IsReceiverConsistent, receiver, arguments); AfterUpdateConsystency(vr, callee, receiver, arguments, calleecState, lb, ipm); }
/// <summary> /// Join two PointsToAndWriteEffects /// </summary> /// <param name="ptgWe"></param> public virtual void Join(PointsToState ptgWe) { if (ptgWe != null) { if (pointsToGraph != ptgWe.pointsToGraph) pointsToGraph.Join(ptgWe.pointsToGraph); //if (callToNonAnalyzableMethods != ptgWe.callToNonAnalyzableMethods) // joinCalledMethod(callToNonAnalyzableMethods, ptgWe.callToNonAnalyzableMethods); //if (exceptions != ptgWe.exceptions) // exceptions.AddRange(ptgWe.exceptions); currentException = joinExceptions(currentException, ptgWe.currentException); if (methodAssumptions != ptgWe.methodAssumptions) methodAssumptions.AddRange(ptgWe.methodAssumptions); isDefault = isDefault && ptgWe.isDefault; } }
public void SetSummaryForMethod(Method m, PointsToState cState) { //String mName = m.GetFullUnmangledNameWithTypeParameters(); //pointsToWEMap[mName] = cState; if(m.FullName.Contains("Where")) { } pointsToWEMap[m] = cState; }
/// <summary> /// We record the method entry /// </summary> /// <param name="method"></param> /// <param name="parameters"></param> /// <param name="stat"></param> /// <param name="arg"></param> /// <returns></returns> /// protected virtual PointsToState EnlargeState(PointsToState initial, PointsToState enclosing) { PointsToState cState = initial; return cState; }
/// <summary> /// Check whether dataflow analysis changes or not /// </summary> /// <param name="m"></param> /// <param name="newResult"></param> /// <returns></returns> protected override bool AnalysisResultsChanges(Method m, PointsToState newResult) { bool res = base.AnalysisResultsChanges(m,newResult); return res; }
/// <summary> /// Inclusion check for two PointsToAndWriteEffects /// </summary> /// <param name="ptgWe"></param> public override bool Includes(PointsToState pts) { PointsToAndWriteEffects ptwe2 = (PointsToAndWriteEffects)pts; bool includes = base.Includes(ptwe2); includes = includes && this.WriteEffects.Includes(ptwe2.WriteEffects); includes = includes && this.ReadEffects.Includes(ptwe2.ReadEffects); return includes; }
protected override bool HasToVisit(PointsToState state) { // If there are too many calls to non analyzable methods // starts to ignore the statements PointsToAndWriteEffects ptwe = (PointsToAndWriteEffects)state; WeakPurityAndWriteEffectsAnalysis wpea = (WeakPurityAndWriteEffectsAnalysis) this.pointsToStateAnalysys; bool res = (!pointsToStateAnalysys.BoogieMode ||ptwe.CallsToNonAnalyzable.Count < wpea.maxCallToNonAnalyzable); return res; }
/// <summary> /// Join two PointsToAndWriteEffects /// </summary> /// <param name="ptgWe"></param> public override void Join(PointsToState pts) { PointsToAndWriteEffects ptgWe = (PointsToAndWriteEffects)pts; if (ptgWe != null) { base.Join(ptgWe); if (writeEffects != ptgWe.writeEffects) writeEffects.Join(ptgWe.writeEffects); if (allWriteEffects != ptgWe.allWriteEffects) allWriteEffects.Join(ptgWe.allWriteEffects); if (readEffects != ptgWe.readEffects) readEffects.Join(ptgWe.readEffects); if (allReadEffects != ptgWe.allReadEffects) allReadEffects.Join(ptgWe.allReadEffects); if (callToNonAnalyzableMethods != ptgWe.callToNonAnalyzableMethods) joinCalledMethod(callToNonAnalyzableMethods, ptgWe.callToNonAnalyzableMethods); } }
public PointsToAndWriteEffects(PointsToState ptWE) : base(ptWE) { this.writeEffects = new AbstractEffects(); this.allWriteEffects = new AbstractEffects(); this.readEffects = new AbstractEffects(); this.allReadEffects = new AbstractEffects(); this.callToNonAnalyzableMethods = new Dictionary<Label, Set<Method>>(); //if(ptWE.nonNullState!=null) // nonNullState = new NonNullState((NonNullState)ptWE.nonNullState); }
protected virtual void BeforeUpdateConsystency(Variable vr, Method callee, Variable receiver, ExpressionList arguments, PointsToState calleecState, Label lb, InterProcMapping ipm) { }
public override void ApplyAnalyzableCall(Variable vr, Method callee, Variable receiver, ExpressionList arguments, PointsToState calleecState, Label lb, out InterProcMapping ipm) { Nodes receiverValues = Nodes.Empty; bool IsReceiverConsistent = false; if (receiver != null) { receiverValues = Values(receiver); IsReceiverConsistent = IsExposable(receiver); } base.ApplyAnalyzableCall(vr, callee, receiver, arguments, calleecState, lb, out ipm); if(receiver==null) return; BeforeUpdateConsystency(vr, callee, receiver, arguments, calleecState, lb,ipm); ConsistencyForCalls(callee, lb, receiverValues, IsReceiverConsistent, receiver,arguments); AfterUpdateConsystency(vr, callee, receiver, arguments, calleecState, lb,ipm); }
private bool TryToSolveVirtualCall(PointsToState callercState, Variable receiver, Method callee, bool isVirtualCall, ref bool solveInstance, out Set<Method> callees) { callees = Set<Method>.Empty; bool isAnalyzable = false; if (isVirtualCall) { Nodes receivers = callercState.PointsToGraph.Values(receiver); if (PointsToAnalysis.debug) { Console.WriteLine("Receivers virtual call:" + receivers); if (receivers.Count > 1) { Console.WriteLine("More than one potential receiver"); } } if (receivers.Count > 0) { bool allInside = true; foreach (IPTAnalysisNode r in receivers) { allInside = allInside && (!CciHelper.IsInterface(r.Type) && r.IsInside); if (!allInside) break; // Try to get the method from an instance of the passed type callees.Add(PointsToAnalysis.solveInstance(r.Type, callee, out solveInstance)); } if (allInside) { if (PointsToAnalysis.debug) { Console.WriteLine("Receivers Var Type: {0} Nodes: {1} {2} {3}", receiver.Type, receivers, isVirtualCall, callee.IsVirtual); } isAnalyzable = true; } } } return isAnalyzable; }
private bool TryToSolveDelegate(PointsToState callercState, Variable receiver, Method callee, bool isExtern, Label lb, out Set<Method> callees) { callees = Set<Method>.Empty; bool isAnalyzable = false; if (isExtern) { Nodes receivers = Nodes.Empty; if (receiver != null) receivers.AddRange(callercState.PointsToGraph.GetValuesIfEmptyLoadNode(receiver, lb)); if (PointsToAnalysis.debug) { Console.WriteLine("Receivers virtual call:" + receivers); if (receivers.Count > 1) { Console.WriteLine("More than one potential receiver"); } } if (receivers.Count > 0) { bool allInside = true; foreach (IPTAnalysisNode r in receivers) { allInside = allInside && (r.IsMethodDelegate); if (!allInside) break; MethodDelegateNode mn = (MethodDelegateNode)r; callees.Add(mn.Method); } if (allInside) { isAnalyzable = true; } } } return isAnalyzable; }
/* This was related with the old way of dealing with non analyzable calls private void RegisterModifiesInReachableObjects(Variable v, Label lb, bool confined) { // Use Filters for !owned!!!!!! Nodes reachables = PointsToGraph.NodesForwardReachableFromVariable(v, confined); foreach (IPTAnalysisNode n in reachables) { //if (n is LValueNode || n.IsGlobal) if(n.IsObjectAbstraction) { RegisterWriteEffect(n, PTGraph.allFields, lb,false); } } } private void RegisterReadInReachableObjects(Variable v, Label lb, bool confined) { // Use Filters for !owned!!!!!! Nodes reachables = PointsToGraph.NodesForwardReachableFromVariable(v,confined); foreach (IPTAnalysisNode n in reachables) { // Add Filters!!!!!! //if (n is LValueNode || n.IsGlobal) if (n.IsObjectAbstraction) { RegisterReadEffect(n, PTGraph.allFields, lb); } } } */ /// <summary> /// Apply the inter-procedural analysis, binding information from caller and callee /// </summary> /// <param name="vr"></param> /// <param name="callee"></param> /// <param name="receiver"></param> /// <param name="arguments"></param> /// <param name="calleePTWE"></param> /// <param name="lb"></param> /// public override void ApplyAnalyzableCall(Variable vr, Method callee, Variable receiver, ExpressionList arguments, PointsToState calleecState, Label lb, out InterProcMapping ipm) { if (this.method.FullName.Contains("Count")) { if (callee.Name.Name.Contains("Reverse")) { } if (callee.Name.Name.Contains("Dispose")) { } } if (callee.Name.Name.Contains("MoveNext2")) { } base.ApplyAnalyzableCall(vr, callee, receiver, arguments, calleecState, lb, out ipm); PointsToAndWriteEffects calleePTWE = (PointsToAndWriteEffects)calleecState; // Join the set of non-analyzable calls joinCalledMethod(callToNonAnalyzableMethods, calleePTWE.callToNonAnalyzableMethods); // For each write effect in the calee foreach (AField af in calleePTWE.writeEffects) { // Get the related caller's nodes foreach (IPTAnalysisNode n in ipm.RelatedExtended(af.Src)) { if (IsVisibleEffect(n, af.Field)) { writeEffects.AddEffect(n, af.Field, lb); } allWriteEffects.AddEffect(n, af.Field, lb); } } BindCallerReadEffects(calleePTWE, lb, ipm); }
/// <summary> /// Check whether dataflow analysis changes or not /// </summary> /// <param name="m"></param> /// <param name="newResult"></param> /// <returns></returns> protected virtual bool AnalysisResultsChanges(Method m, PointsToState newResult) { bool res = false; if (HasSummary(m)) { PointsToState oldResult = GetSummaryForMethod(m); //res = !oldResult.Equals(newResult); res = !oldResult.Includes(newResult); if (verbose && res) { Console.Out.WriteLine("Method {0} has changed:", m.FullName); Console.Out.WriteLine("DIFERENCE old vs new"); oldResult.DumpDifference(newResult); Console.Out.WriteLine("DIFERENCE new vs old"); newResult.DumpDifference(oldResult); //if (oldResult.writeEffects.Equals(newResult.writeEffects)) //{ // Console.Out.WriteLine(oldResult.writeEffects); // Console.Out.WriteLine(newResult.writeEffects); // Console.Out.WriteLine("****"); //} } } else { res = newResult != null; } return res; }
/// <summary> /// Creates a summary from scratch using annotations /// </summary> /// <param name="vr"></param> /// <param name="callee"></param> /// <param name="receiver"></param> /// <param name="arguments"></param> /// <param name="lb"></param> /// <returns></returns> public virtual PointsToState CreateSummaryForFakeCallee(Variable vr, Method callee, Variable receiver, ExpressionList arguments, Label lb) { PointsToState calleeState = new PointsToState(callee, this.pta); // Create a fake PTG for the calle using annotations... PTGraph calleFakePTG = PTGraph.PTGraphFromAnnotations(callee); // calleFakePTG.GenerateDotGraph(callee.FullName + ".dot"); calleeState.pointsToGraph = calleFakePTG; return calleeState; }
// Copy Constructor public PointsToState(PointsToState cState) { this.pta = cState.pta; pointsToGraph = new PTGraph(cState.pointsToGraph); // callToNonAnalyzableMethods = new Dictionary<Label, Set<Method>>(cState.callToNonAnalyzableMethods); method = cState.method; methodLabel = cState.methodLabel; //exceptions = cState.exceptions; currentException = cState.currentException; methodAssumptions = cState.methodAssumptions; isDefault = cState.isDefault; }
/// <summary> /// Apply the inter-procedural analysis, binding information from caller and callee /// </summary> /// <param name="vr"></param> /// <param name="callee"></param> /// <param name="receiver"></param> /// <param name="arguments"></param> /// <param name="calleecState"></param> /// <param name="lb"></param> public virtual void ApplyAnalyzableCall(Variable vr, Method callee, Variable receiver, ExpressionList arguments, PointsToState calleecState, Label lb, out InterProcMapping ipm) { // Apply the binding between the pointsToGraph of the caller and the callee // Returns also the mapping used during the parameter-arguments nodes binding if (PointsToAnalysis.debug) { Console.Out.WriteLine("before call to {0}", callee.Name); //pointsToGraph.Dump(); this.Dump(); } if (this.Method.Name.Name.StartsWith("UsingFoo")) { } ipm = InterProcMapping.ComputeInterProgMapping(this.pointsToGraph, calleecState.pointsToGraph, receiver, arguments, vr, lb); BeforeBindCallWithCallee(this, calleecState, receiver, arguments, vr, lb, ipm); PTGraph interProcPTG = ipm.ComputeInterProgGraph(this.pointsToGraph, calleecState.pointsToGraph, receiver, arguments, vr, lb); pointsToGraph = interProcPTG; AfterBindCallWithCallee(this, calleecState, receiver, arguments, vr, lb, ipm); if (PointsToAnalysis.debug) { Console.Out.WriteLine("after call to {0}", callee.Name); Console.Out.WriteLine(ipm); Console.Out.WriteLine("Callee:"); calleecState.Dump(); Console.Out.WriteLine("Caller:"); this.Dump(); } // Update the set of write effects considering the writeffects of the callee // in nodes that will stay in the caller Set<LNode> removedLoadNodes = ipm.removedLoadNodes; // Join the set of non-analyzable calls //joinCalledMethod(callToNonAnalyzableMethods, calleecState.callToNonAnalyzableMethods); }
/// <summary> /// Inlusion check for two PointsToAndWriEffects /// </summary> /// <param name="ptgWe"></param> public virtual bool Includes(PointsToState cState2) { bool includes = pointsToGraph.AtMost(cState2.pointsToGraph, this.pointsToGraph); //foreach(Label lb in cState2.callToNonAnalyzableMethods.Keys) //{ // includes = includes && this.callToNonAnalyzableMethods.ContainsKey(lb) // && this.callToNonAnalyzableMethods[lb].Includes(cState2.callToNonAnalyzableMethods[lb]); //} return includes; }
protected virtual void AfterBindCallWithCallee(PointsToState callerPTS, PointsToState calleePTS, Variable receiver, ExpressionList arguments, Variable vr, Label lb, InterProcMapping ipm) { }
// Get the least elements representing the bottom for the lattice of m //public static Reentrancy BottomFor(Method m) //{ // return new Reentrancy(m); //} #endregion protected override void BeforeBindCallWithCallee(PointsToState callerPTS, PointsToState calleePTS, Variable receiver, ExpressionList arguments, Variable vr, Label lb, InterProcMapping ipm) { base.BeforeBindCallWithCallee(callerPTS, calleePTS, receiver, arguments, vr, lb, ipm); Reentrancy reentrancyCalleeState = (Reentrancy)calleePTS; Receivers potentialReceivers = Receivers.Empty; // ** FOR REENTRANCY ANALYSIS if (receiver != null) { Nodes values = pointsToGraph.GetValuesIfEmptyLoadNode(receiver, lb); potentialReceivers.AddNodes(values); } bool isReentrant = false; // Check Exposure por every parameters if (!IsMethodToIgnoreForReentrancy(reentrancyCalleeState.Method)) { //isReentrant = ReentrancyAnalysisForAnalyzableCalls(reentrancyCalleeState.Method, reentrancyCalleeState, lb, // potentialReceivers, ipm); isReentrant = false; CheckExposureForCall(calleePTS, receiver, arguments, lb, isReentrant); } }
public virtual void DumpDifference(PointsToState pt2) { pointsToGraph.DumpDifference(pt2.pointsToGraph); }
protected virtual bool HasToVisit(PointsToState state) { bool res = true; return res; }
/// <summary> /// Determine if the callee method is analyzable /// or pure and gets or compute the callee dataflow information /// </summary> /// <param name="callercState"></param> /// <param name="receiver"></param> /// <param name="callee"></param> /// <param name="caller"></param> /// <param name="isVirtualCall"></param> /// <param name="lb"></param> /// <param name="calleecState"></param> /// <returns></returns> protected virtual bool TryAnalyzeCallee(PointsToState callercState, Variable receiver, Method callee, Method caller, bool isVirtualCall, Label lb, out Set<PointsToState> calleecStates) { calleecStates = new Set<PointsToState>(); if (caller.FullName.Contains("Except")) if (callee.Name.Name.Equals("Add")) { } // DIEGO-TODO: Check if is better to replace the calle by its template directly at the beggining bool isTemplate = false; bool solveInstance = false; isTemplate = callee.DeclaringType.IsGeneric && callee.Template == null; // verify whether the method is analyzed or not // That means, is not unsafe and the statements are available // This can be bounded to the compuation unit to reduce // analysis time, still being interprocedural bool isAnalyzable = false; // If it is assumed pure I don't analyzed it if ((!PureAsAnalyzable() && PointsToAndEffectsAnnotations.IsAssumedPureMethod(callee)) || ForcedByAnnotations(callee) ) { // We treat known pure as non-analyzable but we then rely on the // the provided annotations (pure, confined, stateindependend, fresh, etc.) isAnalyzable = false; } else { //if (callee.Name.Name.Contains("GetEnumerator") && caller.Name.Name.Contains("AddAll")) //{ // System.Diagnostics.Debugger.Break(); //} if (PointsToAnalysis.IsInterProceduralAnalysys) { Set<Method> callees = new Set<Method>(); ; isAnalyzable = PointsToAnalysis.IsAnalyzable(callee) && (!callee.IsVirtual || !isVirtualCall); if (isAnalyzable) callees.Add(callee); // Set<Method> potencialCalles = PotentialCallees(callercState, callee, receiver); // I removed virtual call resolution because it tries to analyze method (eg. Dictionary.Add) // which has calls that is not able to analyze, leading to not desired behaviour. if (PointsToAnalysis.tryToSolveCallsToInterfaces) { if (!isAnalyzable && callee.IsVirtual && !callee.IsExtern) isAnalyzable = TryToSolveVirtualCall(callercState, receiver, callee, isVirtualCall, ref solveInstance, out callees); } // Try to obtain the delegate that is contained in the node if (!isAnalyzable && callee.IsExtern) isAnalyzable = TryToSolveDelegate(callercState, receiver, callee, callee.IsExtern, lb, out callees); // isAnalyzable = isAnalyzable && wasAnalyzed; if (isAnalyzable) { AnalyzeAnalyzable(ref callee, caller, calleecStates, ref isAnalyzable, callees); } } else { isAnalyzable = false; } // If it's a virtual call and we analyze the callee, we add the // asumption about we use that method and not a subclass method if (isAnalyzable) { if ((isVirtualCall && callee.IsVirtual && solveInstance) || (isTemplate)) { callercState.methodAssumptions.Add(callee); // Console.WriteLine("Added {0} in method assumptions", callee.FullName); // calleecState.methodAssumptions.Add(callee); } } } return isAnalyzable; }
protected virtual void BeforeUpdateConsystency(Variable vr, Method callee, Variable receiver, ExpressionList arguments, PointsToState calleecState, Label lb, InterProcMapping ipm) { }
/// <summary> /// Join two PointsToAndWriteEffects /// </summary> /// <param name="ptgWe"></param> public override void Join(PointsToState ptg) { base.Join(ptg); if (ptg != null) { ConsistencyState ptgE = (ConsistencyState)ptg; if (consistency!= ptgE.consistency) JoinConsistencyNodes(ptgE.consistency); //if (exposedNodes != ptgE.exposedNodes) // exposedNodes.AddRange(ptgE.exposedNodes); } }