Skip to content

Linker tracks wrong IL offset for return values #2778

@sbomer

Description

@sbomer

ScanAndProcessReturnValue uses the current origin to report warnings for method return values. The origin's IL offset is updated at certain spots in ReflectionMethodBodyScanner, but not for ret opcodes. Instead we just track the possible return values:

case Code.Ret: {
bool hasReturnValue = !methodBody.Method.ReturnsVoid ();
if (currentStack.Count != (hasReturnValue ? 1 : 0)) {
WarnAboutInvalidILInMethod (methodBody, operation.Offset);
}
if (hasReturnValue) {
StackSlot retValue = PopUnknown (currentStack, 1, methodBody, operation.Offset);
ReturnValue = MultiValueLattice.Meet (ReturnValue, retValue.Value);

And later report warnings about the return value using the current origin (which will have whatever IL offset we last updated it to):

public void ScanAndProcessReturnValue (MethodBody methodBody)
{
Scan (methodBody);
if (!methodBody.Method.ReturnsVoid ()) {
var method = methodBody.Method;
var methodReturnValue = _annotations.GetMethodReturnValue (method);
if (methodReturnValue.DynamicallyAccessedMemberTypes != 0) {
var diagnosticContext = new DiagnosticContext (_origin, ShouldEnableReflectionPatternReporting (_origin.Provider), _context);
RequireDynamicallyAccessedMembers (diagnosticContext, ReturnValue, methodReturnValue);
}
}
}

We probably should be tracking the IL offset for each ret instruction instead. I can't think of a case where this produces any different warning behavior, but it requires a workaround in how we handle trim analysis patterns in the linker.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions