[llvm-dev] UBSan, StringRef and Allocator.h

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Tue Mar 22 17:57:59 PDT 2016


On Tue, Mar 22, 2016 at 5:30 PM, Pete Cooper via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> Hi all
>
> (No idea if I have the correct audience.  Please CC more people as needed).
>
> I have an UBSan failure in BumpPtrAllocatorImpl.Allocate.
>
> The problem is that lld requests that we StringRef::copy an empty string.
> This passes a length of 0 to a BumpPtrAllocator.  The BumpPtrAllocator
> happened to not have anything allocated yet so the CurPtr is nullptr, but
> given that we need 0 space we think we have enough space and return an
> allocation of size 0 at address nullptr.  This therefore returns nullptr
> from Allocate, but that method is marked with LLVM_ATTRIBUTE_RETURNS_NONNULL
> and LLVM_ATTRIBUTE_RETURNS_NOALIAS, both of which aren’t true in this case.

Why is noalias not valid here?

I thought LLVM's notion of noalias was based on data dependence --
ptr_a does not alias ptr_b if a store to ptr_a does not have a data
dependence with a load from ptr_b and vice versa (and for a zero-sized
allocation there can be no data dependence since there cannot legally
be such a load/store).  Is the C++ notion of noalias different?

>
> To put this in code, if I have
>
> BumpPtrAllocator allocator;
> StringRef s;
> s.copy(allocator);
>
>
> then i’m going to allocate 0 bytes in the allocator and get a
> StringRef(nullptr, 0).  Its a valid StringRef, but an UBSan failures in the
> allocator.
>
> Lang and I looked up malloc behaviour online as this is fairly analogous.
> The answer there is that you are allowed to return nullptr, or not, its
> implementation defined.  So no help there.
>
> So the question is, how do we want this to behave in our code?
>
> Some options:
> - Assert that Allocate never gets a size 0 allocation.  So fix
> StringRef::copy to see this case
> - Remove the attributes from Allocate but continue to return nullptr (or
> base of the allocator?) in this case
> - Keep the attributes on Allocate and treat size 0 allocations as size 1

A fourth option would be return a non-null pointer (maybe the address
of some static char) for allocations of size 0; unless I'm mistaken
about the noalias bit above.

-- Sanjoy


More information about the llvm-dev mailing list