diff --git a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/Common/ExceptionStringID.cs b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/Common/ExceptionStringID.cs index 14800f0e739f96..7de12aa4fe0168 100644 --- a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/Common/ExceptionStringID.cs +++ b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/Common/ExceptionStringID.cs @@ -32,6 +32,8 @@ public enum ExceptionStringID InvalidProgramVararg, InvalidProgramCallVirtFinalize, InvalidProgramNativeCallable, + InvalidProgramCallAbstractMethod, + InvalidProgramCallVirtStatic, // BadImageFormatException BadImageFormatGeneric, diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index d38ca882b1dc09..70d61f327e35c5 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -915,7 +915,7 @@ private void ceeInfoGetCallInfo( // a static method would have never found an instance method. if (originalMethod.Signature.IsStatic && (flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_CALLVIRT) != 0) { - throw new BadImageFormatException(); + ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramCallVirtStatic, originalMethod); } exactType = type; @@ -1037,15 +1037,15 @@ private void ceeInfoGetCallInfo( // Static methods are always direct calls directCall = true; } + else if ((flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_CALLVIRT) == 0 || resolvedConstraint) + { + directCall = true; + } else if (targetMethod.OwningType.IsInterface && targetMethod.IsAbstract) { // Backwards compat: calls to abstract interface methods are treated as callvirt directCall = false; } - else if ((flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_CALLVIRT) == 0 || resolvedConstraint) - { - directCall = true; - } else { bool devirt; @@ -1090,6 +1090,14 @@ private void ceeInfoGetCallInfo( if (directCall) { + // Direct calls to abstract methods are not allowed + if (targetMethod.IsAbstract && + // Compensate for always treating delegates as direct calls above + !(((flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_LDFTN) != 0) && ((flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_CALLVIRT) != 0) && !resolvedCallVirt)) + { + ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramCallAbstractMethod, targetMethod); + } + bool allowInstParam = (flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_ALLOWINSTPARAM) != 0; if (!allowInstParam && canonMethod.RequiresInstArg())