-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Open
Labels
Milestone
Description
The following program:
using System;
using System.Runtime.CompilerServices;
C.TestMethod(false);
Console.WriteLine("Done");
static class C
{
[MethodImpl(MethodImplOptions.NoInlining)] // doesn't matter, but JIC
public static int TestMethod(bool cond)
{
if (cond)
{
// never invoked in this program
return ClassB.X;
}
// always taken
return 0;
}
}
public class ClassB
{
public static readonly int X = GetX();
static int GetX()
{
Console.WriteLine("GetX call!"); // not expected to be invoked in this program
return 42;
}
}Output on Mono:
GetX call!
Done
Output on CoreCLR:
Done
It's not wrong according to ECMA-335:
: BeforeFieldInit behavior is intended for initialization code with no interesting sideeffects,
where exact timing does not matter. Also, under BeforeFieldInit semantics, type
initializers are allowed to be executed at or before first access to any static field of that type,
at the discretion of the CLI.
However, it'd be nice to align this behavior with CoreCLR to avoid potential issues like the one I've hit in #77398 (comment). And, obviously, in this case Mono executed completely redundant code (did more work). I think I've hit the same issue in the past where static initialization in Mono triggered DllImport leading to DllNotFoundException while CoreCLR didn't, can't find the issue.
Related issue: #4346 (see #4346 (comment))