Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
//
// AnalysisDecoder.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 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 Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Expressions;
using Mono.CodeContracts.Static.ControlFlow;
using Mono.CodeContracts.Static.Lattices;
namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis {
class AnalysisDecoder<TSymValue> : ILVisitorBase<APC, TSymValue, TSymValue, ExprDomain<TSymValue>, ExprDomain<TSymValue>>
where TSymValue : IEquatable<TSymValue> {
public override ExprDomain<TSymValue> DefaultVisit (APC pc, ExprDomain<TSymValue> data)
{
return data;
}
public override ExprDomain<TSymValue> Assume (APC pc, EdgeTag tag, TSymValue condition, ExprDomain<TSymValue> data)
{
FlatDomain<Expr<TSymValue>> aExpression = data [condition];
if (aExpression.IsNormal()) {
bool truth = tag != EdgeTag.False;
data = aExpression.Value.Decode<ExprDomain<TSymValue>, ExprDomain<TSymValue>, AssumeDecoder<TSymValue>>
(pc, condition, new AssumeDecoder<TSymValue> (truth), data);
}
return data;
}
public override ExprDomain<TSymValue> Assert (APC pc, EdgeTag tag, TSymValue condition, ExprDomain<TSymValue> data)
{
FlatDomain<Expr<TSymValue>> expression = data [condition];
if (expression.IsNormal()) {
data = expression.Value.Decode<ExprDomain<TSymValue>, ExprDomain<TSymValue>, AssumeDecoder<TSymValue>>
(pc, condition, new AssumeDecoder<TSymValue> (true), data);
}
return data;
}
public override ExprDomain<TSymValue> Binary (APC pc, BinaryOperator op, TSymValue dest, TSymValue operand1, TSymValue operand2, ExprDomain<TSymValue> data)
{
return data.Add (dest, new BinaryExpr<TSymValue> (operand1, operand2, op));
}
public override ExprDomain<TSymValue> Isinst (APC pc, TypeNode type, TSymValue dest, TSymValue obj, ExprDomain<TSymValue> data)
{
return data.Add (dest, new IsInstExpr<TSymValue> (obj, type));
}
public override ExprDomain<TSymValue> LoadConst (APC pc, TypeNode type, object constant, TSymValue dest, ExprDomain<TSymValue> data)
{
return data.Add (dest, new ConstExpr<TSymValue> (type, constant));
}
public override ExprDomain<TSymValue> LoadNull (APC pc, TSymValue dest, ExprDomain<TSymValue> polarity)
{
return polarity.Add (dest, NullExpr<TSymValue>.Instance);
}
public override ExprDomain<TSymValue> Sizeof (APC pc, TypeNode type, TSymValue dest, ExprDomain<TSymValue> data)
{
return data.Add (dest, new SizeOfExpr<TSymValue> (type));
}
public override ExprDomain<TSymValue> Unary (APC pc, UnaryOperator op, bool unsigned, TSymValue dest, TSymValue source, ExprDomain<TSymValue> data)
{
return data.Add (dest, new UnaryExpr<TSymValue> (source, op, unsigned));
}
}
}

View File

@@ -0,0 +1,100 @@
//
// AssumeDecoder.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 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 Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Expressions;
using Mono.CodeContracts.Static.ControlFlow;
using Mono.CodeContracts.Static.Lattices;
namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis {
struct AssumeDecoder<SymbolicValue> : IExpressionILVisitor<APC, SymbolicValue, SymbolicValue, ExprDomain<SymbolicValue>, ExprDomain<SymbolicValue>>
where SymbolicValue : IEquatable<SymbolicValue> {
private readonly bool truth;
public AssumeDecoder (bool truth)
{
this.truth = truth;
}
#region IExpressionILVisitor<APC,SymbolicValue,SymbolicValue,ExprDomain<SymbolicValue>,ExprDomain<SymbolicValue>> Members
public ExprDomain<SymbolicValue> Binary (APC pc, BinaryOperator op, SymbolicValue dest, SymbolicValue s1, SymbolicValue s2, ExprDomain<SymbolicValue> data)
{
if (this.truth && op.IsEqualityOperator ()) {
if (!data.HasRefinement (s1)) {
FlatDomain<Expr<SymbolicValue>> expression2 = data [s2];
if (expression2.IsNormal() && !data.IsReachableFrom (s2, s1))
return data.Add (s1, expression2.Value);
} else if (!data.HasRefinement (s2)) {
FlatDomain<Expr<SymbolicValue>> expression1 = data [s1];
if (expression1.IsNormal() && !data.IsReachableFrom (s1, s2))
return data.Add (s2, expression1.Value);
}
}
if (!this.truth && op == BinaryOperator.Cne_Un) {
if (!data.HasRefinement (s1)) {
FlatDomain<Expr<SymbolicValue>> expression2 = data [s2];
if (expression2.IsNormal() && !data.IsReachableFrom (s2, s1))
return data.Add (s1, expression2.Value);
} else if (!data.HasRefinement (s2)) {
FlatDomain<Expr<SymbolicValue>> expression1 = data [s1];
if (expression1.IsNormal() && !data.IsReachableFrom (s1, s2))
return data.Add (s2, expression1.Value);
}
}
return data;
}
public ExprDomain<SymbolicValue> Isinst (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue obj, ExprDomain<SymbolicValue> data)
{
return data;
}
public ExprDomain<SymbolicValue> LoadNull (APC pc, SymbolicValue dest, ExprDomain<SymbolicValue> polarity)
{
return polarity;
}
public ExprDomain<SymbolicValue> LoadConst (APC pc, TypeNode type, object constant, SymbolicValue dest, ExprDomain<SymbolicValue> data)
{
return data;
}
public ExprDomain<SymbolicValue> Sizeof (APC pc, TypeNode type, SymbolicValue dest, ExprDomain<SymbolicValue> data)
{
return data;
}
public ExprDomain<SymbolicValue> Unary (APC pc, UnaryOperator op, bool unsigned, SymbolicValue dest, SymbolicValue source, ExprDomain<SymbolicValue> data)
{
return data;
}
#endregion
}
}

