Add contant progration for string within the Range Analysis. Modify the interproc analysis to progagate ranges (or string) to callees.

This commit is contained in:
Diego 2018-01-27 18:34:08 -08:00
Родитель 781847b959
Коммит 903ccf79ba
4 изменённых файлов: 162 добавлений и 70 удалений

Просмотреть файл

@ -187,7 +187,7 @@ namespace ScopeProgramAnalysis
nodeExit.Successors.Add(nodeEntry);
nodeEntry.Predecessors.Add(nodeExit);
var rangeAnalysis = new RangeAnalysis(cfg);
var rangeAnalysis = new RangeAnalysis(cfg, this.processToAnalyze.MoveNextMethod);
var ranges = rangeAnalysis.Analyze();
var exitRange = ranges[cfg.Exit.Id];

Просмотреть файл

@ -57,7 +57,8 @@ namespace ScopeProgramAnalysis
public IEnumerable<ProtectedRowNode> ProtectedNodes { get; set; }
public Instruction Instruction { get; internal set; }
}
public VariableRangeDomain VariableRanges { get; internal set; }
}
public struct InterProceduralReturnInfo
{
public InterProceduralReturnInfo(DependencyPTGDomain state)
@ -175,11 +176,15 @@ namespace ScopeProgramAnalysis
IDictionary<IVariable, IExpression> equalities = new Dictionary<IVariable, IExpression>();
calleeCFG.PropagateExpressions(equalities);
var rangesAnalysis = new RangeAnalysis(calleeCFG);
rangesAnalysis.Analyze();
// 2) Bind Parameters of the dependency analysis and run
var calleeDomain = BindCallerCallee(callInfo);
calleeDomain.PTG = calleePTG;
// 2) Bind Parameters of the dependency analysis
VariableRangeDomain boundVariablesRanges;
var calleeDomain = BindCallerCallee(callInfo, out boundVariablesRanges);
var rangesAnalysis = new RangeAnalysis(calleeCFG, callInfo.Callee, boundVariablesRanges);
// 4) Now we perform the analyses
rangesAnalysis.Analyze();
calleeDomain.PTG = calleePTG;
var dependencyAnalysis = new IteratorDependencyAnalysis(processToAnalyze, callInfo.Callee, calleeCFG, calleePTA, callInfo.ProtectedNodes, equalities, this, rangesAnalysis, calleeDomain, callInfo.ScopeData);
// If we already did the dataflow analysis for this method we recover the dataflow state
@ -212,7 +217,9 @@ namespace ScopeProgramAnalysis
// Should I need the PTG of caller and callee?
//var exitCalleePTG = calleePTA.Result[calleeCFG.Exit.Id].Output;
var exitCalleePTG = dependencyAnalysis.Result[calleeCFG.Exit.Id].Output.PTG;
var exitResult = BindCalleeCaller(callInfo, calleeCFG, dependencyAnalysis);
var exitResult = BindCalleeCaller(callInfo, calleeCFG, dependencyAnalysis, rangesAnalysis);
// Recover the frame of the original Ptg and bind ptg results
//PointsToGraph bindPtg = PTABindCaleeCalleer(callInfo.CallLHS, calleeCFG, calleePTA);
@ -227,33 +234,40 @@ namespace ScopeProgramAnalysis
//return new InterProceduralReturnInfo(exitResult, bindPtg);
}
private DependencyPTGDomain BindCallerCallee(InterProceduralCallInfo callInfo)
private DependencyPTGDomain BindCallerCallee(InterProceduralCallInfo callInfo, out VariableRangeDomain initializedRanges)
{
initializedRanges = new VariableRangeDomain();
var calleeDepDomain = new DependencyPTGDomain();
calleeDepDomain.Dependencies.IsTop = callInfo.CallerState.Dependencies.IsTop;
// Bind parameters with arguments
var body = MethodBodyProvider.Instance.GetBody(callInfo.Callee);
for (int i = 0; i < body.Parameters.Count(); i++)
{
var arg = callInfo.CallArguments[i];
for (int i = 0; i < body.Parameters.Count(); i++)
{
var arg = callInfo.CallArguments[i];
var param = body.Parameters[i];
var param = body.Parameters[i];
arg = AdaptIsReference(arg);
param = AdaptIsReference(param);
arg = AdaptIsReference(arg);
param = AdaptIsReference(param);
if (callInfo.CallerState.HasTraceables(arg))
{
calleeDepDomain.AssignTraceables(param, callInfo.CallerState.GetTraceables(arg));
}
if (callInfo.CallerState.HasOutputTraceables(arg))
{
calleeDepDomain.AddOutputTraceables(param, callInfo.CallerState.GetOutputTraceables(arg));
}
if (callInfo.CallerState.HasOutputControlTraceables(arg))
{
calleeDepDomain.AddOutputControlTraceables(param, callInfo.CallerState.GetOutputControlTraceables(arg));
}
if (callInfo.CallerState.HasTraceables(arg))
{
calleeDepDomain.AssignTraceables(param, callInfo.CallerState.GetTraceables(arg));
}
if (callInfo.CallerState.HasOutputTraceables(arg))
{
calleeDepDomain.AddOutputTraceables(param, callInfo.CallerState.GetOutputTraceables(arg));
}
if (callInfo.CallerState.HasOutputControlTraceables(arg))
{
calleeDepDomain.AddOutputControlTraceables(param, callInfo.CallerState.GetOutputControlTraceables(arg));
}
// DIEGODIEGO: Do I need this?
callInfo.ScopeData.PropagateCopy(arg, param);
initializedRanges.AssignValue(param, callInfo.VariableRanges.GetValue(param));
}
calleeDepDomain.Dependencies.A1_Escaping = callInfo.CallerState.Dependencies.A1_Escaping;
@ -280,10 +294,14 @@ namespace ScopeProgramAnalysis
return arg;
}
private DependencyPTGDomain BindCalleeCaller(InterProceduralCallInfo callInfo, ControlFlowGraph calleeCFG, IteratorDependencyAnalysis depAnalysis)
private DependencyPTGDomain BindCalleeCaller(InterProceduralCallInfo callInfo, ControlFlowGraph calleeCFG,
IteratorDependencyAnalysis depAnalysis,RangeAnalysis rangeAnalysis)
{
var exitResult = depAnalysis.Result[calleeCFG.Exit.Id].Output;
var body = MethodBodyProvider.Instance.GetBody(callInfo.Callee);
var exitRange = rangeAnalysis.Result[calleeCFG.Exit.Id].Output;
var body = MethodBodyProvider.Instance.GetBody(callInfo.Callee);
for (int i = 0; i < body.Parameters.Count(); i++)
{
@ -349,6 +367,9 @@ namespace ScopeProgramAnalysis
{
callInfo.CallerState.AddOutputControlTraceables(callInfo.CallLHS, exitResult.GetOutputControlTraceables(depAnalysis.ReturnVariable));
}
// DIEGODIEGO: Need to propagate range of return value
callInfo.VariableRanges.AssignValue(callInfo.CallLHS, exitRange.GetValue(rangeAnalysis.ReturnVariable));
}
return callInfo.CallerState;

Просмотреть файл

@ -1145,7 +1145,9 @@ namespace Backend.Analyses
CallerPTG = currentPTG,
ScopeData = this.scopeData,
Instruction = instruction,
ProtectedNodes = this.iteratorDependencyAnalysis.protectedNodes
VariableRanges = variableRanges,
ProtectedNodes = this.iteratorDependencyAnalysis.protectedNodes
};
var interProcResult = this.iteratorDependencyAnalysis.interproceduralManager.DoInterProcWithCallee(interProcInfo);
@ -2072,6 +2074,7 @@ namespace Backend.Analyses
CallerPTG = currentPTG,
ScopeData = this.scopeData,
Instruction = methodCall,
VariableRanges = this.variableRanges,
ProtectedNodes = this.iteratorDependencyAnalysis.protectedNodes
};

