[llvm] r216973 - BumpPtrAllocator: use uintptr_t when aligning addresses to avoid undefined behaviour

Hans Wennborg hans at chromium.org
Wed Sep 3 09:38:35 PDT 2014


On Tue, Sep 2, 2014 at 4:40 PM, Hans Wennborg <hans at chromium.org> wrote:
> On Tue, Sep 2, 2014 at 3:45 PM, David Majnemer <david.majnemer at gmail.com> wrote:
>> On Tue, Sep 2, 2014 at 2:51 PM, Hans Wennborg <hans at hanshq.net> wrote:
>>>
>>> Author: hans
>>> Date: Tue Sep  2 16:51:35 2014
>>> New Revision: 216973
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=216973&view=rev
>>> Log:
>>> BumpPtrAllocator: use uintptr_t when aligning addresses to avoid undefined
>>> behaviour
>>>
>>> In theory, alignPtr() could push a pointer beyond the end of the current
>>> slab, making
>>> comparisons with that pointer undefined behaviour. Use an integer type to
>>> avoid this.
>>>
>>> Modified:
>>>     llvm/trunk/include/llvm/Support/Allocator.h
>>>     llvm/trunk/include/llvm/Support/MathExtras.h
>>>     llvm/trunk/unittests/Support/AllocatorTest.cpp
>>>
>>> Modified: llvm/trunk/include/llvm/Support/Allocator.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Allocator.h?rev=216973&r1=216972&r2=216973&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/Allocator.h (original)
>>> +++ llvm/trunk/include/llvm/Support/Allocator.h Tue Sep  2 16:51:35 2014
>>> @@ -210,16 +210,17 @@ public:
>>>      BytesAllocated += Size;
>>>
>>>      // Allocate the aligned space, going forwards from CurPtr.
>>> -    char *Ptr = alignPtr(CurPtr, Alignment);
>>> +    uintptr_t AlignedAddr = alignAddr(CurPtr, Alignment);
>>>
>>>      // Check if we can hold it.
>>> -    if (Ptr + Size <= End) {
>>> -      CurPtr = Ptr + Size;
>>> +    if (AlignedAddr + Size <= (uintptr_t)End) {
>>
>>
>> I would somehow assert that the alignment doesn't wrap End such that it is
>> smaller than CurPtr.
>
> Right, alignPtr should never overflow. I'll add an assert there.
>
>> I would also change this to be:
>> if ((uintptr_t)End - AlignedAddr >= Size)
>
> That relies on End being greater than AlignedAddr though, which isn't
> guaranteed. I'll add a test that exercises this.
>
>> Consider AlignedAddr + Size s.t. it wraps *past* End and results in being
>> really small.
>
> Right, AlignedAddr + Size could overflow uintptr_t, and then my code
> breaks. How about we take your code, but do a signed comparison,
> something like:
>
> if ((ptrdiff_t)((uintptr_t)End - AlignedAddr) >= (ptrdiff_t)Size)) {
>
> Hrm, I don't like how complicated this becomes :/ Maybe we could just
> assert that AlignedAddr + Size doesn't overflow?

Duncan had the idea of extracting the adjustment required for aligning
first, and then checking that size + adjustment fits in the slab,
which seems like an easier approach. The discussion is on the patch
thread: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140901/233553.html



More information about the llvm-commits mailing list