Skip to content

NativeAOT: Usage of static virtual method from interface gets miscompiled as infinite loop #110932

@ZingBallyhoo

Description

@ZingBallyhoo

Description

In .NET9 NativeAOT, usage of a static virtual method from an interface sometimes gets miscompiled to an infinte loop.

Reproduction Steps

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net9.0</TargetFramework>
        <PublishAot>true</PublishAot>
    </PropertyGroup>
</Project>
using System;

Do<Primary>();
Do<Secondary>();

static void Do<T>() where T: Interface
{
    if (T.IsSecondary())
    {
        Console.Out.WriteLine("IsSecondary");
    } else
    {
        Console.Out.WriteLine("Isn't Secondary");
    }
}

interface Interface
{
    public static virtual bool IsSecondary() => false; // does not work under NativeAOT
    //public static abstract bool IsSecondary(); // works under NativeAOT and CoreCLR
}
    
struct Primary : Interface
{
    public static bool IsSecondary() => false;
}
    
struct Secondary : Interface
{
    public static bool IsSecondary() => true;
}

Or on gotbolt: https://godbolt.org/z/7P1rsMs4x

Expected behavior

Isn't Secondary
IsSecondary

Actual behavior

Isn't Secondary
(hangs)

Regression?

Yes, the same code does not hang on .NET 8 NativeAOT.

Known Workarounds

  • Use static abstract instead of static virtual.
  • Add [MethodImpl(MethodImplOptions.NoInlining)] to the abstract method.

Configuration

.NET 9.0.100
Windows 10 x64

Other information

Using a larger method body still triggers the issue (the normal body runs before entering the infinite loop).
Implementing the interface on a class instead of a struct still triggers the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-NativeAOT-coreclrin-prThere is an active PR which will close this issue when it is merged

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions