Repository: dotnet/runtime
File: src/coreclr/jit/lclmorph.cpp (C++)

Code before:

            case GT_SUB:
            {
                Value& rhs = TopValue(0);
                Value& lhs = TopValue(1);
                if (m_compiler->opts.OptimizationEnabled() && lhs.IsAddress() && rhs.IsAddress() &&
                    (lhs.LclNum() == rhs.LclNum()) && (rhs.Offset() <= lhs.Offset()) &&
                    FitsIn<int>(lhs.Offset() - rhs.Offset()))
                {
                    // TODO-Bug: Due to inlining we may end up with incorrectly typed SUB trees here.
                    assert(node->TypeIs(TYP_I_IMPL, TYP_BYREF));

                    ssize_t result = (ssize_t)(lhs.Offset() - rhs.Offset());
                    node->BashToConst(result, TYP_I_IMPL);
                    INDEBUG(lhs.Consume());
                    INDEBUG(rhs.Consume());
                    PopValue();
                    PopValue();
                    m_stmtModified = true;
                    break;
                }

                EscapeValue(TopValue(0), node);
                PopValue();
                EscapeValue(TopValue(0), node);
                PopValue();
                break;
            }

            case GT_FIELD_ADDR:
                if (node->AsFieldAddr()->IsInstance())
                {
                    assert(TopValue(1).Node() == node);
                    assert(TopValue(0).Node() == node->AsFieldAddr()->GetFldObj());

                    if (!TopValue(1).AddOffset(TopValue(0), node->AsFieldAddr()->gtFldOffset))
                    {
                        // The field object did not represent an address, or the latter overflowed.
                        EscapeValue(TopValue(0), node);
                    }

                    PopValue();
                }
                else
                {
                    assert(TopValue(0).Node() == node);
                }
                break;

            case GT_STOREIND:
            case GT_STORE_BLK:

Review comment (bug):
Potential arithmetic overflow: Adding `lvFldOffset` (unsigned char, max 255) to `lhsOffset` (unsigned) without checking for overflow. While unlikely in practice since struct field offsets are typically small, consider adding an overflow check similar to the pattern used elsewhere in the codebase (e.g., line 1126 uses `FitsIn<unsigned>(offset)` before adding). This could be addressed by checking if the addition would overflow before performing it, or by verifying the result is greater than or equal to the original offset.
```suggestion
                        if (FitsIn<unsigned>(lhsOffset + lhsDsc->lvFldOffset))
                        {
                            lhsOffset += lhsDsc->lvFldOffset;
                        }
                        else
                        {
                            // Bail out if offset addition would overflow
                            break;
                        }
                    }

                    if (rhsDsc->lvIsStructField)
                    {
                        rhsLclNum = rhsDsc->lvParentLcl;
                        if (FitsIn<unsigned>(rhsOffset + rhsDsc->lvFldOffset))
                        {
                            rhsOffset += rhsDsc->lvFldOffset;
                        }
                        else
                        {
                            // Bail out if offset addition would overflow
                            break;
                        }
```

Code after:

            case GT_SUB:
            {
                Value& rhs = TopValue(0);
                Value& lhs = TopValue(1);
                if (m_compiler->opts.OptimizationEnabled() && lhs.IsAddress() && rhs.IsAddress())
                {
                    LclVarDsc* lhsDsc = m_compiler->lvaGetDesc(lhs.LclNum());
                    LclVarDsc* rhsDsc = m_compiler->lvaGetDesc(rhs.LclNum());

                    unsigned lhsLclNum = lhs.LclNum();
                    unsigned rhsLclNum = rhs.LclNum();

                    unsigned lhsOffset = lhs.Offset();
                    unsigned rhsOffset = rhs.Offset();

                    if (lhsDsc->lvIsStructField)
                    {
                        lhsLclNum = lhsDsc->lvParentLcl;
                        lhsOffset += lhsDsc->lvFldOffset;
                    }

                    if (rhsDsc->lvIsStructField)
                    {
                        rhsLclNum = rhsDsc->lvParentLcl;
                        rhsOffset += rhsDsc->lvFldOffset;
                    }

                    if ((lhsLclNum == rhsLclNum) && (rhsOffset <= lhsOffset) && FitsIn<int>(lhsOffset - rhsOffset))
                    {
                        // TODO-Bug: Due to inlining we may end up with incorrectly typed SUB trees here.
                        assert(node->TypeIs(TYP_I_IMPL, TYP_BYREF));

                        ssize_t result = (ssize_t)(lhsOffset - rhsOffset);
                        node->BashToConst(result, TYP_I_IMPL);
                        INDEBUG(lhs.Consume());
                        INDEBUG(rhs.Consume());
                        PopValue();
                        PopValue();
                        m_stmtModified = true;
                        break;
                    }
                }

                EscapeValue(TopValue(0), node);
                PopValue();
                EscapeValue(TopValue(0), node);
                PopValue();
                break;
            }