diff --git a/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs b/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
index 49ff62cc2..7b38b2e90 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
@@ -537,6 +537,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
+ ///
+ /// Gets whether the ILInstruction will turn into a C# expresion that is considered readonly by the C# compiler.
+ ///
internal static bool IsReadonlyReference(ILInstruction addr)
{
switch (addr)
diff --git a/ICSharpCode.Decompiler/IL/Transforms/IntroduceRefReadOnlyModifierOnLocals.cs b/ICSharpCode.Decompiler/IL/Transforms/IntroduceRefReadOnlyModifierOnLocals.cs
index 946f15363..aba272b1f 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/IntroduceRefReadOnlyModifierOnLocals.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/IntroduceRefReadOnlyModifierOnLocals.cs
@@ -52,8 +52,18 @@ namespace ICSharpCode.Decompiler.IL
{
foreach (var store in variable.StoreInstructions.OfType())
{
+ // Check if C# requires that the local is ref-readonly in order to allow the store:
if (ILInlining.IsReadonlyReference(store.Value))
return true;
+ // Check whether the local needs to be ref-readonly to avoid changing the semantics of
+ // a readonly.ldelema:
+ ILInstruction val = store.Value;
+ while (val is LdFlda ldflda)
+ {
+ val = ldflda.Target;
+ }
+ if (val is LdElema { IsReadOnly: true })
+ return true;
}
return false;
}