Browse Source

Fix #202: Decompilation of multiple catch clauses sharing the same variable name

pull/182/merge
Daniel Grunwald 15 years ago
parent
commit
f1a34c6a31
  1. 27
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  2. 4
      ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs
  3. 20
      ICSharpCode.Decompiler/Tests/ExceptionHandling.cs

27
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -575,16 +575,35 @@ namespace ICSharpCode.Decompiler.ILAst @@ -575,16 +575,35 @@ namespace ICSharpCode.Decompiler.ILAst
// This ensures that a single IL variable is a single C# variable (gets assigned only one name)
// The DeclareVariables transformation might then split up the C# variable again if it is used indendently in two separate scopes.
Dictionary<VariableDefinition, ILVariable> dict = new Dictionary<VariableDefinition, ILVariable>();
foreach (ILExpression expr in method.GetSelfAndChildrenRecursive<ILExpression>()) {
ILVariable v = expr.Operand as ILVariable;
if (v != null && v.OriginalVariable != null) {
ReplaceVariables(
method,
delegate(ILVariable v) {
ILVariable combinedVariable;
if (!dict.TryGetValue(v.OriginalVariable, out combinedVariable)) {
dict.Add(v.OriginalVariable, v);
combinedVariable = v;
}
expr.Operand = combinedVariable;
return combinedVariable;
});
}
public static void ReplaceVariables(ILNode node, Func<ILVariable, ILVariable> variableMapping)
{
ILExpression expr = node as ILExpression;
if (expr != null) {
ILVariable v = expr.Operand as ILVariable;
if (v != null)
expr.Operand = variableMapping(v);
foreach (ILExpression child in expr.Arguments)
ReplaceVariables(child, variableMapping);
} else {
var catchBlock = node as ILTryCatchBlock.CatchBlock;
if (catchBlock != null && catchBlock.ExceptionVariable != null) {
catchBlock.ExceptionVariable = variableMapping(catchBlock.ExceptionVariable);
}
foreach (ILNode child in node.GetChildren())
ReplaceVariables(child, variableMapping);
}
}

4
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -523,8 +523,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -523,8 +523,8 @@ namespace ICSharpCode.Decompiler.ILAst
if (recombineVariable) {
// Split local variable, unsplit these two instances
foreach (var ilExpression in method.GetSelfAndChildrenRecursive<ILExpression>(expression => expression.Operand == nextExpr.Operand))
ilExpression.Operand = exprInit.Operand;
// replace nextExpr.Operand with exprInit.Operand
ReplaceVariables(method, oldVar => oldVar == nextExpr.Operand ? (ILVariable)exprInit.Operand : oldVar);
}
switch (loadInstruction) {

20
ICSharpCode.Decompiler/Tests/ExceptionHandling.cs

@ -105,4 +105,24 @@ public class ExceptionHandling @@ -105,4 +105,24 @@ public class ExceptionHandling
cancellationTokenSource = new CancellationTokenSource();
}
}
public void TwoCatchBlocksWithSameVariable()
{
try
{
Console.WriteLine("Try1");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
try
{
Console.WriteLine("Try2");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

Loading…
Cancel
Save