Browse Source

Fix #3621: Fix multiple uses of primary ctor parameter in initializer of record.

pull/3620/head
Siegfried Pammer 1 month ago
parent
commit
3fd9981535
  1. 11
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Records.cs
  2. 17
      ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

11
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Records.cs

@ -232,6 +232,17 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
this.A = A; this.A = A;
} }
} }
private record RecordWithMultipleInitializerAssignmentsInPrimaryCtor(string name, string? value, in object encode)
{
public string? Value { get; } = name;
public string Name { get; } = value;
private string? WebValue { get; } = (name != null) ? "111" : value;
private string? WebValue2;
}
} }
#if CS100 #if CS100

17
ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

@ -303,13 +303,13 @@ namespace ICSharpCode.Decompiler.CSharp
continue; continue;
if (valueInst.MatchLdLoc(out var v)) if (valueInst.MatchLdLoc(out var v))
{ {
if (v.Kind != VariableKind.Parameter || v.Index < parameterIndex) if (!ValidateParameter(v, parameterIndex))
return false; return false;
parameterIndex = v.Index!.Value; parameterIndex = v.Index!.Value;
} }
else if (valueInst.MatchLdObj(out valueInst, out _) && valueInst.MatchLdLoc(out v)) else if (valueInst.MatchLdObj(out valueInst, out _) && valueInst.MatchLdLoc(out v))
{ {
if (v.Kind != VariableKind.Parameter || v.Index < parameterIndex) if (!ValidateParameter(v, parameterIndex))
return false; return false;
parameterIndex = v.Index!.Value; parameterIndex = v.Index!.Value;
if (method.Parameters[parameterIndex].ReferenceKind is ReferenceKind.None) if (method.Parameters[parameterIndex].ReferenceKind is ReferenceKind.None)
@ -339,6 +339,19 @@ namespace ICSharpCode.Decompiler.CSharp
var returnInst = body.Instructions.LastOrDefault(); var returnInst = body.Instructions.LastOrDefault();
return returnInst != null && returnInst.MatchReturn(out var retVal) && retVal.MatchNop(); return returnInst != null && returnInst.MatchReturn(out var retVal) && retVal.MatchNop();
bool ValidateParameter(ILVariable v, int expectedMinimumIndex)
{
if (v.Kind != VariableKind.Parameter)
return false;
Debug.Assert(v.Index.HasValue);
if (v.Index < 0 || v.Index >= unspecializedMethod.Parameters.Count)
return false;
var parameter = unspecializedMethod.Parameters[v.Index.Value];
if (primaryCtorParameterToAutoProperty.ContainsKey(parameter))
return true;
return v.Index >= expectedMinimumIndex;
}
} }
IMethod? FindChainedCtor(Block body) IMethod? FindChainedCtor(Block body)

Loading…
Cancel
Save