View File

@@ -0,0 +1,123 @@
//
// ExprDomain.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 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.Collections.Generic;
using System.IO;
using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Expressions;
using Mono.CodeContracts.Static.DataStructures;
using Mono.CodeContracts.Static.Lattices;
namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis {
class ExprDomain<TSymValue> : IGraph<TSymValue, Dummy>
where TSymValue : IEquatable<TSymValue> {
private readonly EnvironmentDomain<TSymValue, FlatDomain<Expr<TSymValue>>> expressions;
private ExprDomain (EnvironmentDomain<TSymValue, FlatDomain<Expr<TSymValue>>> expressions)
{
this.expressions = expressions;
}
#region Implementation of IGraph<SymbolicValue,Dummy>
public IEnumerable<TSymValue> Keys
{
get { return this.expressions.Keys; }
}
public bool IsBottom
{
get { return this.expressions.IsBottom; }
}
IEnumerable<TSymValue> IGraph<TSymValue, Dummy>.Nodes
{
get { return this.expressions.Keys; }
}
public IEnumerable<Pair<Dummy, TSymValue>> Successors(TSymValue node)
{
FlatDomain<Expr<TSymValue>> expr = this.expressions[node];
if (expr.IsNormal())
foreach (TSymValue sv in expr.Value.Variables)
yield return new Pair<Dummy, TSymValue> (Dummy.Value, sv);
}
#endregion
public FlatDomain<Expr<TSymValue>> this[TSymValue sv]
{
get { return this.expressions[sv]; }
}
public ExprDomain<TSymValue> Join(ExprDomain<TSymValue> that, bool widening, out bool weaker)
{
return new ExprDomain<TSymValue> (this.expressions.Join (that.expressions, widening, out weaker));
}
public static ExprDomain<TSymValue> TopValue(Func<TSymValue, int> keyConverter)
{
return new ExprDomain<TSymValue> (EnvironmentDomain<TSymValue, FlatDomain<Expr<TSymValue>>>.TopValue (keyConverter));
}
public ExprDomain<TSymValue> Add (TSymValue sv, Expr<TSymValue> expr)
{
return new ExprDomain<TSymValue> (this.expressions.With (sv, expr));
}
public ExprDomain<TSymValue> Remove(TSymValue sv)
{
return new ExprDomain<TSymValue> (this.expressions.Without (sv));
}
public ExprDomain<TSymValue> Empty()
{
return new ExprDomain<TSymValue> (this.expressions.Empty ());
}
public bool HasRefinement(TSymValue sv)
{
return this.expressions.Contains (sv);
}
public bool IsReachableFrom(TSymValue source, TSymValue target)
{
bool reachable = false;
DepthFirst.Visit (this, source, sv => {
if (sv.Equals (target))
reachable = true;
return !reachable; // break if reachable
}, null);
return reachable;
}
public void Dump(TextWriter tw)
{
this.expressions.Dump (tw);
}
}
}

View File

@@ -0,0 +1,88 @@
//
// ExpressionAnalysisFacade.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 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 Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.Analysis.HeapAnalysis;
using Mono.CodeContracts.Static.ControlFlow;
using Mono.CodeContracts.Static.DataFlowAnalysis;
using Mono.CodeContracts.Static.DataStructures;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis {
class ExpressionAnalysisFacade<TSymValue, TContext, TEdgeData>
where TSymValue : IEquatable<TSymValue>
where TContext : IValueContextProvider<TSymValue>
where TEdgeData : IImmutableMap<TSymValue, Sequence<TSymValue>> {
public readonly Predicate<APC> IsUnreachable;
public readonly ICodeLayer<TSymValue, TSymValue, TContext, TEdgeData> ValueLayer;
private IFixPointInfo<APC, ExprDomain<TSymValue>> fix_point_info;
public ExpressionAnalysisFacade (ICodeLayer<TSymValue, TSymValue, TContext, TEdgeData> valueLayer,
Predicate<APC> isUnreachable)
{
this.ValueLayer = valueLayer;
this.IsUnreachable = isUnreachable;
}
public bool PreStateLookup (APC label, out ExprDomain<TSymValue> ifFound)
{
return this.fix_point_info.PreStateLookup (label, out ifFound);
}
public bool PostStateLookup (APC label, out ExprDomain<TSymValue> ifFound)
{
return this.fix_point_info.PostStateLookup (label, out ifFound);
}
public void SaveFixPointInfo (IFixPointInfo<APC, ExprDomain<TSymValue>> fixPointInfo)
{
this.fix_point_info = fixPointInfo;
}
public ExprDomain<TSymValue> InitialValue (Func<TSymValue, int> keyConverter)
{
return ExprDomain<TSymValue>.TopValue (keyConverter);
}
public IAnalysis<APC, ExprDomain<TSymValue>, IILVisitor<APC, TSymValue, TSymValue, ExprDomain<TSymValue>, ExprDomain<TSymValue>>, TEdgeData>
CreateExpressionAnalysis ()
{
return new ValueAnalysis<TSymValue, TContext, TEdgeData> (this);
}
public IILDecoder<APC, LabeledSymbol<APC, TSymValue>, TSymValue, IExpressionContextProvider<LabeledSymbol<APC, TSymValue>, TSymValue>, TEdgeData>
GetDecoder (
IILDecoder<APC, TSymValue, TSymValue, IValueContextProvider<TSymValue>, TEdgeData> ilDecoder)
{
return new ExpressionDecoder<TSymValue, TContext, TEdgeData> (ilDecoder, this);
}
}
}

