Skip to content

Commit 4339159

Browse files
authored
Fix pointer comparison (#3252)
***NO_CI***
1 parent b295724 commit 4339159

File tree

1 file changed

+52
-4
lines changed

1 file changed

+52
-4
lines changed

src/CLR/Core/CLR_RT_HeapBlock.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,7 +1656,8 @@ static inline int CompareValues_Numeric(CLR_UINT32 left, CLR_UINT32 right)
16561656
return 1;
16571657
if (left < right)
16581658
return -1;
1659-
/**************/ return 0;
1659+
/**************/
1660+
return 0;
16601661
}
16611662

16621663
static int CompareValues_Numeric(const CLR_INT64 left, const CLR_INT64 right)
@@ -1734,11 +1735,58 @@ static int CompareValues_Numeric(const CLR_RT_HeapBlock &left, const CLR_RT_Heap
17341735
static inline int CompareValues_Pointers(const CLR_RT_HeapBlock *left, const CLR_RT_HeapBlock *right)
17351736
{
17361737
NATIVE_PROFILE_CLR_CORE();
1737-
if (left > right)
1738+
1739+
// let's save time and check up front for equality
1740+
if (left == right)
1741+
{
1742+
return 0;
1743+
}
1744+
1745+
// edge case when comparing arrays with storage pointers
1746+
if (left && right && left->DataType() == DATATYPE_SZARRAY && right->DataType() == DATATYPE_SZARRAY)
1747+
{
1748+
const CLR_RT_HeapBlock_Array *leftArray = (const CLR_RT_HeapBlock_Array *)left;
1749+
const CLR_RT_HeapBlock_Array *rightArray = (const CLR_RT_HeapBlock_Array *)right;
1750+
1751+
if (leftArray->ReflectionDataConst().kind == REFLECTION_STORAGE_PTR &&
1752+
rightArray->ReflectionDataConst().kind == REFLECTION_STORAGE_PTR)
1753+
{
1754+
// compare the storage pointers only if both are valid (non-zero)
1755+
uintptr_t leftStorage = leftArray->m_StoragePointer;
1756+
uintptr_t rightStorage = rightArray->m_StoragePointer;
1757+
1758+
if (leftStorage != 0 && rightStorage != 0)
1759+
{
1760+
if (leftStorage > rightStorage)
1761+
{
1762+
return 1;
1763+
}
1764+
if (leftStorage < rightStorage)
1765+
{
1766+
return -1;
1767+
}
1768+
1769+
// they are equal
1770+
return 0;
1771+
}
1772+
}
1773+
}
1774+
1775+
// default pointer comparison using uintptr_t to avoid undefined behavior
1776+
uintptr_t leftPtr = (uintptr_t)left;
1777+
uintptr_t rightPtr = (uintptr_t)right;
1778+
1779+
if (leftPtr > rightPtr)
1780+
{
17381781
return 1;
1739-
if (left < right)
1782+
}
1783+
if (leftPtr < rightPtr)
1784+
{
17401785
return -1;
1741-
/**************/ return 0;
1786+
}
1787+
1788+
// they are equal
1789+
return 0;
17421790
}
17431791

17441792
CLR_INT32 CLR_RT_HeapBlock::Compare_Values(const CLR_RT_HeapBlock &left, const CLR_RT_HeapBlock &right, bool fSigned)

0 commit comments

Comments
 (0)