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,179 @@
//
// AbstractType.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.IO;
using Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.Lattices;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
struct AbstractType : IAbstractDomainForEGraph<AbstractType>, IEquatable<AbstractType> {
public static AbstractType TopValue = new AbstractType (FlatDomain<TypeNode>.TopValue, false);
public static AbstractType BottomValue = new AbstractType (FlatDomain<TypeNode>.BottomValue, true);
private FlatDomain<TypeNode> value;
public AbstractType (FlatDomain<TypeNode> value, bool isZero) : this ()
{
IsZero = isZero;
this.value = value;
}
public bool IsZero { get; private set; }
public FlatDomain<TypeNode> Type
{
get { return this.value; }
}
public TypeNode ConcreteType
{
get { return this.value.Value; }
}
private static AbstractType ForManifestedFieldValue
{
get { return TopValue; }
}
public AbstractType ButZero
{
get { return new AbstractType (this.value, true); }
}
public AbstractType With (FlatDomain<TypeNode> type)
{
return new AbstractType (type, this.IsZero);
}
#region IAbstractDomainForEGraph<AbstractType> Members
public AbstractType Top
{
get { return new AbstractType (FlatDomain<TypeNode>.TopValue, false); }
}
public AbstractType Bottom
{
get { return new AbstractType (FlatDomain<TypeNode>.BottomValue, true); }
}
public bool IsTop
{
get { return !IsZero && this.value.IsTop; }
}
public bool IsBottom
{
get { return IsZero && this.value.IsBottom; }
}
public AbstractType Join(AbstractType that)
{
throw new NotImplementedException();
}
public AbstractType Join (AbstractType that, bool widening, out bool weaker)
{
if (that.IsZero) {
weaker = false;
if (this.value.IsBottom)
return new AbstractType (that.value, IsZero);
return this;
}
if (IsZero) {
weaker = true;
if (that.value.IsBottom)
return new AbstractType (this.value, that.IsZero);
return that;
}
FlatDomain<TypeNode> resultType = this.value.Join (that.value, widening, out weaker);
return new AbstractType (resultType, false);
}
public AbstractType Widen(AbstractType that)
{
throw new NotImplementedException();
}
public AbstractType Meet (AbstractType that)
{
return new AbstractType (this.value.Meet (that.value), IsZero || that.IsZero);
}
public bool LessEqual (AbstractType that)
{
if (IsZero)
return true;
if (that.IsZero)
return false;
return this.value.LessEqual (that.value);
}
public AbstractType ImmutableVersion ()
{
return this;
}
public AbstractType Clone ()
{
return this;
}
public void Dump (TextWriter tw)
{
if (IsZero)
tw.Write ("(Zero) ");
this.value.Dump (tw);
}
public bool HasAllBottomFields
{
get { return IsZero; }
}
public AbstractType ForManifestedField ()
{
return ForManifestedFieldValue;
}
#endregion
#region IEquatable<AbstractType> Members
public bool Equals (AbstractType that)
{
return this.IsZero == that.IsZero && this.value.Equals (that.value);
}
#endregion
public override string ToString ()
{
return (IsZero ? "(Zero) " : "") + this.value;
}
}
}

View File