View File

@@ -0,0 +1,164 @@
//
// ExpressionDecoder.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 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 Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Expressions;
using Mono.CodeContracts.Static.Analysis.HeapAnalysis;
using Mono.CodeContracts.Static.ControlFlow;
using Mono.CodeContracts.Static.DataStructures;
using Mono.CodeContracts.Static.Lattices;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis {
class ExpressionDecoder<TSymbolicValue, TContext, TEdgeData> :
IILDecoder<APC, LabeledSymbol<APC, TSymbolicValue>, TSymbolicValue, IExpressionContextProvider<LabeledSymbol<APC, TSymbolicValue>, TSymbolicValue>, TEdgeData>,
IExpressionContextProvider<LabeledSymbol<APC, TSymbolicValue>, TSymbolicValue>,
IExpressionContext<LabeledSymbol<APC, TSymbolicValue>, TSymbolicValue>
where TSymbolicValue : IEquatable<TSymbolicValue>
where TContext : IValueContextProvider<TSymbolicValue>
where TEdgeData : IImmutableMap<TSymbolicValue, Sequence<TSymbolicValue>> {
private readonly IILDecoder<APC, TSymbolicValue, TSymbolicValue, IValueContextProvider<TSymbolicValue>, TEdgeData> value_decoder;
private readonly ExpressionAnalysisFacade<TSymbolicValue, TContext, TEdgeData> parent;
private readonly IValueContextProvider<TSymbolicValue> underlying;
public ExpressionDecoder (IILDecoder<APC, TSymbolicValue, TSymbolicValue, IValueContextProvider<TSymbolicValue>, TEdgeData> valueDecoder,
ExpressionAnalysisFacade<TSymbolicValue, TContext, TEdgeData> parent)
{
this.value_decoder = valueDecoder;
this.parent = parent;
this.underlying = valueDecoder.ContextProvider;
}
#region IExpressionContext<LabeledSymbol<APC,SymbolicValue>,SymbolicValue> Members
public LabeledSymbol<APC, TSymbolicValue> Refine (APC pc, TSymbolicValue variable)
{
return new LabeledSymbol<APC, TSymbolicValue> (pc, variable);
}
public TSymbolicValue Unrefine (LabeledSymbol<APC, TSymbolicValue> expression)
{
return expression.Symbol;
}
public Result Decode<Data, Result, Visitor> (LabeledSymbol<APC, TSymbolicValue> expr, Visitor visitor, Data data)
where Visitor : ISymbolicExpressionVisitor<LabeledSymbol<APC, TSymbolicValue>, LabeledSymbol<APC, TSymbolicValue>, TSymbolicValue, Data, Result>
{
ExprDomain<TSymbolicValue> ifFound;
if (!this.parent.PreStateLookup (expr.ReadAt, out ifFound) || ifFound.IsBottom)
return visitor.SymbolicConstant (expr, expr.Symbol, data);
FlatDomain<Expr<TSymbolicValue>> aExpr = ifFound [expr.Symbol];
if (aExpr.IsNormal()) {
return aExpr.Value.Decode<Data, Result, ExpressionDecoderAdapter<TSymbolicValue, Data, Result, Visitor>>
(expr.ReadAt, expr.Symbol, new ExpressionDecoderAdapter<TSymbolicValue, Data, Result, Visitor> (visitor), data);
}
TypeNode type;
object constant;
if (this.parent.ValueLayer.ILDecoder.ContextProvider.ValueContext.IsConstant (expr.ReadAt, expr.Symbol, out type, out constant))
return visitor.LoadConst (expr, type, constant, expr.Symbol, data);
return visitor.SymbolicConstant (expr, expr.Symbol, data);
}
public FlatDomain<TypeNode> GetType (LabeledSymbol<APC, TSymbolicValue> expr)
{
return this.underlying.ValueContext.GetType (expr.ReadAt, expr.Symbol);
}
public APC GetPC (LabeledSymbol<APC, TSymbolicValue> pc)
{
return pc.ReadAt;
}
public LabeledSymbol<APC, TSymbolicValue> For (TSymbolicValue variable)
{
return new LabeledSymbol<APC, TSymbolicValue> (MethodContext.CFG.Entry, variable);
}
public bool IsZero (LabeledSymbol<APC, TSymbolicValue> expression)
{
return ValueContext.IsZero (expression.ReadAt, expression.Symbol);
}
#endregion
#region IILDecoder<APC,LabeledSymbol<APC,SymbolicValue>,SymbolicValue,IExpressionContextProvider<LabeledSymbol<APC,SymbolicValue>,SymbolicValue>,EdgeData> Members
public IExpressionContextProvider<LabeledSymbol<APC, TSymbolicValue>, TSymbolicValue> ContextProvider
{
get { return this; }
}
public Result ForwardDecode<Data, Result, Visitor> (APC pc, Visitor visitor, Data state)
where Visitor : IILVisitor<APC, LabeledSymbol<APC, TSymbolicValue>, TSymbolicValue, Data, Result>
{
return this.value_decoder.ForwardDecode<Data, Result, ILDecoderAdapter<TSymbolicValue, Data, Result, Visitor>>
(pc, new ILDecoderAdapter<TSymbolicValue, Data, Result, Visitor> (visitor), state);
}
public bool IsUnreachable (APC pc)
{
return this.parent.IsUnreachable (pc);
}
public TEdgeData EdgeData (APC from, APC to)
{
return this.parent.ValueLayer.ILDecoder.EdgeData (from, to);
}
#endregion
#region Implementation of IMethodContextProvider<Field,Method>
public IMethodContext MethodContext
{
get { return this.underlying.MethodContext; }
}
#endregion
#region Implementation of IStackContextProvider<Field,Method>
public IStackContext StackContext
{
get { return this.underlying.StackContext; }
}
#endregion
#region Implementation of IValueContextProvider<Local,Parameter,Method,Field,Type,SymbolicValue>
public IValueContext<TSymbolicValue> ValueContext
{
get { return this.underlying.ValueContext; }
}
#endregion
#region Implementation of IExpressionContextProvider<Local,Parameter,Method,Field,Type,ExternalExpression<APC,SymbolicValue>,SymbolicValue>
public IExpressionContext<LabeledSymbol<APC, TSymbolicValue>, TSymbolicValue> ExpressionContext
{
get { return this; }
}
#endregion
}
}

View File

@@ -0,0 +1,85 @@
//
// ExpressionDecoderAdapter.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 Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.Analysis.HeapAnalysis;
using Mono.CodeContracts.Static.ControlFlow;
namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis {
struct ExpressionDecoderAdapter<SymbolicValue, Data, Result, Visitor>
: IExpressionILVisitor<APC, SymbolicValue, SymbolicValue, Data, Result>
where SymbolicValue : IEquatable<SymbolicValue>
where Visitor : ISymbolicExpressionVisitor<LabeledSymbol<APC, SymbolicValue>, LabeledSymbol<APC, SymbolicValue>, SymbolicValue, Data, Result> {
private readonly Visitor visitor;
public ExpressionDecoderAdapter (Visitor visitor)
{
this.visitor = visitor;
}
#region Implementation of IExpressionILVisitor<APC,Type,SymbolicValue,SymbolicValue,Data,Result>
public Result Binary (APC pc, BinaryOperator op, SymbolicValue dest, SymbolicValue operand1, SymbolicValue operand2, Data data)
{
return this.visitor.Binary (Unrefine (pc, dest), op, dest, Unrefine (pc, operand1), Unrefine (pc, operand2), data);
}
public Result Isinst (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue obj, Data data)
{
return this.visitor.Isinst (Unrefine (pc, dest), type, dest, Unrefine (pc, obj), data);
}
public Result LoadNull (APC pc, SymbolicValue dest, Data polarity)
{
return this.visitor.LoadNull (Unrefine (pc, dest), dest, polarity);
}
public Result LoadConst (APC pc, TypeNode type, object constant, SymbolicValue dest, Data data)
{
return this.visitor.LoadConst (Unrefine (pc, dest), type, constant, dest, data);
}
public Result Sizeof (APC pc, TypeNode type, SymbolicValue dest, Data data)
{
return this.visitor.Sizeof (Unrefine (pc, dest), type, dest, data);
}
public Result Unary (APC pc, UnaryOperator op, bool unsigned, SymbolicValue dest, SymbolicValue source, Data data)
{
return this.visitor.Unary (Unrefine (pc, dest), op, unsigned, dest, Unrefine (pc, source), data);
}
private LabeledSymbol<APC, SymbolicValue> Unrefine (APC pc, SymbolicValue dest)
{
return new LabeledSymbol<APC, SymbolicValue> (pc, dest);
}
#endregion
}
}

View File

@@ -0,0 +1,132 @@
//
// ExpressionPrinterFactory.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 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.Text;
using Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.Analysis.Drivers;
using Mono.CodeContracts.Static.Analysis.HeapAnalysis;
using Mono.CodeContracts.Static.ControlFlow;
using Mono.CodeContracts.Static.DataStructures;
namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis {
static class ExpressionPrinterFactory {
public static Func<LabeledSymbol<APC, SymbolicValue>, string> Printer<SymbolicValue>
(IExpressionContextProvider<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> contextProvider,
IMethodDriver<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> methodDriver)
where SymbolicValue : IEquatable<SymbolicValue>
{
return new PrinterImpl<SymbolicValue> (contextProvider, methodDriver).PrintAt;
}
#region Nested type: PrinterImpl
private class PrinterImpl<SymbolicValue> :
ISymbolicExpressionVisitor<LabeledSymbol<APC, SymbolicValue>, LabeledSymbol<APC, SymbolicValue>, SymbolicValue, StringBuilder, Dummy>
where SymbolicValue : IEquatable<SymbolicValue> {
private readonly IExpressionContextProvider<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> context_provider;
private readonly IMethodDriver<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> method_driver;
public PrinterImpl (IExpressionContextProvider<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> contextProvider,
IMethodDriver<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> methodDriver)
{
this.context_provider = contextProvider;
this.method_driver = methodDriver;
}
public string PrintAt (LabeledSymbol<APC, SymbolicValue> expr)
{
var sb = new StringBuilder ();
Recurse (sb, expr);
return sb.ToString ();
}
private void Recurse (StringBuilder sb, LabeledSymbol<APC, SymbolicValue> expr)
{
if (expr.Symbol.Equals (default(SymbolicValue)))
sb.Append ("<!null!>");
else
this.context_provider.ExpressionContext.Decode<StringBuilder, Dummy, PrinterImpl<SymbolicValue>> (expr, this, sb);
}
#region Implementation of IExpressionILVisitor<ExternalExpression<APC,SymbolicValue>,ExternalExpression<APC,SymbolicValue>,SymbolicValue,StringBuilder,Dummy>
public Dummy Binary (LabeledSymbol<APC, SymbolicValue> pc, BinaryOperator op, SymbolicValue dest, LabeledSymbol<APC, SymbolicValue> operand1, LabeledSymbol<APC, SymbolicValue> operand2,
StringBuilder data)
{
data.Append ('(');
Recurse (data, operand1);
data.AppendFormat (" {0} ", op);
Recurse (data, operand2);
data.Append (')');
return Dummy.Value;
}
public Dummy Isinst (LabeledSymbol<APC, SymbolicValue> pc, TypeNode type, SymbolicValue dest, LabeledSymbol<APC, SymbolicValue> obj, StringBuilder data)
{
data.AppendFormat ("IsInst({0}) ", this.method_driver.MetaDataProvider.FullName (type));
Recurse (data, obj);
return Dummy.Value;
}
public Dummy LoadNull (LabeledSymbol<APC, SymbolicValue> pc, SymbolicValue dest, StringBuilder polarity)
{
polarity.Append ("NULL");
return Dummy.Value;
}
public Dummy LoadConst (LabeledSymbol<APC, SymbolicValue> pc, TypeNode type, object constant, SymbolicValue dest, StringBuilder data)
{
data.Append (constant.ToString ());
return Dummy.Value;
}
public Dummy Sizeof (LabeledSymbol<APC, SymbolicValue> pc, TypeNode type, SymbolicValue dest, StringBuilder data)
{
data.AppendFormat ("sizeof({0})", this.method_driver.MetaDataProvider.FullName (type));
return Dummy.Value;
}
public Dummy Unary (LabeledSymbol<APC, SymbolicValue> pc, UnaryOperator op, bool unsigned, SymbolicValue dest, LabeledSymbol<APC, SymbolicValue> source, StringBuilder data)
{
data.AppendFormat ("{0} ", op.ToString ());
Recurse (data, source);
return Dummy.Value;
}
#endregion
#region Implementation of ISymbolicExpressionVisitor<ExternalExpression<APC,SymbolicValue>,ExternalExpression<APC,SymbolicValue>,SymbolicValue,StringBuilder,Dummy>
public Dummy SymbolicConstant (LabeledSymbol<APC, SymbolicValue> pc, SymbolicValue variable, StringBuilder data)
{
data.Append (variable.ToString ());
return Dummy.Value;
}
#endregion
}
#endregion
}
}

View File

