EmitFieldLoad possibly uses over-optimistic optimization for scenario when field's value isn't used
- Dominant language
- C#
- Stars
- 20.7k
- Forks
- 4.3k
- PR merge metrics
- PR metrics pending
Description
Note, the code stops at loading receiver:
```
// Accessing a volatile field is sideeffecting because it establishes an acquire fence.
// Otherwise, accessing an unused instance field on a struct is a noop. Just emit an unused receiver.
if (!field.IsVolatile && !field.IsStatic && fieldAccess.ReceiverOpt.Type.IsVerifierValue() && field.RefKind == RefKind.None)
{
EmitExpression(fieldAccess.ReceiverOpt, used: false);
return;
}
```
However, it looks like loading a field has another side-effect - checking if receiver is at null ref. This can be observed with the following code (https://lab.razor.fyi/#bVFLbhNBEFUMC2gJCXGCUtjYEplIXnoYpMQfyVEAy01AYkW7pzxupad7VNU9zhDlElwAcQHEng0n4AacAZZIbNA4DjJSlq_fe_W6XokfHSFm5AtSZaL50fdOZOMKkA0HLFOxi5J5dMGUmAx9WRmLJJFqo5FTIQiXQKhy72wDsg_chwzaxzPHaonJi2jtHJdPZf9Zt5cKEagRlwIAQMICMuB-ItMNHnrH3mLyhkzAU-Owuz-ez1_OByBXPtocVqpGCCvyawfbsUjoNI4vNFbBeLffS8WV0CroFXRvl_S26bekzY6kvJ4gOFDUAWR_q67iwhoNEuSG3sIbFVzeCBZNQJikcCXEt454MDKEOpgaua34c-fxoCJfIYUGjqz16-uOjq3X55wFiih2FEPvlqaIpNpvZyNcxGKXnqAKkZCzyHhAnm3jDoI_R2feI6UTY_FYMebbE-86p2VljTbhrD0xZ7lhtbD_RZ8qV7xG4ja4IqwNrnfpttnWkqHbOA8P4dfHD5_g1XQ2gOeeEPJ_i4MiBI5V5Slg_gQaH0ErB7lh7WskCCssoTYKpqMxcCwK5HZhTsTJHYru7f17X77-_vOzeHj33d7F3l8):
```
using System;
using System.Runtime.CompilerServices;
ref readonly S2 s2 = ref Unsafe.NullRef();
try
{
S b = s2.S;
Console.WriteLine("ERROR: Should have thrown NullReferenceException");
}
catch (NullReferenceException)
{
Console.WriteLine("PASS");
}
struct S2
{
public S S;
}
public struct S { public byte F; }
```
The code prints "PASS".
Perhaps when field's value isn't needed, compiler should emit `ldflda`. Probably scenarios when receiver itself is a non-ref field could still be optimized the way it is done right now.
Contributor guide
Assessment
This issue has not been assessed yet.