@@ -0,0 +1,185 @@
//
// FunctionsTable.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.Collections.Generic;
using Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
class FunctionsTable
{
public readonly SymFunction BoxOperator;
public readonly SymFunction ElementAddress;
public readonly SymFunction Length;
public readonly SymFunction NeZero;
public readonly SymFunction NullValue;
public readonly SymFunction ObjectVersion;
public readonly SymFunction OldValueOf;
public readonly SymFunction ResultOfCall;
public readonly SymFunction ResultOfLoadElement;
public readonly SymFunction StructId;
public readonly SymFunction UnaryNot;
public readonly SymFunction ValueOf;
public readonly SymFunction VoidAddr;
public readonly SymFunction ZeroValue;
private readonly Dictionary<BinaryOperator, Wrapper<BinaryOperator>> binary_operators;
private readonly Dictionary<Field, Wrapper<Field>> fields;
private readonly Dictionary<Local, Wrapper<Local>> locals;
private readonly IMetaDataProvider meta_data_provider;
private readonly Dictionary<Method, Wrapper<Method>> method_pointers;
private readonly Dictionary<Parameter, Wrapper<Parameter>> parameters;
private readonly Dictionary<object, Wrapper<object>> program_constants;
private readonly Dictionary<Method, Wrapper<Method>> pseudo_fields;
private readonly Dictionary<string, Wrapper<string>> strings;
private readonly Dictionary<int, Wrapper<int>> temp;
private readonly Dictionary<UnaryOperator, Wrapper<UnaryOperator>> unary_operators;
private int id_gen;
public FunctionsTable(IMetaDataProvider metaDataProvider)
{
this.meta_data_provider = metaDataProvider;
this.locals = new Dictionary<Local, Wrapper<Local>> ();
this.parameters = new Dictionary<Parameter, Wrapper<Parameter>> ();
this.fields = new Dictionary<Field, Wrapper<Field>> ();
this.pseudo_fields = new Dictionary<Method, Wrapper<Method>> ();
this.temp = new Dictionary<int, Wrapper<int>> ();
this.strings = new Dictionary<string, Wrapper<string>> ();
this.program_constants = new Dictionary<object, Wrapper<object>> ();
this.method_pointers = new Dictionary<Method, Wrapper<Method>> ();
this.binary_operators = new Dictionary<BinaryOperator, Wrapper<BinaryOperator>> ();
this.unary_operators = new Dictionary<UnaryOperator, Wrapper<UnaryOperator>> ();
this.ValueOf = For ("$Value");
this.OldValueOf = For ("$OldValue");
this.StructId = For ("$StructId");
this.ObjectVersion = For ("$ObjectVersion");
this.NullValue = For ("$Null");
this.ElementAddress = For ("$ElementAddress");
this.Length = For ("$Length");
this.VoidAddr = For ("$VoidAddr");
this.UnaryNot = For ("$UnaryNot");
this.NeZero = For ("$NeZero");
this.BoxOperator = For ("$Box");
this.ResultOfCall = For ("$ResultOfCall");
this.ResultOfLoadElement = For ("$ResultOfLoadElement");
this.ZeroValue = ForConstant (0, this.meta_data_provider.System_Int32);
}
private Wrapper<T> For<T>(T key, Dictionary<T, Wrapper<T>> cache)
{
Wrapper<T> wrapper;
if (!cache.TryGetValue (key, out wrapper)) {
wrapper = SymFunction.For (key, ref this.id_gen, this.meta_data_provider);
cache.Add (key, wrapper);
}
return wrapper;
}
public SymFunction For(Local v)
{
return For (v, this.locals);
}
public SymFunction For(Parameter v)
{
return For (v, this.parameters);
}
public SymFunction For(Field v)
{
v = this.meta_data_provider.Unspecialized (v);
return For (v, this.fields);
}
public SymFunction For(Method v)
{
return For (v, this.pseudo_fields);
}
public SymFunction For(string v)
{
return For (v, this.strings);
}
public SymFunction For(int v)
{
return For (v, this.temp);
}
public SymFunction For(BinaryOperator v)
{
return For (v, this.binary_operators);
}
public SymFunction For(UnaryOperator v)
{
return For (v, this.unary_operators);
}
public SymFunction ForConstant(object constant, TypeNode type)
{
Wrapper<object> wrapper = For (constant, this.program_constants);
wrapper.Type = type;
return wrapper;
}
public SymFunction ForMethod(Method method, TypeNode type)
{
Wrapper<Method> wrapper = For (method, this.method_pointers);
wrapper.Type = type;
return wrapper;
}
public bool IsConstantOrMethod(SymFunction constant)
{
var wrapper = constant as Wrapper<object>;
if (wrapper != null && this.program_constants.ContainsKey (wrapper.Item))
return true;
var wrapper1 = constant as Wrapper<Method>;
if (wrapper1 != null && this.method_pointers.ContainsKey (wrapper1.Item))
return true;
return false;
}
public bool IsConstant(SymFunction c, out TypeNode type, out object value)
{
var wrapper = c as Wrapper<object>;
if (wrapper != null && this.program_constants.ContainsKey (wrapper.Item)) {
type = wrapper.Type;
value = wrapper.Item;
return true;
}
type = null;
value = null;
return false;
}
}
}

View File

