Browse Source

Fix #1624: Stack type mismatch in expression trees.

pull/1633/head
Siegfried Pammer 6 years ago
parent
commit
87353aac5a
  1. 48
      ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

48
ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

@ -510,14 +510,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (arguments == null) if (arguments == null)
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
IMethod method = (IMethod)member; IMethod method = (IMethod)member;
Debug.Assert(arguments.Count == method.Parameters.Count); if (!ConvertCallArguments(arguments, method))
for (int i = 0; i < arguments.Count; i++) {
var expectedType = method.Parameters[i].Type;
var (argument, argumentType) = ConvertInstruction(arguments[i], expectedType);
if (argument == null)
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
arguments[i] = argument;
}
if (method.FullName == "System.Reflection.MethodInfo.CreateDelegate" && method.Parameters.Count == 2) { if (method.FullName == "System.Reflection.MethodInfo.CreateDelegate" && method.Parameters.Count == 2) {
if (!MatchGetMethodFromHandle(target, out var targetMethod)) if (!MatchGetMethodFromHandle(target, out var targetMethod))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
@ -562,6 +556,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
} }
bool ConvertCallArguments(IList<ILInstruction> arguments, IMethod method)
{
Debug.Assert(arguments.Count == method.Parameters.Count);
for (int i = 0; i < arguments.Count; i++) {
var expectedType = method.Parameters[i].Type;
var argument = ConvertInstruction(arguments[i], expectedType).Item1;
if (argument == null)
return false;
arguments[i] = argument;
}
return true;
}
(ILInstruction, IType) ConvertCast(CallInstruction invocation, bool isChecked) (ILInstruction, IType) ConvertCast(CallInstruction invocation, bool isChecked)
{ {
if (invocation.Arguments.Count < 2) if (invocation.Arguments.Count < 2)
@ -737,12 +744,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
if (!MatchArgumentList(invocation.Arguments[1], out var arguments)) if (!MatchArgumentList(invocation.Arguments[1], out var arguments))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
for (int i = 0; i < arguments.Count; i++) { if (!ConvertCallArguments(arguments, invokeMethod))
var arg = ConvertInstruction(arguments[i]).Item1;
if (arg == null)
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
arguments[i] = arg;
}
var call = new CallVirt(invokeMethod); var call = new CallVirt(invokeMethod);
call.Arguments.Add(target); call.Arguments.Add(target);
call.Arguments.AddRange(arguments); call.Arguments.AddRange(arguments);
@ -925,22 +928,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
if (!MatchArgumentList(invocation.Arguments[1], out arguments)) if (!MatchArgumentList(invocation.Arguments[1], out arguments))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
var args = arguments.SelectArray(arg => ConvertInstruction(arg).Item1); IMethod method = (IMethod)member;
if (args.Any(a => a == null)) if (!ConvertCallArguments(arguments, method))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
newObj = new NewObj((IMethod)member); newObj = new NewObj(method);
newObj.Arguments.AddRange(args); newObj.Arguments.AddRange(arguments);
return (newObj, member.DeclaringType); return (newObj, member.DeclaringType);
case 3: case 3:
if (!MatchGetConstructorFromHandle(invocation.Arguments[0], out member)) if (!MatchGetConstructorFromHandle(invocation.Arguments[0], out member))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
if (!MatchArgumentList(invocation.Arguments[1], out arguments)) if (!MatchArgumentList(invocation.Arguments[1], out arguments))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
var args2 = arguments.SelectArray(arg => ConvertInstruction(arg).Item1); method = (IMethod)member;
if (args2.Any(a => a == null)) if (!ConvertCallArguments(arguments, method))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
newObj = new NewObj((IMethod)member); newObj = new NewObj(method);
newObj.Arguments.AddRange(args2); newObj.Arguments.AddRange(arguments);
return (newObj, member.DeclaringType); return (newObj, member.DeclaringType);
} }
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
@ -984,12 +987,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (invocation.Arguments.Count != 3 || !MatchArgumentList(invocation.Arguments[2], out arguments)) { if (invocation.Arguments.Count != 3 || !MatchArgumentList(invocation.Arguments[2], out arguments)) {
arguments = new List<ILInstruction>(); arguments = new List<ILInstruction>();
} else { } else {
for (int i = 0; i < arguments.Count; i++) { if (!ConvertCallArguments(arguments, (IMethod)member))
arguments[i] = ConvertInstruction(arguments[i]).Item1;
if (arguments[i] == null)
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
} }
}
CallInstruction call; CallInstruction call;
if (member.IsAbstract || member.IsVirtual || member.IsOverride) { if (member.IsAbstract || member.IsVirtual || member.IsOverride) {
call = new CallVirt((IMethod)member); call = new CallVirt((IMethod)member);

Loading…
Cancel
Save