Browse Source

When a constructor starts with a NOP instruction, the primary constructor check is skipped to allow some unit tests to pass.

pull/3598/head
sonyps5201314 2 months ago
parent
commit
2a887cc5fd
  1. 22
      ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

22
ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

@ -249,10 +249,11 @@ namespace ICSharpCode.Decompiler.CSharp
var unspecializedMethod = instanceCtors[i]; var unspecializedMethod = instanceCtors[i];
var method = unspecializedMethod.Specialize(subst); var method = unspecializedMethod.Specialize(subst);
Block body = null; Block body = null;
bool? bodyHasLeadingNop = false;
if (mustFindChainingWithThis_Or_IsPrimaryConstructor) if (mustFindChainingWithThis_Or_IsPrimaryConstructor)
{ {
body = DecompileBody(method); body = DecompileBody(method, ref bodyHasLeadingNop);
if (body != null) if (body != null)
{ {
var first = body.Instructions.FirstOrDefault(); var first = body.Instructions.FirstOrDefault();
@ -286,7 +287,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
} }
if (!CheckForInitPrimaryConstructor(method, unspecializedMethod, body)) if (bodyHasLeadingNop == true || !CheckForInitPrimaryConstructor(method, unspecializedMethod, body))
{ {
primaryConstructor = null; primaryConstructor = null;
primaryCtorParameterToAutoPropertyOrBackingField.Clear(); primaryCtorParameterToAutoPropertyOrBackingField.Clear();
@ -313,7 +314,12 @@ namespace ICSharpCode.Decompiler.CSharp
return false; return false;
if (body == null) if (body == null)
body = DecompileBody(method); {
bool? bodyHasLeadingNop = false;
body = DecompileBody(method, ref bodyHasLeadingNop);
if (bodyHasLeadingNop == true)
return false;
}
if (body == null) if (body == null)
return false; return false;
@ -1290,6 +1296,11 @@ namespace ICSharpCode.Decompiler.CSharp
} }
Block DecompileBody(IMethod method) Block DecompileBody(IMethod method)
{
bool? bodyHasLeadingNop = null;
return DecompileBody(method, ref bodyHasLeadingNop);
}
Block DecompileBody(IMethod method, ref bool? bodyHasLeadingNop)
{ {
if (method == null || method.MetadataToken.IsNil) if (method == null || method.MetadataToken.IsNil)
return null; return null;
@ -1306,6 +1317,11 @@ namespace ICSharpCode.Decompiler.CSharp
var body = typeSystem.MainModule.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress); var body = typeSystem.MainModule.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
var ilReader = new ILReader(typeSystem.MainModule); var ilReader = new ILReader(typeSystem.MainModule);
var il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken); var il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken);
if (bodyHasLeadingNop != null)
{
var preBody = il.Body is BlockContainer bc ? bc.EntryPoint ?? il.Body as Block : null;
bodyHasLeadingNop = preBody != null ? preBody.Instructions.FirstOrDefault() is Nop : false;
}
var settings = new DecompilerSettings(LanguageVersion.CSharp1); var settings = new DecompilerSettings(LanguageVersion.CSharp1);
var transforms = CSharpDecompiler.GetILTransforms(); var transforms = CSharpDecompiler.GetILTransforms();
// Remove the last couple transforms -- we don't need variable names etc. here // Remove the last couple transforms -- we don't need variable names etc. here

Loading…
Cancel
Save