@@ -0,0 +1,254 @@
//
// HeapAnalysis.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.AST;
using Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.Analysis.HeapAnalysis.SymbolicGraph;
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.HeapAnalysis {
class HeapAnalysis : IAnalysis<APC, Domain, IILVisitor<APC, int, int, Domain, Domain>, Dummy> {
private readonly Dictionary<Pair<APC, APC>, IImmutableMap<SymbolicValue, Sequence<SymbolicValue>>> forwardRenamings =
new Dictionary<Pair<APC, APC>, IImmutableMap<SymbolicValue, Sequence<SymbolicValue>>> ();
public readonly Dictionary<APC, IMergeInfo> MergeInfoCache = new Dictionary<APC, IMergeInfo> ();
public readonly DoubleDictionary<APC, APC, Dummy> RenamePoints = new DoubleDictionary<APC, APC, Dummy> ();
private readonly ICodeLayer<int, int, IStackContextProvider, Dummy> stackLayer;
private IFixPointInfo<APC, Domain> fixPointInfo;
public HeapAnalysis (ICodeLayer<int, int, IStackContextProvider, Dummy> stackLayer)
{
this.stackLayer = stackLayer;
}
public IStackContextProvider StackContextProvider
{
get { return this.stackLayer.ILDecoder.ContextProvider; }
}
public IMetaDataProvider MetaDataProvider
{
get { return this.stackLayer.MetaDataProvider; }
}
public IContractProvider ContractProvider
{
get { return this.stackLayer.ContractProvider; }
}
public Method CurrentMethod
{
get { return this.StackContextProvider.MethodContext.CurrentMethod; }
}
IILVisitor<APC, int, int, Domain, Domain> IAnalysis<APC, Domain, IILVisitor<APC, int, int, Domain, Domain>, Dummy>.
GetVisitor ()
{
return GetVisitor ();
}
public Domain Join (Pair<APC, APC> edge, Domain newstate, Domain prevstate, out bool weaker, bool widen)
{
if (DebugOptions.Debug)
{
Console.WriteLine ("-----OPT Join at {0}", edge);
Console.WriteLine ("-----Existing state:");
prevstate.Dump (Console.Out);
Console.WriteLine ("-----New state:");
newstate.Dump (Console.Out);
}
IMergeInfo mi;
Domain domain = prevstate.Join (newstate, widen, out weaker, out mi);
if (weaker) {
IMergeInfo mi2;
if (this.MergeInfoCache.TryGetValue (edge.Value, out mi2) && mi2 == null)
this.MergeInfoCache [edge.Value] = mi;
} else
this.MergeInfoCache [edge.Value] = mi;
if (DebugOptions.Debug)
{
Console.WriteLine ("-----Result state: changed = {0} (widen = {1})", weaker ? 1 : 0, widen ? 1 : 0);
domain.Dump (Console.Out);
Console.WriteLine ("----------------------------------------------");
}
return domain;
}
public Domain ImmutableVersion (Domain arg)
{
return arg.ImmutableVersion ();
}
public Domain MutableVersion (Domain arg)
{
if (arg.IsBottom)
return arg;
return arg.Clone ();
}
public Domain EdgeConversion (APC @from, APC to, bool isJoinPoint, Dummy data, Domain state)
{
if (isJoinPoint) {
this.RenamePoints [from, to] = Dummy.Value;
if (!this.MergeInfoCache.ContainsKey (to))
this.MergeInfoCache.Add (to, null);
}
if (DebugOptions.Debug)
{
Console.WriteLine ("----Edge conversion on {0}->{1}------", from, to);
state.Dump (Console.Out);
Console.WriteLine ("-------------------------------------");
}
return state;
}
public bool IsBottom (APC pc, Domain state)
{
return state.IsBottom;
}
public Predicate<APC> SaveFixPointInfo (IFixPointInfo<APC, Domain> fixPointInfo)
{
this.fixPointInfo = fixPointInfo;
return pc => true;
}
public void Dump (Pair<Domain, TextWriter> pair)
{
pair.Key.Dump (pair.Value);
}
private IILVisitor<APC, int, int, Domain, Domain> GetVisitor ()
{
return new AnalysisDecoder (this);
}
public Domain InitialValue ()
{
return new Domain (this);
}
public IILDecoder<APC, SymbolicValue, SymbolicValue, IValueContextProvider<SymbolicValue>, IImmutableMap<SymbolicValue, Sequence<SymbolicValue>>>
GetDecoder<Context>(IILDecoder<APC, int, int, Context, Dummy> underlying)
where Context : IStackContextProvider
{
return new ValueDecoder<Context> (this, underlying);
}
public bool IsUnreachable (APC pc)
{
Domain domain;
if (!this.fixPointInfo.PreStateLookup (pc, out domain) || domain.IsBottom)
return true;
return false;
}
public IImmutableMap<SymbolicValue, Sequence<SymbolicValue>> EdgeRenaming (Pair<APC, APC> edge, bool isJoinPoint)
{
IImmutableMap<SymbolicValue, Sequence<SymbolicValue>> forwardRenaming;
if (this.forwardRenamings.TryGetValue (edge, out forwardRenaming))
return forwardRenaming;
IImmutableMap<SymbolicValue, Sequence<SymbolicValue>> renaming = null;
Domain afterBegin;
PostStateLookup (edge.Key, out afterBegin);
if (afterBegin == null || afterBegin.IsBottom)
return null;
Domain beforeEnd;
PreStateLookup (edge.Value, out beforeEnd);
if (beforeEnd != null) {
IImmutableMap<SymValue, Sequence<SymValue>> forward;
if (!TryComputeFromJoinCache (afterBegin, beforeEnd, edge.Value, out forward)) {
IImmutableMap<SymValue, SymValue> backward;
if (!afterBegin.LessEqual (beforeEnd, out forward, out backward))
throw new InvalidOperationException ("Should never happen");
if (isJoinPoint && forward == null)
forward = afterBegin.GetForwardIdentityMap ();
}
if (forward != null) {
renaming = ImmutableIntKeyMap<SymbolicValue, Sequence<SymbolicValue>>.Empty (SymbolicValue.GetUniqueKey);
foreach (SymValue sv in forward.Keys) {
Sequence<SymbolicValue> targets = null;
foreach (SymValue target in forward [sv].AsEnumerable ())
targets = targets.Cons (new SymbolicValue (target));
if (targets != null)
renaming = renaming.Add (new SymbolicValue (sv), targets);
}
}
}
this.forwardRenamings.Add (edge, renaming);
return renaming;
}
private bool TryComputeFromJoinCache (Domain inDomain, Domain outDomain, APC joinPoint, out IImmutableMap<SymValue, Sequence<SymValue>> forward)
{
forward = null;
IMergeInfo mi;
if (this.MergeInfoCache.TryGetValue (joinPoint, out mi) && mi != null && outDomain.IsResultEGraph (mi)) {
if (inDomain.IsGraph1 (mi)) {
forward = mi.ForwardG1Map;
return true;
}
if (inDomain.IsGraph2 (mi)) {
forward = mi.ForwardG2Map;
return true;
}
}
return false;
}
public Domain GetPreState (APC pc)
{
Domain domain;
PreStateLookup (pc, out domain);
return domain;
}
public bool PreStateLookup (APC pc, out Domain ifFound)
{
return this.fixPointInfo.PreStateLookup (pc, out ifFound);
}
public bool PostStateLookup (APC pc, out Domain ifFound)
{
return this.fixPointInfo.PostStateLookup (pc, out ifFound);
}
}
}

View File

@@ -0,0 +1,35 @@
//
// IAbstractDomainForEGraph.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 Mono.CodeContracts.Static.Lattices;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
interface IAbstractDomainForEGraph<TADomain> : IAbstractDomain<TADomain> {
bool HasAllBottomFields { get; }
TADomain ForManifestedField ();
}
}

View File

@@ -0,0 +1,33 @@
//
// IConstantInfo.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.
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
interface IConstantInfo {
bool KeepAsBottomField { get; }
bool ManifestField { get; }
}
}

View File

@@ -0,0 +1,63 @@
//
// ISymGraph.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.Analysis.HeapAnalysis.SymbolicGraph;
using Mono.CodeContracts.Static.DataStructures;
using Mono.CodeContracts.Static.Lattices;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
interface ISymGraph<TFunc, TADomain, TGraph> : IAbstractDomain<TGraph>
where TFunc : IEquatable<TFunc>, IConstantInfo
where TADomain : IAbstractDomainForEGraph<TADomain> {
SymValue this [TFunc function, SymValue arg] { get; set; }
SymValue this [TFunc function] { get; set; }
TADomain this [SymValue symbol] { get; set; }
IEnumerable<TFunc> Constants { get; }
IEnumerable<SymValue> Variables { get; }
SymValue FreshSymbol ();
SymValue TryLookup (TFunc function, SymValue arg);
SymValue TryLookup (TFunc function);
IEnumerable<TFunc> Functions (SymValue symbol);
IEnumerable<SymGraphTerm<TFunc>> EqTerms (SymValue symbol);
void AssumeEqual (SymValue v1, SymValue v2);
bool IsEqual (SymValue v1, SymValue v2);
void Eliminate (TFunc function, SymValue arg);
void Eliminate (TFunc function);
void EliminateAll (SymValue arg);
TGraph Join (TGraph that, out IMergeInfo mergeInfo, bool widen);
bool LessEqual (TGraph that, out IImmutableMap<SymValue, Sequence<SymValue>> forward,
out IImmutableMap<SymValue, SymValue> backward);
}
}

View File

@@ -0,0 +1,64 @@
//
// LabeledSymbol.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;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
struct LabeledSymbol<Label, TSymValue> : IEquatable<LabeledSymbol<Label, TSymValue>>
where TSymValue : IEquatable<TSymValue> {
public readonly Label ReadAt;
public readonly TSymValue Symbol;
public LabeledSymbol (Label readAt, TSymValue symbol)
{
this.ReadAt = readAt;
this.Symbol = symbol;
}
#region Implementation of IEquatable<ExternalExpression<Label,SymbolicValue>>
public bool Equals (LabeledSymbol<Label, TSymValue> other)
{
return this.Symbol.Equals (other.Symbol);
}
#endregion
public override bool Equals (object obj)
{
return obj is LabeledSymbol<Label, TSymValue> && Equals ((LabeledSymbol<Label, TSymValue>) obj);
}
public override int GetHashCode ()
{
return this.Symbol.GetHashCode ();
}
public override string ToString ()
{
return string.Format ("{0}@{1}", this.Symbol, this.ReadAt);
}
}
}

