Browse Source

Bugfix: Crash in type analysis when trying to infer the type of an arg_*-variable that was consumed by a pop instruction.

pull/37/head
Daniel Grunwald 15 years ago
parent
commit
bf7fe3f33c
  1. 10
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

10
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -36,13 +36,14 @@ namespace Decompiler
ILBlock method; ILBlock method;
ModuleDefinition module; ModuleDefinition module;
List<ILExpression> storedToGeneratedVariables = new List<ILExpression>(); List<ILExpression> storedToGeneratedVariables = new List<ILExpression>();
HashSet<ILVariable> inferredVariables = new HashSet<ILVariable>();
void InferTypes(ILNode node) void InferTypes(ILNode node)
{ {
ILExpression expr = node as ILExpression; ILExpression expr = node as ILExpression;
if (expr != null) { if (expr != null) {
ILVariable v = expr.Operand as ILVariable; ILVariable v = expr.Operand as ILVariable;
if (v != null && v.IsGenerated && v.Type == null && expr.Code == ILCode.Stloc && HasSingleLoad(v)) { if (v != null && v.IsGenerated && v.Type == null && expr.Code == ILCode.Stloc && !inferredVariables.Contains(v) && HasSingleLoad(v)) {
// Don't deal with this node or its children yet, // Don't deal with this node or its children yet,
// wait for the expected type to be inferred first. // wait for the expected type to be inferred first.
// This happens with the arg_... variables introduced by the ILAst - we skip inferring the whole statement, // This happens with the arg_... variables introduced by the ILAst - we skip inferring the whole statement,
@ -132,8 +133,13 @@ namespace Decompiler
case Code.Ldloc: case Code.Ldloc:
{ {
ILVariable v = (ILVariable)expr.Operand; ILVariable v = (ILVariable)expr.Operand;
if (v.Type == null) if (v.Type == null) {
v.Type = expectedType; v.Type = expectedType;
// Mark the variable as inferred. This is necessary because expectedType might be null
// (e.g. the only use of an arg_*-Variable is a pop statement),
// so we can't tell from v.Type whether it was already inferred.
inferredVariables.Add(v);
}
return v.Type; return v.Type;
} }
case Code.Starg: case Code.Starg:

Loading…
Cancel
Save