Browse Source

StateRange analysis / SymbolicExecution: add support for implicit int->bool conversion.

This is necessary for yield return decompilation on Roslyn.
pull/469/merge
Daniel Grunwald 12 years ago
parent
commit
b71edb2a88
  1. 2
      ICSharpCode.Decompiler/ILAst/StateRange.cs
  2. 15
      ICSharpCode.Decompiler/ILAst/SymbolicExecution.cs

2
ICSharpCode.Decompiler/ILAst/StateRange.cs

@ -213,7 +213,7 @@ namespace ICSharpCode.Decompiler.ILAst
break; break;
case ILCode.Brtrue: case ILCode.Brtrue:
{ {
SymbolicValue val = evalContext.Eval(expr.Arguments[0]); SymbolicValue val = evalContext.Eval(expr.Arguments[0]).AsBool();
if (val.Type == SymbolicValueType.StateEquals) { if (val.Type == SymbolicValueType.StateEquals) {
ranges[(ILLabel)expr.Operand].UnionWith(nodeRange, val.Constant, val.Constant); ranges[(ILLabel)expr.Operand].UnionWith(nodeRange, val.Constant, val.Constant);
StateRange nextRange = ranges[body[i + 1]]; StateRange nextRange = ranges[body[i + 1]];

15
ICSharpCode.Decompiler/ILAst/SymbolicExecution.cs

@ -67,7 +67,16 @@ namespace ICSharpCode.Decompiler.ILAst
this.Type = type; this.Type = type;
this.Constant = constant; this.Constant = constant;
} }
public SymbolicValue AsBool()
{
if (Type == SymbolicValueType.State) {
// convert state integer to bool:
// if (state + c) = if (state + c != 0) = if (state != -c)
return new SymbolicValue(SymbolicValueType.StateInEquals, unchecked(-Constant));
}
return this;
}
public override string ToString() public override string ToString()
{ {
return string.Format("[SymbolicValue {0}: {1}]", this.Type, this.Constant); return string.Format("[SymbolicValue {0}: {1}]", this.Type, this.Constant);
@ -133,7 +142,7 @@ namespace ICSharpCode.Decompiler.ILAst
// bool: (state == right.Constant - left.Constant) // bool: (state == right.Constant - left.Constant)
return new SymbolicValue(expr.Code == ILCode.Ceq ? SymbolicValueType.StateEquals : SymbolicValueType.StateInEquals, unchecked(right.Constant - left.Constant)); return new SymbolicValue(expr.Code == ILCode.Ceq ? SymbolicValueType.StateEquals : SymbolicValueType.StateInEquals, unchecked(right.Constant - left.Constant));
case ILCode.LogicNot: case ILCode.LogicNot:
SymbolicValue val = Eval(expr.Arguments[0]); SymbolicValue val = Eval(expr.Arguments[0]).AsBool();
if (val.Type == SymbolicValueType.StateEquals) if (val.Type == SymbolicValueType.StateEquals)
return new SymbolicValue(SymbolicValueType.StateInEquals, val.Constant); return new SymbolicValue(SymbolicValueType.StateInEquals, val.Constant);
else if (val.Type == SymbolicValueType.StateInEquals) else if (val.Type == SymbolicValueType.StateInEquals)
@ -141,7 +150,7 @@ namespace ICSharpCode.Decompiler.ILAst
else else
return Failed(); return Failed();
default: default:
return Failed(); return Failed();
} }
} }
} }

Loading…
Cancel
Save