View File

@@ -0,0 +1,48 @@
//
// MethodWrapper.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 Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
class MethodWrapper : Wrapper<Method> {
public MethodWrapper (Method value, ref int idGen, IMetaDataProvider metaDataProvider)
: base (value, ref idGen, metaDataProvider)
{
}
public override bool ActsAsField
{
get { return true; }
}
public override TypeNode FieldAddressType ()
{
return this.MetaDataProvider.ManagedPointer (this.MetaDataProvider.ReturnType (this.Item));
}
}
}

View File

@@ -0,0 +1,72 @@
//
// ParameterWrapper.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.Providers;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
class ParameterWrapper : Wrapper<Parameter>
{
private readonly int parameter_index;
public ParameterWrapper(Parameter parameter, ref int idGen, IMetaDataProvider metaDataProvider)
: base (parameter, ref idGen, metaDataProvider)
{
this.parameter_index = metaDataProvider.ParameterIndex (parameter);
}
public override bool ActsAsField
{
get { return false; }
}
public override TypeNode FieldAddressType()
{
throw new InvalidOperationException ();
}
public override string ToString()
{
return this.MetaDataProvider.Name (this.Item);
}
public override bool Equals(object obj)
{
var other = obj as ParameterWrapper;
if (other == null)
return false;
return other.parameter_index == this.parameter_index;
}
public override int GetHashCode()
{
return this.parameter_index;
}
}
}

View File

@@ -0,0 +1,78 @@
//
// SymFunction.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.Analysis.HeapAnalysis.Paths;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
abstract class SymFunction : IConstantInfo, IEquatable<SymFunction>, IVisibilityCheck<Method> {
protected readonly IMetaDataProvider MetaDataProvider;
protected SymFunction (ref int idGen, IMetaDataProvider metaDataProvider)
{
this.MetaDataProvider = metaDataProvider;
idGen++;
}
public abstract bool ActsAsField { get; }
public abstract bool IsVirtualMethod { get; }
public abstract bool IsStatic { get; }
#region IConstantInfo Members
public abstract bool KeepAsBottomField { get; }
public abstract bool ManifestField { get; }
#endregion
#region IVisibilityCheck<Method> Members
public abstract bool IfRootIsParameter { get; }
public abstract bool IsAsVisibleAs (Method member);
public abstract bool IsVisibleFrom (Method member);
#endregion
public abstract TypeNode FieldAddressType ();
public abstract PathElementBase ToPathElement (bool tryCompact);
public static Wrapper<T> For<T> (T value, ref int idGen, IMetaDataProvider metadataDecoder)
{
if (value is Parameter)
return (Wrapper<T>) (object) new ParameterWrapper ((Parameter) (object) value, ref idGen, metadataDecoder);
if (value is Method)
return (Wrapper<T>) (object) new MethodWrapper ((Method) (object) value, ref idGen, metadataDecoder);
return new Wrapper<T> (value, ref idGen, metadataDecoder);
}
#region Implementation of IEquatable<HeapAnalysis<Local,Parameter,Method,Field,Property,Event,Type,Attribute,Assembly>.Domain.SymFunction>
public bool Equals (SymFunction other)
{
return ReferenceEquals (this, other);
}
#endregion
}
}

View File

@@ -0,0 +1,79 @@
//
// SymValue.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;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
sealed class SymValue : IEquatable<SymValue>, IComparable<SymValue>, IComparable {
private static int _globalIdGenerator;
public readonly int UniqueId;
public readonly int GlobalId;
public SymValue (int uniqueId)
{
this.UniqueId = uniqueId;
this.GlobalId = ++_globalIdGenerator;
}
#region IComparable Members
public int CompareTo (object obj)
{
var that = obj as SymValue;
if (that == null)
return 1;
return CompareTo (that);
}
#endregion
#region Implementation of IEquatable<SymValue>
public bool Equals (SymValue other)
{
return this == other;
}
#endregion
#region IComparable<SymValue> Members
public int CompareTo (SymValue other)
{
return this.UniqueId - other.UniqueId;
}
#endregion
public static int GetUniqueKey (SymValue sv)
{
return sv == null ? 0 : sv.GlobalId;
}
public override string ToString ()
{
return string.Format ("sv{0} ({1})", this.UniqueId, this.GlobalId);
}
}
}

View File

