Skip to content

Possible miscompile in loop inside try/finally #48394

@james-hunt-ra

Description

@james-hunt-ra

Description

The function F, below, returns 1 when run in Release mode on .NET 5 on x64 Win 10.

It is expected to return 0 - which it does indeed return in both Debug configuration, and also under .NET Core 3.1.

using System;

namespace Miscompile
{
    class Program
    {       
        static void Main()
        {
            int result = F();
            if (result == 0)
            {
                Console.WriteLine("OK");
            }
            else
            {
                Console.WriteLine($"FAILED! result = {result}");
            }
        }

        // When compiled in Release mode, this function returns 1 under .NET 5
        // Expect it to return 0, which is the case under .NET Core 3.1
        private static int F()
        {
            bool x = false;            
            int c = 0;

            try
            {
                while (true)
                {
                    // It appears this assignment is erroneously removed or hoisted out of loop?
                    c = 0;

                    if (!x)
                    {
                        c++;
                        x = true;
                    }
                    else
                    {
                        return c;
                    }

                    // Uncommenting the below fixes issue, even if the assignment
                    // to c at loop start is commented out
                    // c = 0;
                }
            }
            finally
            {
                // finally block appears necessary to 
                // reproduce the error
                // Commenting out the finally block, the if expression,
                // or even just the WriteLine statement fixes the problem
                if (c != 0)
                {
                    Console.WriteLine("c not zero");
                }
            }
        }        
    }
}

Configuration

.NET Version: .NET 5
OS: Windows 10
Arch: x64

Does not occur on .NET Core 3.1 or below.
Does not occur in Debug builds.
Not tested on other architectures or operating systems.

Regression?

Yes - worked in .NET 3.1 and before.

Other information

Workarounds - see the comments in code above. There are two minor alterations that stop it miscompiling.

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIbug

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions