Skip to content

Commit

Permalink
Merge pull request dotnet#215 from janvorli/fix-abstractcalls-test
Browse files Browse the repository at this point in the history
Fix crossgen2 handling of direct calls to abstract methods
  • Loading branch information
janvorli authored Nov 22, 2019
2 parents 0509022 + dc75b27 commit d996a91
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public enum ExceptionStringID
InvalidProgramVararg,
InvalidProgramCallVirtFinalize,
InvalidProgramNativeCallable,
InvalidProgramCallAbstractMethod,
InvalidProgramCallVirtStatic,

// BadImageFormatException
BadImageFormatGeneric,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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())
Expand Down

0 comments on commit d996a91

Please sign in to comment.