@@ -0,0 +1,411 @@
//
// ILDecoderAdapter.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 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.Collections.Generic;
using Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.Analysis.HeapAnalysis;
using Mono.CodeContracts.Static.ControlFlow;
using Mono.CodeContracts.Static.DataStructures;
namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis {
/// <summary>
/// This class performs translation from (source) SymbolicValue to LabeledSymbol
/// </summary>
struct ILDecoderAdapter<SymbolicValue, Data, Result, Visitor>
: IILVisitor<APC, SymbolicValue, SymbolicValue, Data, Result>
where SymbolicValue : IEquatable<SymbolicValue>
where Visitor : IILVisitor<APC, LabeledSymbol<APC, SymbolicValue>, SymbolicValue, Data, Result> {
private readonly Visitor visitor;
public ILDecoderAdapter (Visitor visitor)
{
this.visitor = visitor;
}
#region IILVisitor<APC,SymbolicValue,SymbolicValue,Data,Result> Members
public Result Binary (APC pc, BinaryOperator op, SymbolicValue dest, SymbolicValue operand1, SymbolicValue operand2, Data data)
{
return this.visitor.Binary (pc, op, dest, Convert (pc, operand1), Convert (pc, operand2), data);
}
public Result Isinst (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue obj, Data data)
{
return this.visitor.Isinst (pc, type, dest, Convert (pc, obj), data);
}
public Result LoadNull (APC pc, SymbolicValue dest, Data polarity)
{
return this.visitor.LoadNull (pc, dest, polarity);
}
public Result LoadConst (APC pc, TypeNode type, object constant, SymbolicValue dest, Data data)
{
return this.visitor.LoadConst (pc, type, constant, dest, data);
}
public Result Sizeof (APC pc, TypeNode type, SymbolicValue dest, Data data)
{
return this.visitor.Sizeof (pc, type, dest, data);
}
public Result Unary (APC pc, UnaryOperator op, bool unsigned, SymbolicValue dest, SymbolicValue source, Data data)
{
return this.visitor.Unary (pc, op, unsigned, dest, Convert (pc, source), data);
}
public Result Entry (APC pc, Method method, Data data)
{
return this.visitor.Entry (pc, method, data);
}
public Result Assume (APC pc, EdgeTag tag, SymbolicValue condition, Data data)
{
return this.visitor.Assume (pc, tag, Convert (pc, condition), data);
}
public Result Assert (APC pc, EdgeTag tag, SymbolicValue condition, Data data)
{
return this.visitor.Assert (pc, tag, Convert (pc, condition), data);
}
public Result BeginOld (APC pc, APC matchingEnd, Data data)
{
return this.visitor.BeginOld (pc, matchingEnd, data);
}
public Result EndOld (APC pc, APC matchingBegin, TypeNode type, SymbolicValue dest, SymbolicValue source, Data data)
{
return this.visitor.EndOld (pc, matchingBegin, type, dest, Convert (pc, source), data);
}
public Result LoadStack (APC pc, int offset, SymbolicValue dest, SymbolicValue source, bool isOld, Data data)
{
return this.visitor.LoadStack (pc, offset, dest, Convert (pc, source), isOld, data);
}
public Result LoadStackAddress (APC pc, int offset, SymbolicValue dest, SymbolicValue source, TypeNode type, bool isOld, Data data)
{
return this.visitor.LoadStackAddress (pc, offset, dest, Convert (pc, source), type, isOld, data);
}
public Result LoadResult (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue source, Data data)
{
return this.visitor.LoadResult (pc, type, dest, Convert (pc, source), data);
}
public Result Arglist (APC pc, SymbolicValue dest, Data data)
{
return this.visitor.Arglist (pc, dest, data);
}
public Result Branch (APC pc, APC target, bool leavesExceptionBlock, Data data)
{
throw new Exception ("Should not get branches at this level of abstraction.");
}
public Result BranchCond (APC pc, APC target, BranchOperator bop, SymbolicValue value1, SymbolicValue value2, Data data)
{
throw new Exception ("Should not get branches at this level of abstraction.");
}
public Result BranchTrue (APC pc, APC target, SymbolicValue cond, Data data)
{
throw new Exception ("Should not get branches at this level of abstraction.");
}
public Result BranchFalse (APC pc, APC target, SymbolicValue cond, Data data)
{
throw new Exception ("Should not get branches at this level of abstraction.");
}
public Result Break (APC pc, Data data)
{
return this.visitor.Break (pc, data);
}
public Result Call<TypeList, ArgList> (APC pc, Method method, bool virt, TypeList extraVarargs, SymbolicValue dest, ArgList args, Data data)
where TypeList : IIndexable<TypeNode>
where ArgList : IIndexable<SymbolicValue>
{
return this.visitor.Call (pc, method, virt, extraVarargs, dest, Convert (pc, args), data);
}
public Result Calli<TypeList, ArgList> (APC pc, TypeNode returnType, TypeList argTypes, bool instance, SymbolicValue dest, SymbolicValue functionPointer, ArgList args, Data data)
where TypeList : IIndexable<TypeNode> where ArgList : IIndexable<SymbolicValue>
{
return this.visitor.Calli (pc, returnType, argTypes, instance, dest, Convert (pc, functionPointer), Convert (pc, args), data);
}
public Result CheckFinite (APC pc, SymbolicValue dest, SymbolicValue source, Data data)
{
return this.visitor.CheckFinite (pc, dest, Convert (pc, source), data);
}
public Result CopyBlock (APC pc, SymbolicValue destAddress, SymbolicValue srcAddress, SymbolicValue len, Data data)
{
return this.visitor.CopyBlock (pc, Convert (pc, destAddress), Convert (pc, srcAddress), Convert (pc, len), data);
}
public Result EndFilter (APC pc, SymbolicValue decision, Data data)
{
return this.visitor.EndFilter (pc, Convert (pc, decision), data);
}
public Result EndFinally (APC pc, Data data)
{
return this.visitor.EndFinally (pc, data);
}
public Result Jmp (APC pc, Method method, Data data)
{
return this.visitor.Jmp (pc, method, data);
}
public Result LoadArg (APC pc, Parameter argument, bool isOld, SymbolicValue dest, Data data)
{
return this.visitor.LoadArg (pc, argument, isOld, dest, data);
}
public Result LoadArgAddress (APC pc, Parameter argument, bool isOld, SymbolicValue dest, Data data)
{
return this.visitor.LoadArgAddress (pc, argument, isOld, dest, data);
}
public Result LoadLocal (APC pc, Local local, SymbolicValue dest, Data data)
{
return this.visitor.LoadLocal (pc, local, dest, data);
}
public Result LoadLocalAddress (APC pc, Local local, SymbolicValue dest, Data data)
{
return this.visitor.LoadLocalAddress (pc, local, dest, data);
}
public Result Nop (APC pc, Data data)
{
return this.visitor.Nop (pc, data);
}
public Result Pop (APC pc, SymbolicValue source, Data data)
{
return this.visitor.Pop (pc, Convert (pc, source), data);
}
public Result Return (APC pc, SymbolicValue source, Data data)
{
return this.visitor.Return (pc, Convert (pc, source), data);
}
public Result StoreArg (APC pc, Parameter argument, SymbolicValue source, Data data)
{
return this.visitor.StoreArg (pc, argument, Convert (pc, source), data);
}
public Result StoreLocal (APC pc, Local local, SymbolicValue source, Data data)
{
return this.visitor.StoreLocal (pc, local, Convert (pc, source), data);
}
public Result Switch (APC pc, TypeNode type, IEnumerable<Pair<object, APC>> cases, SymbolicValue value, Data data)
{
throw new Exception ("Should not get branches at this level of abstraction.");
}
public Result Box (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue source, Data data)
{
return this.visitor.Box (pc, type, dest, Convert (pc, source), data);
}
public Result ConstrainedCallvirt<TypeList, ArgList> (APC pc, Method method, TypeNode constraint, TypeList extraVarargs, SymbolicValue dest, ArgList args, Data data)
where TypeList : IIndexable<TypeNode>
where ArgList : IIndexable<SymbolicValue>
{
return this.visitor.ConstrainedCallvirt (pc, method, constraint, extraVarargs, dest, Convert (pc, args), data);
}
public Result CastClass (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue obj, Data data)
{
return this.visitor.CastClass (pc, type, dest, Convert (pc, obj), data);
}
public Result CopyObj (APC pc, TypeNode type, SymbolicValue destPtr, SymbolicValue sourcePtr, Data data)
{
return this.visitor.CopyObj (pc, type, Convert (pc, destPtr), Convert (pc, sourcePtr), data);
}
public Result Initobj (APC pc, TypeNode type, SymbolicValue ptr, Data data)
{
return this.visitor.Initobj (pc, type, Convert (pc, ptr), data);
}
public Result LoadElement (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue array, SymbolicValue index, Data data)
{
return this.visitor.LoadElement (pc, type, dest, Convert (pc, array), Convert (pc, index), data);
}
public Result LoadField (APC pc, Field field, SymbolicValue dest, SymbolicValue obj, Data data)
{
return this.visitor.LoadField (pc, field, dest, Convert (pc, obj), data);
}
public Result LoadFieldAddress (APC pc, Field field, SymbolicValue dest, SymbolicValue obj, Data data)
{
return this.visitor.LoadFieldAddress (pc, field, dest, Convert (pc, obj), data);
}
public Result LoadLength (APC pc, SymbolicValue dest, SymbolicValue array, Data data)
{
return this.visitor.LoadLength (pc, dest, Convert (pc, array), data);
}
public Result LoadStaticField (APC pc, Field field, SymbolicValue dest, Data data)
{
return this.visitor.LoadStaticField (pc, field, dest, data);
}
public Result LoadStaticFieldAddress (APC pc, Field field, SymbolicValue dest, Data data)
{
return this.visitor.LoadStaticFieldAddress (pc, field, dest, data);
}
public Result LoadTypeToken (APC pc, TypeNode type, SymbolicValue dest, Data data)
{
return this.visitor.LoadTypeToken (pc, type, dest, data);
}
public Result LoadFieldToken (APC pc, Field type, SymbolicValue dest, Data data)
{
return this.visitor.LoadFieldToken (pc, type, dest, data);
}
public Result LoadMethodToken (APC pc, Method type, SymbolicValue dest, Data data)
{
return this.visitor.LoadMethodToken (pc, type, dest, data);
}
public Result NewArray<ArgList> (APC pc, TypeNode type, SymbolicValue dest, ArgList lengths, Data data) where ArgList : IIndexable<SymbolicValue>
{
return this.visitor.NewArray (pc, type, dest, Convert (pc, lengths), data);
}
public Result NewObj<ArgList> (APC pc, Method ctor, SymbolicValue dest, ArgList args, Data data) where ArgList : IIndexable<SymbolicValue>
{
return this.visitor.NewObj (pc, ctor, dest, Convert (pc, args), data);
}
public Result MkRefAny (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue obj, Data data)
{
return this.visitor.MkRefAny (pc, type, dest, Convert (pc, obj), data);
}
public Result RefAnyType (APC pc, SymbolicValue dest, SymbolicValue source, Data data)
{
return this.visitor.RefAnyType (pc, dest, Convert (pc, source), data);
}
public Result RefAnyVal (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue source, Data data)
{
return this.visitor.RefAnyVal (pc, type, dest, Convert (pc, source), data);
}
public Result Rethrow (APC pc, Data data)
{
return this.visitor.Rethrow (pc, data);
}
public Result StoreElement (APC pc, TypeNode type, SymbolicValue array, SymbolicValue index, SymbolicValue value, Data data)
{
return this.visitor.StoreElement (pc, type, Convert (pc, array), Convert (pc, index), Convert (pc, value), data);
}
public Result StoreField (APC pc, Field field, SymbolicValue obj, SymbolicValue value, Data data)
{
return this.visitor.StoreField (pc, field, Convert (pc, obj), Convert (pc, value), data);
}
public Result StoreStaticField (APC pc, Field field, SymbolicValue value, Data data)
{
return this.visitor.StoreStaticField (pc, field, Convert (pc, value), data);
}
public Result Throw (APC pc, SymbolicValue exception, Data data)
{
return this.visitor.Throw (pc, Convert (pc, exception), data);
}
public Result Unbox (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue obj, Data data)
{
return this.visitor.Unbox (pc, type, dest, Convert (pc, obj), data);
}
public Result UnboxAny (APC pc, TypeNode type, SymbolicValue dest, SymbolicValue obj, Data data)
{
return this.visitor.UnboxAny (pc, type, dest, Convert (pc, obj), data);
}
#endregion
private static LabeledSymbol<APC, SymbolicValue> Convert (APC pc, SymbolicValue value)
{
return new LabeledSymbol<APC, SymbolicValue> (pc, value);
}
private static ArgumentWrapper<ArgList> Convert<ArgList> (APC pc, ArgList value)
where ArgList : IIndexable<SymbolicValue>
{
return new ArgumentWrapper<ArgList> (value, pc);
}
#region Nested type: ArgumentWrapper
private struct ArgumentWrapper<ArgList> : IIndexable<LabeledSymbol<APC, SymbolicValue>>
where ArgList : IIndexable<SymbolicValue> {
private readonly APC readAt;
private readonly ArgList underlying;
public ArgumentWrapper (ArgList underlying, APC readAt)
{
this.underlying = underlying;
this.readAt = readAt;
}
#region Implementation of IIndexable<ExternalExpression<APC,SymbolicValue>>
public int Count
{
get { return this.underlying.Count; }
}
public LabeledSymbol<APC, SymbolicValue> this [int index]
{
get { return new LabeledSymbol<APC, SymbolicValue> (this.readAt, this.underlying [index]); }
}
#endregion
}
#endregion
}
}

