Skip to content

Ref locals from generic array access #3584

@ds5678

Description

@ds5678

Input code

using System.Collections;
using System.Collections.Generic;

namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
	internal abstract class Issue4000<T> : IEnumerable<T>, IEnumerable
	{
		public uint Length;

		protected T[] results;

		public T this[int i] {
			get {
				if (i >= Length || i < 0)
				{
					return default(T);
				}
				if (results[i] != null && results[i].Equals(default(T)))
				{
					results[i] = CreateIthElement(i);
				}
				return results[i];
			}
		}

		protected abstract T CreateIthElement(int i);

		public IEnumerator<T> GetEnumerator()
		{
			for (int i = 0; i < Length; i++)
			{
				if (results[i] != null && results[i].Equals(default(T)))
				{
					results[i] = CreateIthElement(i);
				}
				yield return results[i];
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
}

Erroneous output

The decompiled output varies based on decisions like the compiler version, but almost all of the defaultOptions result in output that contains:

ref readonly T reference = ref results[i];
object obj = default(T);
reference.Equals(obj)

which causes issues on C# versions that don't support ref locals ref locals in iterators.

Details

  • Product in use: ILSpy
  • Version in use: ed36ba1
  • Any other relevant information to the issue, or your interest in contributing a fix.
    • As always, I'm willing to work on this. However, I would appreciate some guidance about where this might be fixed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugDecompilerThe decompiler engine itself

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions