Browse Source

Fix #1635: DynamicInvokeConstructorInstruction Did report the wrong StackType for value types and unknown types.

pull/1641/head
Siegfried Pammer 6 years ago
parent
commit
44c044aa33
  1. 5
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/DynamicTests.cs
  2. 8
      ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs
  3. 13
      ICSharpCode.Decompiler/IL/Transforms/DynamicCallSiteTransform.cs

5
ICSharpCode.Decompiler.Tests/TestCases/Pretty/DynamicTests.cs

@ -415,6 +415,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -415,6 +415,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return true.Equals(a);
}
private static IntPtr NewIntPtr(dynamic a)
{
return new IntPtr(a);
}
private static dynamic GetDynamic(int i)
{
return null;

8
ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs

@ -349,14 +349,17 @@ namespace ICSharpCode.Decompiler.IL @@ -349,14 +349,17 @@ namespace ICSharpCode.Decompiler.IL
partial class DynamicInvokeConstructorInstruction
{
readonly IType resultType;
public IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; }
public DynamicInvokeConstructorInstruction(CSharpBinderFlags binderFlags, IType context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments)
public DynamicInvokeConstructorInstruction(CSharpBinderFlags binderFlags, IType type, IType context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments)
: base(OpCode.DynamicInvokeConstructorInstruction, binderFlags, context)
{
ArgumentInfo = argumentInfo;
Arguments = new InstructionCollection<ILInstruction>(this, 0);
Arguments.AddRange(arguments);
this.resultType = type;
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
@ -365,11 +368,12 @@ namespace ICSharpCode.Decompiler.IL @@ -365,11 +368,12 @@ namespace ICSharpCode.Decompiler.IL
output.Write(OpCode);
WriteBinderFlags(output, options);
output.Write(' ');
resultType?.WriteTo(output);
output.Write(".ctor");
WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo));
}
public override StackType ResultType => StackType.O;
public override StackType ResultType => resultType?.GetStackType() ?? StackType.Unknown;
public override CSharpArgumentInfo GetArgumentInfoOfChild(int index)
{

13
ICSharpCode.Decompiler/IL/Transforms/DynamicCallSiteTransform.cs

@ -183,12 +183,23 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -183,12 +183,23 @@ namespace ICSharpCode.Decompiler.IL.Transforms
arguments: targetInvokeCall.Arguments.Skip(2).ToArray()
);
case BinderMethodKind.InvokeConstructor:
var arguments = targetInvokeCall.Arguments.Skip(2).ToArray();
// Extract type information from targetInvokeCall:
// Must either be an inlined type or
// a reference to a variable that is initialized with a type.
if (!TransformExpressionTrees.MatchGetTypeFromHandle(arguments[0], out var type)) {
if (!(arguments[0].MatchLdLoc(out var temp) && temp.IsSingleDefinition && temp.StoreInstructions.FirstOrDefault() is StLoc initStore))
return null;
if (!TransformExpressionTrees.MatchGetTypeFromHandle(initStore.Value, out type))
return null;
}
deadArguments.AddRange(targetInvokeCall.Arguments.Take(2));
return new DynamicInvokeConstructorInstruction(
binderFlags: callsite.Flags,
type: type ?? SpecialType.UnknownType,
context: callsite.Context,
argumentInfo: callsite.ArgumentInfos,
arguments: targetInvokeCall.Arguments.Skip(2).ToArray()
arguments: arguments
);
case BinderMethodKind.InvokeMember:
deadArguments.AddRange(targetInvokeCall.Arguments.Take(2));

Loading…
Cancel
Save