View File

@@ -0,0 +1,150 @@
//
// 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<SymbolicValue, Context, EdgeData> : IAnalysis<APC, ExprDomain<SymbolicValue>,
IILVisitor<APC, SymbolicValue, SymbolicValue, ExprDomain<SymbolicValue>, ExprDomain<SymbolicValue>>, EdgeData>
where SymbolicValue : IEquatable<SymbolicValue>
where Context : IValueContextProvider<SymbolicValue>
where EdgeData : IImmutableMap<SymbolicValue, Sequence<SymbolicValue>> {
private readonly ExpressionAnalysisFacade<SymbolicValue, Context, EdgeData> parent;
public ValueAnalysis (ExpressionAnalysisFacade<SymbolicValue, Context, EdgeData> parent)
{
this.parent = parent;
}
#region Implementation of IAnalysis<APC,ExpressionAnalysis<Local,Parameter,Method,Field,Property,Event,Type,Attribute,Assembly,SymbolicValue,contextProvider,EdgeData>.Domain,IILVisitor<APC,Local,Parameter,Method,Field,Type,SymbolicValue,SymbolicValue,ExpressionAnalysis<Local,Parameter,Method,Field,Property,Event,Type,Attribute,Assembly,SymbolicValue,contextProvider,EdgeData>.Domain,ExpressionAnalysis<Local,Parameter,Method,Field,Property,Event,Type,Attribute,Assembly,SymbolicValue,contextProvider,EdgeData>.Domain>,EdgeData>
public ExprDomain<SymbolicValue> EdgeConversion (APC @from, APC to, bool isJoinPoint, EdgeData sourceTargetMap, ExprDomain<SymbolicValue> originalState)
{
if (sourceTargetMap == null)
return originalState;
if (DebugOptions.Debug)
{
Console.WriteLine ("====Expression analysis Parallel assign====");
DumpMap (sourceTargetMap);
DumpExpressions ("original expressions", originalState);
}
ExprDomain<SymbolicValue> result = originalState.Empty ();
ExprDomain<SymbolicValue> domain = originalState.Empty ();
foreach (SymbolicValue sv in originalState.Keys) {
Expr<SymbolicValue> expression = originalState [sv].Value.Substitute (sourceTargetMap);
if (expression != null)
domain = domain.Add (sv, expression);
}
foreach (SymbolicValue sv in sourceTargetMap.Keys) {
FlatDomain<Expr<SymbolicValue>> expressionDomain = domain [sv];
if (expressionDomain.IsNormal()) {
Expr<SymbolicValue> 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<APC, SymbolicValue, SymbolicValue, ExprDomain<SymbolicValue>, ExprDomain<SymbolicValue>> GetVisitor ()
{
return new AnalysisDecoder<SymbolicValue> ();
}
public ExprDomain<SymbolicValue> Join (Pair<APC, APC> edge, ExprDomain<SymbolicValue> newstate, ExprDomain<SymbolicValue> prevstate, out bool weaker, bool widen)
{
return prevstate.Join (newstate, widen, out weaker);
}
public ExprDomain<SymbolicValue> ImmutableVersion (ExprDomain<SymbolicValue> arg)
{
return arg;
}
public ExprDomain<SymbolicValue> MutableVersion (ExprDomain<SymbolicValue> arg)
{
return arg;
}
public bool IsBottom (APC pc, ExprDomain<SymbolicValue> state)
{
return state.IsBottom;
}
public Predicate<APC> SaveFixPointInfo (IFixPointInfo<APC, ExprDomain<SymbolicValue>> fixPointInfo)
{
this.parent.SaveFixPointInfo (fixPointInfo);
return pc => true;
}
public void Dump (Pair<ExprDomain<SymbolicValue>, TextWriter> pair)
{
pair.Key.Dump (pair.Value);
}
private void DumpMap (IImmutableMap<SymbolicValue, Sequence<SymbolicValue>> 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<SymbolicValue> state)
{
Console.WriteLine ("--- {0} ---", header);
foreach (SymbolicValue index in state.Keys) {
FlatDomain<Expr<SymbolicValue>> 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
}
}