Skip to content

Commit b1cb4c5

Browse files
[clr-interp] Fix more issues implicit conversions (#121319)
- When boxing to a floating point value, ensure that the stack value has the correct type - When boxing to a native int or uint, if the stack value is I4 and we're on a 64bit platform, sign-extend the I4 before boxing - When stack's merge convert to the target stack type instead of blindly copying. --------- Co-authored-by: Copilot <[email protected]>
1 parent 09a4d35 commit b1cb4c5

File tree

1 file changed

+57
-2
lines changed

1 file changed

+57
-2
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -567,8 +567,43 @@ void InterpCompiler::EmitBBEndVarMoves(InterpBasicBlock *pTargetBB)
567567
int dVar = pTargetBB->pStackState[i].var;
568568
if (sVar != dVar)
569569
{
570-
InterpType interpType = m_pVars[sVar].interpType;
571-
int32_t movOp = InterpGetMovForType(interpType, false);
570+
InterpType interpType = g_interpTypeFromStackType[m_pStackBase[i].GetStackType()];
571+
InterpType interpDestType = g_interpTypeFromStackType[pTargetBB->pStackState[i].GetStackType()];
572+
int32_t movOp;
573+
if (interpType != interpDestType)
574+
{
575+
if (interpType == InterpTypeR4 && interpDestType == InterpTypeR8)
576+
{
577+
movOp = INTOP_CONV_R8_R4;
578+
}
579+
else if (interpType == InterpTypeR8 && interpDestType == InterpTypeR4)
580+
{
581+
movOp = INTOP_CONV_R4_R8;
582+
}
583+
else if (interpType == InterpTypeI && interpDestType == InterpTypeByRef)
584+
{
585+
movOp = InterpGetMovForType(interpDestType, false);
586+
}
587+
#ifdef TARGET_64BIT
588+
// nint and int32 can be used interchangeably. Add implicit conversions.
589+
else if (interpType == InterpTypeI4 && interpDestType == InterpTypeI8)
590+
{
591+
movOp = INTOP_CONV_I8_I4;
592+
}
593+
else if (interpType == InterpTypeI8 && interpDestType == InterpTypeI4)
594+
{
595+
movOp = InterpGetMovForType(interpDestType, false);
596+
}
597+
#endif // TARGET_64BIT
598+
else
599+
{
600+
BADCODE("Incompatible types on stack between basic blocks");
601+
}
602+
}
603+
else
604+
{
605+
movOp = InterpGetMovForType(interpType, false);
606+
}
572607

573608
AddIns(movOp);
574609
m_pLastNewIns->SetSVar(sVar);
@@ -7989,6 +8024,26 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
79898024

79908025
if (m_compHnd->isValueClass(resolvedToken.hClass))
79918026
{
8027+
CorInfoType asCorInfoType = m_compHnd->asCorInfoType(m_compHnd->getTypeForBox(resolvedToken.hClass));
8028+
if (asCorInfoType == CORINFO_TYPE_FLOAT && m_pStackPointer[-1].GetStackType() == StackTypeR8)
8029+
{
8030+
EmitConv(m_pStackPointer - 1, StackTypeR4, INTOP_CONV_R4_R8);
8031+
}
8032+
else if (asCorInfoType == CORINFO_TYPE_DOUBLE && m_pStackPointer[-1].GetStackType() == StackTypeR4)
8033+
{
8034+
EmitConv(m_pStackPointer - 1, StackTypeR8, INTOP_CONV_R8_R4);
8035+
}
8036+
#ifdef TARGET_64BIT
8037+
// nint and int32 can be used interchangeably. Add implicit conversions.
8038+
else if (asCorInfoType == CORINFO_TYPE_NATIVEINT && m_pStackPointer[-1].GetStackType() == StackTypeI4)
8039+
{
8040+
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_I4);
8041+
}
8042+
else if (asCorInfoType == CORINFO_TYPE_NATIVEUINT && m_pStackPointer[-1].GetStackType() == StackTypeI4)
8043+
{
8044+
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_U4);
8045+
}
8046+
#endif // TARGET_64BIT
79928047
CORINFO_GENERICHANDLE_RESULT embedInfo;
79938048
m_compHnd->embedGenericHandle(&resolvedToken, false, m_methodInfo->ftn, &embedInfo);
79948049
m_pStackPointer -= 1;

0 commit comments

Comments
 (0)