Browse Source

Fix #937: support implicit Ref->I4 conversions

These are not allowed in Ecma-335 Table 8: Conversion Operations,
but the .NET runtime accepts them anyways, and C++/CLI generates them.
pull/1012/head
Daniel Grunwald 8 years ago
parent
commit
128e05cd11
  1. 16
      ICSharpCode.Decompiler/IL/ILReader.cs

16
ICSharpCode.Decompiler/IL/ILReader.cs

@ -1056,10 +1056,24 @@ namespace ICSharpCode.Decompiler.IL @@ -1056,10 +1056,24 @@ namespace ICSharpCode.Decompiler.IL
} else if (expectedType == StackType.I4 && inst.ResultType == StackType.I) {
// C++/CLI also sometimes implicitly converts in the other direction:
inst = new Conv(inst, PrimitiveType.I4, false, Sign.None);
} else if (expectedType == StackType.I && inst.ResultType == StackType.Ref) {
} else if (inst.ResultType == StackType.Ref) {
// Implicitly stop GC tracking; this occurs when passing the result of 'ldloca' or 'ldsflda'
// to a method expecting a native pointer.
inst = new Conv(inst, PrimitiveType.I, false, Sign.None);
switch (expectedType) {
case StackType.I4:
inst = new Conv(inst, PrimitiveType.I4, false, Sign.None);
break;
case StackType.I:
break;
case StackType.I8:
inst = new Conv(inst, PrimitiveType.I8, false, Sign.None);
break;
default:
Warn($"Expected {expectedType}, but got {StackType.Ref}");
inst = new Conv(inst, expectedType.ToKnownTypeCode().ToPrimitiveType(), false, Sign.None);
break;
}
} else if (expectedType == StackType.Ref) {
// implicitly start GC tracking / object to interior
if (!inst.ResultType.IsIntegerType() && inst.ResultType != StackType.O) {

Loading…
Cancel
Save