diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 83ccdb5caeaff4..9e8bee9c10b3b1 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -6452,8 +6452,8 @@ TEST_P(ImportSourceLocations, OverwrittenFileBuffer) { llvm::SmallVector Buffer; Buffer.append(Contents.begin(), Contents.end()); - auto FileContents = - std::make_unique(std::move(Buffer), Path); + auto FileContents = std::make_unique( + std::move(Buffer), Path, /*RequiresNullTerminator=*/false); FromSM.overrideFileContents(&FE, std::move(FileContents)); // Import the VarDecl to trigger the importing of the FileID. diff --git a/clang/unittests/Frontend/TextDiagnosticTest.cpp b/clang/unittests/Frontend/TextDiagnosticTest.cpp index 220cff6643d506..3acd89a985ab80 100644 --- a/clang/unittests/Frontend/TextDiagnosticTest.cpp +++ b/clang/unittests/Frontend/TextDiagnosticTest.cpp @@ -54,7 +54,7 @@ TEST(TextDiagnostic, ShowLine) { llvm::SmallVector buffer; buffer.append(main_file_contents.begin(), main_file_contents.end()); auto file_contents = std::make_unique( - std::move(buffer), file_path); + std::move(buffer), file_path, /*RequiresNullTerminator=*/false); SrcMgr.overrideFileContents(fe, std::move(file_contents)); // Create the actual file id and use it as the main file. diff --git a/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h b/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h index af748cf962b00c..f7f2d4e54e705d 100644 --- a/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h +++ b/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h @@ -28,17 +28,21 @@ namespace llvm { /// MemoryBuffer). class SmallVectorMemoryBuffer : public MemoryBuffer { public: - /// Construct an SmallVectorMemoryBuffer from the given SmallVector - /// r-value. - SmallVectorMemoryBuffer(SmallVectorImpl &&SV) - : SV(std::move(SV)), BufferName("") { - init(this->SV.begin(), this->SV.end(), false); - } - - /// Construct a named SmallVectorMemoryBuffer from the given - /// SmallVector r-value and StringRef. - SmallVectorMemoryBuffer(SmallVectorImpl &&SV, StringRef Name) + /// Construct a SmallVectorMemoryBuffer from the given SmallVector r-value. + SmallVectorMemoryBuffer(SmallVectorImpl &&SV, + bool RequiresNullTerminator = true) + : SmallVectorMemoryBuffer(std::move(SV), "", + RequiresNullTerminator) {} + + /// Construct a named SmallVectorMemoryBuffer from the given SmallVector + /// r-value and StringRef. + SmallVectorMemoryBuffer(SmallVectorImpl &&SV, StringRef Name, + bool RequiresNullTerminator = true) : SV(std::move(SV)), BufferName(std::string(Name)) { + if (RequiresNullTerminator) { + this->SV.push_back('\0'); + this->SV.pop_back(); + } init(this->SV.begin(), this->SV.end(), false); } diff --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 200f42aec067a1..ed912280ac826c 100644 --- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -170,8 +170,8 @@ std::unique_ptr MCJIT::emitObject(Module *M) { PM.run(*M); // Flush the output buffer to get the generated code into memory - std::unique_ptr CompiledObjBuffer( - new SmallVectorMemoryBuffer(std::move(ObjBufferSV))); + auto CompiledObjBuffer = std::make_unique( + std::move(ObjBufferSV), /*RequiresNullTerminator=*/false); // If we have an object cache, tell it about the new object. // Note that we're using the compiled image, not the loaded image (as below). diff --git a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp index f8efed15edea32..f3424700525812 100644 --- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp @@ -53,7 +53,8 @@ Expected SimpleCompiler::operator()(Module &M) { } auto ObjBuffer = std::make_unique( - std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer"); + std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer", + /*RequiresNullTerminator=*/false); auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 9474d8c9dafbf6..9aea27f0fdbaf0 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -378,7 +378,8 @@ std::unique_ptr codegenModule(Module &TheModule, // Run codegen now. resulting binary is in OutputBuffer. PM.run(TheModule); } - return std::make_unique(std::move(OutputBuffer)); + return std::make_unique( + std::move(OutputBuffer), /*RequiresNullTerminator=*/false); } /// Manage caching for a single Module. @@ -541,7 +542,8 @@ ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index, auto Index = buildModuleSummaryIndex(TheModule, nullptr, &PSI); WriteBitcodeToFile(TheModule, OS, true, &Index); } - return std::make_unique(std::move(OutputBuffer)); + return std::make_unique( + std::move(OutputBuffer), /*RequiresNullTerminator=*/false); } return codegenModule(TheModule, TM); diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp index ce997464caa733..da8bcec7f3d425 100644 --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -696,7 +696,7 @@ writeArchiveToBuffer(ArrayRef NewMembers, bool WriteSymtab, return std::move(E); return std::make_unique( - std::move(ArchiveBufferVector)); + std::move(ArchiveBufferVector), /*RequiresNullTerminator=*/false); } } // namespace llvm diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp index 9e7b91d730579f..915394b65b12d8 100644 --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -476,9 +476,8 @@ Error objcopy::macho::executeObjcopyOnMachOUniversalBinary( **ObjOrErr, MemStream)) return E; - std::unique_ptr MB = - std::make_unique(std::move(Buffer), - ArchFlagName); + auto MB = std::make_unique( + std::move(Buffer), ArchFlagName, /*RequiresNullTerminator=*/false); Expected> BinaryOrErr = object::createBinary(*MB); if (!BinaryOrErr) return BinaryOrErr.takeError(); diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index ad166487eb78bd..a5963985f78abb 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -236,7 +236,8 @@ createNewArchiveMembers(const MultiFormatConfig &Config, const Archive &Ar) { return createFileError(Ar.getFileName(), Member.takeError()); Member->Buf = std::make_unique( - std::move(Buffer), ChildNameOrErr.get()); + std::move(Buffer), ChildNameOrErr.get(), + /*RequiresNullTerminator=*/false); Member->MemberName = Member->Buf->getBufferIdentifier(); NewArchiveMembers.push_back(std::move(*Member)); } diff --git a/llvm/unittests/Support/MemoryBufferTest.cpp b/llvm/unittests/Support/MemoryBufferTest.cpp index 97bb62df393bb2..c3e7b3c926a6cb 100644 --- a/llvm/unittests/Support/MemoryBufferTest.cpp +++ b/llvm/unittests/Support/MemoryBufferTest.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" @@ -408,4 +409,27 @@ TEST_F(MemoryBufferTest, mmapVolatileNoNull) { EXPECT_EQ(MB->getBufferSize(), std::size_t(FileWrites * 8)); EXPECT_TRUE(MB->getBuffer().startswith("01234567")); } + +// Test that SmallVector without a null terminator gets one. +TEST(SmallVectorMemoryBufferTest, WithoutNullTerminatorRequiresNullTerminator) { + SmallString<0> Data("some data"); + + SmallVectorMemoryBuffer MB(std::move(Data), + /*RequiresNullTerminator=*/true); + EXPECT_EQ(MB.getBufferSize(), 9u); + EXPECT_EQ(MB.getBufferEnd()[0], '\0'); +} + +// Test that SmallVector with a null terminator keeps it. +TEST(SmallVectorMemoryBufferTest, WithNullTerminatorRequiresNullTerminator) { + SmallString<0> Data("some data"); + Data.push_back('\0'); + Data.pop_back(); + + SmallVectorMemoryBuffer MB(std::move(Data), + /*RequiresNullTerminator=*/true); + EXPECT_EQ(MB.getBufferSize(), 9u); + EXPECT_EQ(MB.getBufferEnd()[0], '\0'); } + +} // namespace