Browse Source

#1485: Fix decompilation of TypeAs with Nullable<T> in expression trees

pull/1505/head
Siegfried Pammer 6 years ago
parent
commit
8dc80583ec
  1. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs
  2. 12
      ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs

@ -836,12 +836,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public static void AsTypeExpr() public static void AsTypeExpr()
{ {
Test<Func<object, MyClass>>((object obj) => obj as MyClass, (object obj) => obj as MyClass); Test<Func<object, MyClass>>((object obj) => obj as MyClass, (object obj) => obj as MyClass);
Test<Func<object, int?>>((object obj) => obj as int?, (object obj) => obj as int?);
Test<Func<object, GenericClass<object>>>((object obj) => obj as GenericClass<object>, (object obj) => obj as GenericClass<object>); Test<Func<object, GenericClass<object>>>((object obj) => obj as GenericClass<object>, (object obj) => obj as GenericClass<object>);
} }
public static void IsTypeExpr() public static void IsTypeExpr()
{ {
Test<Func<object, bool>>((object obj) => obj is MyClass, (object obj) => obj is MyClass); Test<Func<object, bool>>((object obj) => obj is MyClass, (object obj) => obj is MyClass);
Test<Func<object, bool>>((object obj) => obj is int?, (object obj) => obj is int?);
} }
public static void UnaryLogicalOperators() public static void UnaryLogicalOperators()

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

@ -995,9 +995,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var converted = ConvertInstruction(invocation.Arguments[0]).Item1; var converted = ConvertInstruction(invocation.Arguments[0]).Item1;
if (!MatchGetTypeFromHandle(invocation.Arguments[1], out var type)) if (!MatchGetTypeFromHandle(invocation.Arguments[1], out var type))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
if (converted != null) if (converted == null)
return (new IsInst(converted, type), type); return (null, SpecialType.UnknownType);
return (null, SpecialType.UnknownType);
ILInstruction inst = new IsInst(converted, type);
// We must follow ECMA-335, III.4.6:
// If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T.
if (type.IsKnownType(KnownTypeCode.NullableOfT))
inst = new UnboxAny(inst, type);
return (inst, type);
} }
(ILInstruction, IType) ConvertTypeIs(CallInstruction invocation) (ILInstruction, IType) ConvertTypeIs(CallInstruction invocation)

Loading…
Cancel
Save