Skip to content

Commit b80d8ac

Browse files
[clr-interp] Handle tail-call return conversions, by requiring that the return type be equivalent in stack layout (#121260)
The current behavior was allowing uninitialized data to show up as return values. This preserves all cases I believe to be important. --------- Co-authored-by: Copilot <[email protected]>
1 parent 3083294 commit b80d8ac

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3766,6 +3766,24 @@ void InterpCompiler::EmitPushLdvirtftn(int thisVar, CORINFO_RESOLVED_TOKEN* pRes
37663766
m_pLastNewIns->info.pCallInfo->pCallArgs = callArgs;
37673767
}
37683768

3769+
static bool DisallowTailCall(CORINFO_SIG_INFO* callerSig, CORINFO_SIG_INFO* calleeSig)
3770+
{
3771+
// We allow only the return value types to differ between caller and callee as long as their stack types are the same.
3772+
// In principle we could allow more differences (e.g. I8 coercion to I4, or O to I) but for now we keep it simple.
3773+
if (callerSig->retType != calleeSig->retType)
3774+
{
3775+
if (g_stackTypeFromInterpType[GetInterpType(callerSig->retType)] != g_stackTypeFromInterpType[GetInterpType(calleeSig->retType)])
3776+
{
3777+
return true;
3778+
}
3779+
}
3780+
else if (callerSig->retType == CORINFO_TYPE_VALUECLASS && callerSig->retTypeClass != calleeSig->retTypeClass)
3781+
{
3782+
return true;
3783+
}
3784+
return false;
3785+
}
3786+
37693787
void InterpCompiler::EmitCalli(bool isTailCall, void* calliCookie, int callIFunctionPointerVar, CORINFO_SIG_INFO* callSiteSig)
37703788
{
37713789
AddIns(isTailCall ? INTOP_CALLI_TAIL : INTOP_CALLI);
@@ -4036,6 +4054,15 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
40364054
#endif
40374055
}
40384056

4057+
if (tailcall && DisallowTailCall(&m_methodInfo->args, &callInfo.sig))
4058+
{
4059+
if (isJmp)
4060+
{
4061+
BADCODE("Incompatible target for CEE_JMP tail call");
4062+
}
4063+
tailcall = false;
4064+
}
4065+
40394066
if (newObj && (callInfo.classFlags & CORINFO_FLG_VAROBJSIZE))
40404067
{
40414068
// This is a variable size object which means "System.String".

0 commit comments

Comments
 (0)