In some cases it's clear from the code that a call to a virtual method is actually not virtual. For example if the method implements an interface but there are no calls to the method through the interface. Similarly for static abstract methods where calling the base can never happen. Same situation happens if the implementation method is called through reflection.
In such cases it is correct to avoid treating the call as virtual and thus avoiding additional work and checks related to virtual calls. So for example warning IL2092 could be avoided.
NativeAOT has this behavior due to the nature of itss code generation algorithms, so there's a discrepancy between ILLink and NativeAOT.
In some cases it's clear from the code that a call to a virtual method is actually not virtual. For example if the method implements an interface but there are no calls to the method through the interface. Similarly for static abstract methods where calling the base can never happen. Same situation happens if the implementation method is called through reflection.
In such cases it is correct to avoid treating the call as virtual and thus avoiding additional work and checks related to virtual calls. So for example warning
IL2092
could be avoided.NativeAOT has this behavior due to the nature of itss code generation algorithms, so there's a discrepancy between ILLink and NativeAOT.