@@ -0,0 +1,99 @@
//
// SymbolicValue.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;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
struct SymbolicValue : IEquatable<SymbolicValue>, IComparable<SymbolicValue>, IComparable {
public readonly SymValue Symbol;
public SymbolicValue (SymValue symbol)
{
this.Symbol = symbol;
}
public bool IsNull
{
get { return this.Symbol == null; }
}
public int MethodLocalId
{
get { return this.Symbol.UniqueId; }
}
#region Implementation of IEquatable<SymbolicValue>
public bool Equals (SymbolicValue other)
{
return this.Symbol == other.Symbol;
}
#endregion
#region Implementation of IComparable<in SymbolicValue>
public int CompareTo (SymbolicValue other)
{
return this.Symbol.CompareTo (other.Symbol);
}
#endregion
#region Implementation of IComparable
public int CompareTo (object obj)
{
if (!(obj is SymbolicValue))
return 1;
return CompareTo ((SymbolicValue) obj);
}
#endregion
public override bool Equals (object obj)
{
if (obj is SymbolicValue)
return Equals ((SymbolicValue) obj);
return false;
}
public override int GetHashCode ()
{
return this.Symbol == null ? 0 : this.Symbol.GetHashCode ();
}
public override string ToString ()
{
if (this.Symbol == null)
return "<!null!>";
return this.Symbol.ToString ();
}
public static int GetUniqueKey (SymbolicValue arg)
{
return SymValue.GetUniqueKey (arg.Symbol);
}
}
}

View File

@@ -0,0 +1,57 @@
//
// TypeCache.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 Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
struct TypeCache {
private readonly string full_name;
private TypeNode cache;
private bool cache_is_valid;
private bool have_type;
public TypeCache (string fullName)
{
this.cache_is_valid = false;
this.have_type = false;
this.cache = default(TypeNode);
this.full_name = fullName;
}
public bool TryGet (IMetaDataProvider mdProvider, out TypeNode type)
{
if (!this.cache_is_valid) {
this.cache_is_valid = true;
this.have_type = mdProvider.TryGetSystemType (this.full_name, out this.cache);
}
type = this.cache;
return this.have_type;
}
}
}

View File

@@ -0,0 +1,184 @@
//
// ValueContextProvider.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.Linq;
using Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.Analysis.HeapAnalysis.Paths;
using Mono.CodeContracts.Static.ControlFlow;
using Mono.CodeContracts.Static.DataStructures;
using Mono.CodeContracts.Static.Lattices;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
class ValueContextProvider<TContext> : IValueContextProvider<SymbolicValue>, IValueContext<SymbolicValue>
where TContext : IStackContextProvider {
private readonly HeapAnalysis parent;
private readonly TContext underlying;
public ValueContextProvider (HeapAnalysis parent, TContext underlying)
{
this.parent = parent;
this.underlying = underlying;
}
#region Implementation of IMethodContextProvider
public IMethodContext MethodContext
{
get { return this.underlying.MethodContext; }
}
#endregion
#region Implementation of IStackContextProvider
public IStackContext StackContext
{
get { return this.underlying.StackContext; }
}
#endregion
#region Implementation of IValueContextProvider<SymbolicValue>
IValueContext<SymbolicValue> IValueContextProvider<SymbolicValue>.ValueContext
{
get { return this; }
}
#endregion
#region Implementation of IValueContext<SymbolicValue>
public FlatDomain<TypeNode> GetType (APC pc, SymbolicValue value)
{
Domain domain;
if (!this.parent.PreStateLookup (pc, out domain) || domain.IsBottom)
return FlatDomain<TypeNode>.TopValue;
return domain.GetType (value.Symbol).Type;
}
public bool IsZero (APC at, SymbolicValue value)
{
Domain domain;
if (!this.parent.PreStateLookup (at, out domain))
return true;
return domain.IsZero (value.Symbol);
}
public bool TryLocalValue (APC at, Local local, out SymbolicValue sv)
{
Domain domain;
if (this.parent.PreStateLookup (at, out domain))
return domain.TryGetCorrespondingValueAbstraction (local, out sv);
sv = new SymbolicValue ();
return false;
}
public bool TryParameterValue (APC at, Parameter p, out SymbolicValue sv)
{
Domain domain;
if (this.parent.PreStateLookup (at, out domain))
return domain.TryGetCorrespondingValueAbstraction (p, out sv);
sv = new SymbolicValue ();
return false;
}
public bool TryGetArrayLength (APC at, SymbolicValue array, out SymbolicValue length)
{
Domain domain;
if (!this.parent.PreStateLookup (at, out domain))
throw new ArgumentException ("pc wasn't visited");
SymValue lengthValue;
bool arrayLength = domain.TryGetArrayLength (array.Symbol, out lengthValue);
length = new SymbolicValue (lengthValue);
return arrayLength;
}
public Sequence<PathElement> AccessPathList (APC at, SymbolicValue sv, bool allowLocal, bool preferLocal)
{
Domain domain;
if (!this.parent.PreStateLookup (at, out domain))
throw new ArgumentException ("pc wasn't visited");
AccessPathFilter<Method> filter = AccessPathFilter<Method>.IsVisibleFrom (MethodContext.CurrentMethod);
return domain.GetAccessPathList (sv.Symbol, filter, allowLocal, preferLocal);
}
public bool IsConstant (APC at, SymbolicValue symbol, out TypeNode type, out object constant)
{
Domain domain;
if (!this.parent.PreStateLookup (at, out domain))
throw new ArgumentException ("pc wasn't visited");
return domain.IsConstant (symbol.Symbol, out type, out constant);
}
public bool TryStackValue (APC at, int stackIndex, out SymbolicValue sv)
{
Domain domain;
if (this.parent.PreStateLookup (at, out domain))
return domain.TryGetCorrespondingValueAbstraction (stackIndex, out sv);
sv = new SymbolicValue ();
return false;
}
public bool IsValid (SymbolicValue sv)
{
return sv.Symbol != null;
}
public string AccessPath (APC at, SymbolicValue sv)
{
Domain domain;
if (!this.parent.PreStateLookup (at, out domain))
throw new ArgumentException ("pc wasn't visited");
return domain.GetAccessPath (sv.Symbol);
}
public IEnumerable<Sequence<PathElement>> AccessPaths (APC at, SymValue value, AccessPathFilter<Method> filter)
{
Domain domain;
if (!this.parent.PreStateLookup (at, out domain))
throw new ArgumentException ("pc wasn't visited");
return domain.GetAccessPathsFiltered (value, filter, true).Select (path => path.Coerce<PathElementBase, PathElement> ());
}
public Sequence<PathElement> VisibleAccessPathList (APC at, SymbolicValue value)
{
Domain domain;
if (!this.parent.PreStateLookup (at, out domain))
throw new ArgumentException ("pc wasn't visited");
AccessPathFilter<Method> filter = AccessPathFilter<Method>.FromPrecondition (MethodContext.CurrentMethod);
return domain.GetAccessPathList (value.Symbol, filter, false, false);
}
#endregion
}
}

