dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.95k stars 4.02k forks source link

BadImageFormatException when building Expression using lambda inside a lambda #43298

Open kevinjwz opened 4 years ago

kevinjwz commented 4 years ago

Version Used: .NET Core 3.1.101 on Windows 10

Steps to Reproduce: Compile and run following code:

using System;
using System.Linq.Expressions;  

class C<T>
{
    public static C<T> operator +(C<T> a, C<T> b) => null;
}

class Test
{ 
    static void Method<T>()
    {
        C<T> c=null;

        Action action = () => {
            Expression<Func<C<T>>> e = () => c + c;
        };

        action();  // BadImageFormatException from here
    }

    static void Main(string[] args)
    {
        Method<int>();
    }
}

Expected Behavior: Either compile and run without errors, or refuse to compile if the program is incorrect.

Actual Behavior: Program compiles without error but throws BadImageFormatException when run.

System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (0x8007000B)
   at Test.<>c__DisplayClass0_0`1.<Method>b__0()
   at Test.Method[T](T a)
   at Test.Main(String[] args)

Test on SharpLab

kevinjwz commented 4 years ago

Interestingly if I wrap the operator+ by some helper function, the program runs without error.

using System;
using System.Linq.Expressions;  

class C<T>
{
    public static C<T> operator +(C<T> a, C<T> b) => null;
}

class Test
{ 
    static C<T> Add<T>(C<T> a, C<T> b) => a + b;
    static void Method<T>()
    {
        C<T> c=null;

        Action action = () => {
            Expression<Func<C<T>>> e = () => Add(c, c);
        };

        action();
    }

    static void Main(string[] args)
    {
        Method<int>();
    }
}