-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Closed
Copy link
Description
The construct if (pointer is null) produces invalid IL, per https://sharplab.io/ running on latest Roslyn master.
public unsafe class C {
public static bool Foo(void* ptr) {
return (ptr == null);
}
public static bool Bar(void* ptr) {
return (ptr is null);
}
}.class public auto ansi beforefieldinit C
extends [System.Private.CoreLib]System.Object
{
// Methods
.method public hidebysig static
bool Foo (
void* ptr
) cil managed
{
// Method begins at RVA 0x2050
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: conv.u
IL_0003: ceq
IL_0005: ret
} // end of method C::Foo
.method public hidebysig static
bool Bar (
void* ptr
) cil managed
{
// Method begins at RVA 0x2057
// Code size 5 (0x5)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldnull
IL_0002: ceq
IL_0004: ret
} // end of method C::Bar
} // end of class CIn the Foo method, the compiler emits a ceq instruction comparing a native int against a native int. However, in the Bar method, the compiler emits a ceq instruction comparing a native int against an O (see ECMA-335, Sec. III.3.45).
Per ECMA-335, Sec. III.1.5 (Table III.4), it is illegal for the IL stream to use ceq to compare a native int against an O. We even had to work around this in the runtime in our implementation of Unsafe.IsNullRef (see source).
The expected behavior is that the if (pointer is null) construct should continue to emit the same IL that the if (pointer == null) construct did.