View File

@@ -0,0 +1,91 @@
//
// ValueDecoder.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.IO;
using Mono.CodeContracts.Static.AST.Visitors;
using Mono.CodeContracts.Static.ControlFlow;
using Mono.CodeContracts.Static.DataStructures;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
class ValueDecoder<TContext> :
IILDecoder<APC, SymbolicValue, SymbolicValue, IValueContextProvider<SymbolicValue>, IImmutableMap<SymbolicValue, Sequence<SymbolicValue>>>
where TContext : IStackContextProvider
{
private readonly HeapAnalysis parent;
private readonly IILDecoder<APC, int, int, TContext, Dummy> stack_decoder;
private readonly Lazy<IValueContextProvider<SymbolicValue>> context;
public ValueDecoder(HeapAnalysis parent, IILDecoder<APC, int, int, TContext, Dummy> stackDecoder)
{
this.context = new Lazy<IValueContextProvider<SymbolicValue>> (()=> new ValueContextProvider<TContext>(this.parent, this.stack_decoder.ContextProvider));
this.parent = parent;
this.stack_decoder = stackDecoder;
}
#region Implementation of IILDecoder<APC,SymbolicValue,SymbolicValue,IValueContext<SymbolicValue>,IImmutableMap<SymbolicValue,Sequence<SymbolicValue>>>
public IValueContextProvider<SymbolicValue> ContextProvider { get { return context.Value; } }
public Result ForwardDecode<Data, Result, Visitor>(APC pc, Visitor visitor, Data state)
where Visitor : IILVisitor<APC, SymbolicValue, SymbolicValue, Data, Result>
{
return this.stack_decoder.ForwardDecode<Data, Result, StackToSymbolicAdapter<Data, Result, Visitor>>
(pc, new StackToSymbolicAdapter<Data, Result, Visitor> (this.parent, visitor), state);
}
public bool IsUnreachable(APC pc)
{
return this.parent.IsUnreachable (pc);
}
public IImmutableMap<SymbolicValue, Sequence<SymbolicValue>> EdgeData(APC from, APC to)
{
if (!this.parent.RenamePoints.ContainsKey(from, to))
return null;
if (this.parent.MergeInfoCache.ContainsKey(to) && this.parent.MergeInfoCache[to] == null)
return null;
return this.parent.EdgeRenaming (new Pair<APC, APC> (from, to), this.ContextProvider.MethodContext.CFG.IsJoinPoint (to));
}
public void Dump(TextWriter tw, string prefix, IImmutableMap<SymValue, Sequence<SymValue>> edgeData )
{
if (edgeData == null)
return;
edgeData.Visit ((key, targets) => {
tw.Write (" {0} -> ", key);
foreach (var target in targets.AsEnumerable ())
tw.Write ("{0} ", target);
tw.WriteLine ();
return VisitStatus.ContinueVisit;
});
}
#endregion
}
}

View File

@@ -0,0 +1,191 @@
//
// Wrapper.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.Analysis.HeapAnalysis.Paths;
using Mono.CodeContracts.Static.DataStructures;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
class Wrapper<T> : SymFunction {
public readonly T Item;
protected PathElementBase PathElement = null;
public Wrapper (T item, ref int idGen, IMetaDataProvider metaDataProvider)
: base (ref idGen, metaDataProvider)
{
this.Item = item;
}
#region Overrides of SymFunction
public override bool ActsAsField
{
get { return this.Item is Field; }
}
public override bool IsVirtualMethod
{
get { return this.Item is Method && this.MetaDataProvider.IsVirtual ((Method) (object) this.Item); }
}
public override bool KeepAsBottomField
{
get
{
var str = this.Item as string;
if (str == null)
return true;
return str != "$UnaryNot" && str != "$NeZero";
}
}
public override bool ManifestField
{
get
{
var str = this.Item as string;
if (str != null)
return str == "$Value" || str == "$Length";
return (this.Item is Field || this.Item is Method);
}
}
public override bool IsStatic
{
get
{
if (this.Item is Field)
return this.MetaDataProvider.IsStatic ((Field) (object) this.Item);
if (this.Item is Method)
return this.MetaDataProvider.IsStatic ((Method) (object) this.Item);
return false;
}
}
public override bool IfRootIsParameter
{
get
{
if (this.Item is Field)
return !this.MetaDataProvider.IsStatic ((Field) (object) this.Item);
if (this.Item is Method)
return !this.MetaDataProvider.IsStatic ((Method) (object) this.Item);
if (this.Item is Parameter)
return true;
if (this.Item is Local)
return false;
return true;
}
}
public override bool IsAsVisibleAs (Method method)
{
if (this.Item is Field)
return this.MetaDataProvider.IsAsVisibleAs ((Field) (object) this.Item, method);
if (this.Item is Method)
return this.MetaDataProvider.IsAsVisibleAs ((Method) (object) this.Item, method);
if (this.MetaDataProvider.IsConstructor (method) && this.Item is Parameter
&& this.MetaDataProvider.Name ((Parameter) (object) this.Item) == "this")
return false;
return true;
}
public override bool IsVisibleFrom (Method method)
{
TypeNode declaringType = this.MetaDataProvider.DeclaringType (method);
if (this.Item is Field) {
var f = ((Field) (object) this.Item);
return this.MetaDataProvider.IsVisibleFrom (f, declaringType);
}
if (this.Item is Method)
this.MetaDataProvider.IsVisibleFrom ((Method) (object) this.Item, declaringType);
if (this.Item is Parameter)
this.MetaDataProvider.Equal (this.MetaDataProvider.DeclaringMethod ((Parameter) (object) this.Item), method);
if (this.Item is Local) {
var local = (Local) (object) this.Item;
IIndexable<Local> locals = this.MetaDataProvider.Locals (method);
for (int i = 0; i < locals.Count; i++) {
if (locals [i].Equals (local))
return true;
}
return false;
}
return true;
}
public override TypeNode FieldAddressType ()
{
if (this.Item is Field)
return this.MetaDataProvider.ManagedPointer (this.MetaDataProvider.FieldType ((Field) (object) this.Item));
throw new InvalidOperationException ();
}
public override PathElementBase ToPathElement (bool tryCompact)
{
throw new NotImplementedException ();
}
#endregion
public TypeNode Type { get; set; }
public override string ToString ()
{
if (typeof (T).Equals (typeof (int)))
return String.Format ("s{0}", this.Item);
if (this.Item is Field) {
var field = (Field) (object) this.Item;
if (this.MetaDataProvider.IsStatic (field)) {
return String.Format ("{0}.{1}",
this.MetaDataProvider.FullName (this.MetaDataProvider.DeclaringType (field)),
this.MetaDataProvider.Name (field));
}
return this.MetaDataProvider.Name (field);
}
if (this.Item is Method) {
var method = (Method) (object) this.Item;
if (this.MetaDataProvider.IsStatic (method)) {
return String.Format ("{0}.{1}",
this.MetaDataProvider.FullName (this.MetaDataProvider.DeclaringType (method)),
this.MetaDataProvider.Name (method));
}
return this.MetaDataProvider.Name (method);
}
return this.Item.ToString ();
}
}
}