Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to translate DisplayClass in some special local function #1913

Closed
yyjdelete opened this issue Jan 19, 2020 · 1 comment · Fixed by #2005
Closed

Failed to translate DisplayClass in some special local function #1913

yyjdelete opened this issue Jan 19, 2020 · 1 comment · Fixed by #2005
Labels
Bug C# Decompiler The decompiler engine itself
Milestone

Comments

@yyjdelete
Copy link
Contributor

Tested with 6.0.0.5559-preview2

Orig Code

using System;

namespace ConsoleApp4
{
    public class CZZZ
    {
        static int count;

        static void Main()
        {
            Console.WriteLine(M1());
            Console.WriteLine(M2());
        }
        public static int M1()
        {
            count = 0;
            int _x;
            return M1_x();

            int M1_x()
            {
                TryGetX(out _x);
                if (++count == 1)
                {
                    M1_x();
                }
                return _x;
            }
        }

        public static int M2()
        {
            int _x;
            M2_x();
            return _x;

            void M2_x()
            {
                _x = 0;
            }
        }

        private static bool TryGetX(out int x)
        {
            x = count;
            return true;
        }
    }
}

Actual

M1: InvalidOperationException: Sequence contains no elements, maybe related to #1781

System.InvalidOperationException: Sequence contains no elements
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at ICSharpCode.Decompiler.IL.Transforms.TransformDisplayClassUsage.IsClosure(ILTransformContext context, ILVariable variable, ITypeDefinition& closureType, ILInstruction& initializer)
   at ICSharpCode.Decompiler.IL.Transforms.TransformDisplayClassUsage.Run(ILFunction function, ILTransformContext context)
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext)

M1: After modified variable.HasInitialValue to variable.AddressCount > 0(which also fix #1781) in TransformDisplayClassUsage.cs, it not throw exception.

if (context.Settings.LocalFunctions && closureType?.Kind == TypeKind.Struct && variable.HasInitialValue && IsPotentialClosure(context, closureType)) {

But the scope of _x will be changed, and it will return 0 instead of 1 in new code.

public static int M1()
{
	count = 0;
	return M1_x();
	int M1_x()
	{
		TryGetX(out int _x);
		if (++count == 1)
		{
			M1_x();
		}
		return _x;
	}
}

M2: Maybe an variant of M1, it will not throw InvalidOperationException, but will hit some assert and see the return is lost.

public static int M2()
{
	M2();
	int _x;
//<--see the `return` is lost.
	void M2()
	{
		_x = 0;
	}
}
@siegfriedpammer
Copy link
Member

For the method M2 I have added a fix to prevent removing the return statement.

@dgrunwald Do you have any idea how we could extend the DeclareVariables step to support correctly declaring variables captured in local functions that do not have any use-sites except the calls to the local function?

@siegfriedpammer siegfriedpammer removed this from the v6.0-preview3 milestone Apr 7, 2020
@siegfriedpammer siegfriedpammer added this to the v6.0-preview4 milestone May 14, 2020
siegfriedpammer added a commit that referenced this issue May 17, 2020
…ctions before the first invocation of the local function.
@siegfriedpammer siegfriedpammer linked a pull request May 17, 2020 that will close this issue
3 tasks
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug C# Decompiler The decompiler engine itself
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants