Browse Source

Merge pull request #4053 from sonyps5201314/split/unresolved-value-type-call-targets

Handle unresolved value-type call targets
pull/4104/head
Daniel Grunwald 2 weeks ago committed by GitHub
parent
commit
56f45ae8f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 7
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3729.cs
  2. 17
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3729.il
  3. 21
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

7
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3729.cs

@ -66,6 +66,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty @@ -66,6 +66,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty
MyClass value = new MyClass();
Console.WriteLine(value);
}
public void TestUnresolvedStructMemberCalls()
{
MyEnumerator val = default;
val.MoveNext();
((IDisposable)val/*cast due to constrained. prefix*/).Dispose();
}
}
public class Issue3729_DerivedFromUnknown : MissingBase
{

17
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3729.il

@ -177,6 +177,23 @@ @@ -177,6 +177,23 @@
IL_000c: ret
}
.method public hidebysig
instance void TestUnresolvedStructMemberCalls () cil managed
{
.maxstack 1
.locals init (
[0] valuetype [Library1]Library1.MyEnumerator
)
IL_0000: ldloca.s 0
IL_0002: call instance bool [Library1]Library1.MyEnumerator::MoveNext()
IL_0007: pop
IL_0008: ldloca.s 0
IL_000a: constrained. [Library1]Library1.MyEnumerator
IL_0010: callvirt instance void [System.Runtime]System.IDisposable::Dispose()
IL_0015: ret
}
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{

21
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -2923,7 +2923,18 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2923,7 +2923,18 @@ namespace ICSharpCode.Decompiler.CSharp
else
{
IType targetTypeHint = constrainedTo ?? memberDeclaringType;
if (CallInstruction.ExpectedTypeForThisPointer(memberDeclaringType, constrainedTo) == StackType.Ref)
if (target is Conv {
Kind: ConversionKind.Invalid,
InputType: StackType.Ref,
TargetType: IL.PrimitiveType.Unknown
} && targetTypeHint.Kind == TypeKind.Unknown)
{
target = target.UnwrapConv(ConversionKind.Invalid);
}
StackType expectedThisPointerType = CallInstruction.ExpectedTypeForThisPointer(memberDeclaringType, constrainedTo);
bool requiresManagedReference = expectedThisPointerType == StackType.Ref
|| (expectedThisPointerType == StackType.Unknown && target.ResultType == StackType.Ref);
if (requiresManagedReference)
{
if (target.ResultType == StackType.Ref)
{
@ -2935,13 +2946,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2935,13 +2946,15 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
var translatedTarget = Translate(target, targetTypeHint);
if (CallInstruction.ExpectedTypeForThisPointer(memberDeclaringType, constrainedTo) == StackType.Ref)
if (requiresManagedReference)
{
// When accessing members on value types, ensure we use a reference of the correct type,
// and not a pointer or a reference to a different type (issue #1333)
if (!(translatedTarget.Type is ByReferenceType brt && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(brt.ElementType, constrainedTo ?? memberDeclaringType)))
IType expectedTargetType = constrainedTo ?? memberDeclaringType;
if (!(translatedTarget.Type is ByReferenceType brt
&& NormalizeTypeVisitor.TypeErasure.EquivalentTypes(brt.ElementType, expectedTargetType)))
{
translatedTarget = translatedTarget.ConvertTo(new ByReferenceType(constrainedTo ?? memberDeclaringType), this);
translatedTarget = translatedTarget.ConvertTo(new ByReferenceType(expectedTargetType), this);
}
}
if (translatedTarget.Expression is DirectionExpression)

Loading…
Cancel
Save