diff --git a/llvm/lib/Support/MemoryBuffer.cpp b/llvm/lib/Support/MemoryBuffer.cpp --- a/llvm/lib/Support/MemoryBuffer.cpp +++ b/llvm/lib/Support/MemoryBuffer.cpp @@ -135,7 +135,11 @@ auto Buf = WritableMemoryBuffer::getNewUninitMemBuffer(InputData.size(), BufferName); if (!Buf) return make_error_code(errc::not_enough_memory); - memcpy(Buf->getBufferStart(), InputData.data(), InputData.size()); + // Calling memcpy with null src/dst is UB, and an empty StringRef is + // represented with {nullptr, 0}. Make sure we don't copy anything in that + // case. + if (!InputData.empty()) + memcpy(Buf->getBufferStart(), InputData.data(), InputData.size()); return std::move(Buf); } diff --git a/llvm/unittests/Support/MemoryBufferTest.cpp b/llvm/unittests/Support/MemoryBufferTest.cpp --- a/llvm/unittests/Support/MemoryBufferTest.cpp +++ b/llvm/unittests/Support/MemoryBufferTest.cpp @@ -161,6 +161,10 @@ // verify the two copies do not point to the same place EXPECT_NE(MBC1->getBufferStart(), MBC2->getBufferStart()); + + // check that copies from defaulted stringrefs don't trigger UB. + OwningBuffer MBC3(MemoryBuffer::getMemBufferCopy(StringRef{})); + EXPECT_NE(nullptr, MBC3.get()); } #if LLVM_ENABLE_THREADS