Просмотреть файл

@ -9,6 +9,7 @@ using Backend.Visitors;
using Backend.Analyses;
using Microsoft.Cci;
using Backend.Model;
using ScopeProgramAnalysis.Framework;
namespace ScopeProgramAnalysis
{
@ -16,15 +17,21 @@ namespace ScopeProgramAnalysis
{
public static readonly RangeDomain TOP = new RangeDomain(int.MinValue, int.MinValue);
public static readonly RangeDomain BOTTOM = new RangeDomain(0, -1);
public static readonly string STRINGTOP = "_STRING_TOP_";
public static readonly string STRINGBOTTOM = null;
public int LowerBound { get; set; }
public int UpperBound { get; set; }
public int LowerBound { get; private set; }
public int UpperBound { get; private set; }
public bool IsTop
public string Literal{ get; private set; }
private bool isString;
public bool IsTop
{
get
{
return LowerBound==int.MinValue && UpperBound==int.MaxValue;
return (!isString && LowerBound==int.MinValue && UpperBound==int.MaxValue) || (isString && Literal==STRINGTOP);
}
}
@ -32,7 +39,7 @@ namespace ScopeProgramAnalysis
{
get
{
return LowerBound == 0 && UpperBound == -1;
return (!isString && LowerBound == 0 && UpperBound == -1) || (isString && Literal == STRINGBOTTOM);
}
}
@ -40,15 +47,32 @@ namespace ScopeProgramAnalysis
{
this.LowerBound = singleton;
this.UpperBound = singleton;
this.Literal = null;
this.isString = false;
}
public RangeDomain(int start, int end)
{
this.LowerBound = start;
this.UpperBound = end;
}
public RangeDomain Join(RangeDomain oth)
this.Literal = null;
this.isString = false;
}
public RangeDomain(string literal)
{
this.LowerBound = 0;
this.UpperBound = -1;
this.Literal = literal;
this.isString = true;
}
public RangeDomain Join(RangeDomain oth)
{
if (isString)
{
return oth.Literal != this.Literal ? new RangeDomain(STRINGTOP) : this;
}
var prevInterval = this;
if (prevInterval.IsBottom)
return oth;
@ -64,8 +88,12 @@ namespace ScopeProgramAnalysis
public RangeDomain Widening(RangeDomain prev)
{
// Trivial cases
if (this.IsBottom)
if (isString)
{
return prev.Literal != this.Literal ? new RangeDomain(STRINGTOP) : this;
}
// Trivial cases
if (this.IsBottom)
return prev;
if (this.IsTop)
return this;
@ -83,33 +111,44 @@ namespace ScopeProgramAnalysis
public RangeDomain Clone()
{
if (isString) return new RangeDomain(this.Literal);
return new RangeDomain(this.LowerBound, this.UpperBound);
}
public bool LessEqual(RangeDomain oth)
{
return this.LowerBound>=oth.LowerBound && this.UpperBound<=oth.UpperBound;
if (isString) return this.Literal==oth.Literal;
return this.LowerBound>=oth.LowerBound && this.UpperBound<=oth.UpperBound;
}
public bool Equals(RangeDomain oth)
{
return this.LowerBound==oth.LowerBound && this.UpperBound==oth.UpperBound;
if (isString) return this.Literal == oth.Literal;
return this.LowerBound==oth.LowerBound && this.UpperBound==oth.UpperBound;
}
public RangeDomain Sum(RangeDomain rangeDomain)
{
if (IsTop) return this;
if (isString) return this;
if (IsTop) return this;
return new RangeDomain(this.LowerBound+rangeDomain.LowerBound,this.UpperBound+rangeDomain.UpperBound);
}
public RangeDomain Sub(RangeDomain rangeDomain)
{
if (IsTop) return this;
if (isString) return this;
if (IsTop) return this;
return new RangeDomain(this.LowerBound - rangeDomain.LowerBound, this.UpperBound - rangeDomain.UpperBound);
}
public override string ToString()
{
if (IsTop) return "_TOP_";
if (isString) return this.Literal!=null?$"'{this.Literal}":"_STRING_BOTTOM_";
if (IsTop) return "_TOP_";
if(IsBottom)
return "_BOTTOM_";
var result = String.Format(CultureInfo.InvariantCulture, "[{0}..{1}]", LowerBound, UpperBound);
@ -208,15 +247,22 @@ namespace ScopeProgramAnalysis
{
private object originalValue = null;
private VariableRangeDomain initRange = null;
public IVariable ReturnVariable { get; private set; }
public DataFlowAnalysisResult<VariableRangeDomain>[] Result { get; private set; }
public DataFlowAnalysisResult<VariableRangeDomain>[] Result { get; private set; }
public RangeAnalysis(ControlFlowGraph cfg): base(cfg)
public RangeAnalysis(ControlFlowGraph cfg, IMethodDefinition method): base(cfg)
{
this.ReturnVariable = new LocalVariable(method.Name + "_" + "$RV") { Type = method.Type.PlatformType.SystemObject };
}
public RangeAnalysis(ControlFlowGraph cfg, IMethodDefinition method, VariableRangeDomain initRange) : this(cfg, method)
{
this.initRange = initRange;
}
}
public override DataFlowAnalysisResult<VariableRangeDomain>[] Analyze()
public override DataFlowAnalysisResult<VariableRangeDomain>[] Analyze()
{
Result = base.Analyze();
return Result;
@ -236,10 +282,14 @@ namespace ScopeProgramAnalysis
protected override VariableRangeDomain InitialValue(CFGNode node)
{
return new VariableRangeDomain();
if (this.cfg.Entry.Id == node.Id && this.initRange != null)
{
return this.initRange;
}
return new VariableRangeDomain();
}
protected override VariableRangeDomain Join(VariableRangeDomain left, VariableRangeDomain right)
protected override VariableRangeDomain Join(VariableRangeDomain left, VariableRangeDomain right)
{
return left.Join(right);
}
@ -257,27 +307,45 @@ namespace ScopeProgramAnalysis
public VariableRangeDomain State { get; internal set; }
public override void Visit(LoadInstruction instruction)
{
if(instruction.Operand is Constant)
{
var value = ExtractConstant(instruction.Operand as Constant);
this.State.SetValue(instruction.Result, value);
}
if(instruction.Operand is IVariable)
{
this.State.SetValue(instruction.Result, this.State.GetValue(instruction.Operand as IVariable));
}
}
{
var source = instruction.Operand;
var dest = instruction.Result;
Copy(source, dest);
}
private void Copy(IValue source, IVariable dest)
{
if (source is Constant)
{
var value = ExtractConstant(source as Constant);
this.State.SetValue(dest, value);
}
if (source is IVariable)
{
this.State.SetValue(dest, this.State.GetValue(source as IVariable));
}
}
public override void Visit(ReturnInstruction instruction)
{
Copy(instruction.Operand, this.rangeAnalysis.ReturnVariable);
}
private RangeDomain ExtractConstant(Constant K)
{
int value = -1;
if (TypeHelper.IsPrimitiveInteger(K.Type) && !(K.Value is Int64 || K.Value is UInt64))
{
value = (int)K.Value;
return new RangeDomain(value, value);
}
if (K.Type.IsString())
{
var literal = (string)K.Value;
return new RangeDomain(literal);
}
private RangeDomain ExtractConstant(Constant K)
{
int value = -1;
if (TypeHelper.IsPrimitiveInteger(K.Type) && !(K.Value is Int64 || K.Value is UInt64))
{
value = (int)K.Value;
return new RangeDomain(value, value);
}
return RangeDomain.BOTTOM;
}