[llvm] 67220c2 - [ORC] Fix serialization / deserialization of default-constructed ArrayRef<char>.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 18 20:39:08 PDT 2022


Author: Lang Hames
Date: 2022-07-18T20:39:01-07:00
New Revision: 67220c2ad72e32cea18bb261366e64fe5de75b16

URL: https://github.com/llvm/llvm-project/commit/67220c2ad72e32cea18bb261366e64fe5de75b16
DIFF: https://github.com/llvm/llvm-project/commit/67220c2ad72e32cea18bb261366e64fe5de75b16.diff

LOG: [ORC] Fix serialization / deserialization of default-constructed ArrayRef<char>.

Avoids a zero-length memcpy from a null src, which caused errors on some of the
sanitizer bots. Also uses null when deserializing an empty ArrayRef (rather
than pointing to a zero length range in the middle of the input buffer).

Added: 
    

Modified: 
    llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h
    llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h
index 9be58e9f0fa9d..794c07b4e4c0b 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h
@@ -56,6 +56,7 @@ class SPSOutputBuffer {
   SPSOutputBuffer(char *Buffer, size_t Remaining)
       : Buffer(Buffer), Remaining(Remaining) {}
   bool write(const char *Data, size_t Size) {
+    assert(Data && "Data must not be null");
     if (Size > Remaining)
       return false;
     memcpy(Buffer, Data, Size);
@@ -349,6 +350,8 @@ template <> class SPSSerializationTraits<SPSSequence<char>, ArrayRef<char>> {
   static bool serialize(SPSOutputBuffer &OB, const ArrayRef<char> &A) {
     if (!SPSArgList<uint64_t>::serialize(OB, static_cast<uint64_t>(A.size())))
       return false;
+    if (A.empty()) // Empty ArrayRef may have null data, so bail out early.
+      return true;
     return OB.write(A.data(), A.size());
   }
 
@@ -358,7 +361,7 @@ template <> class SPSSerializationTraits<SPSSequence<char>, ArrayRef<char>> {
       return false;
     if (Size > std::numeric_limits<size_t>::max())
       return false;
-    A = {IB.data(), static_cast<size_t>(Size)};
+    A = {Size ? IB.data() : nullptr, static_cast<size_t>(Size)};
     return IB.skip(Size);
   }
 };

diff  --git a/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp b/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp
index 56b6ad6c81df1..f5319e3287766 100644
--- a/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp
@@ -187,3 +187,24 @@ TEST(SimplePackedSerializationTest, ArrayRef) {
   // Input should reference buffer.
   EXPECT_LT(HelloIn.data() - Buffer, BufferSize);
 }
+
+TEST(SimplePackedSerializationTest, ArrayRefEmpty) {
+  // Make sure that empty ArrayRefs serialize and deserialize as expected.
+  // Empty ArrayRefs should not succeed even when the data field is null, and
+  // should deserialize to a default-constructed ArrayRef, not a pointer into
+  // the stream.
+  constexpr unsigned BufferSize = sizeof(uint64_t);
+  char Buffer[BufferSize];
+  memset(Buffer, 0, BufferSize);
+
+  ArrayRef<char> AOut;
+  SPSOutputBuffer OB(Buffer, BufferSize);
+  EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, AOut));
+
+  ArrayRef<char> AIn;
+  SPSInputBuffer IB(Buffer, BufferSize);
+  EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, AIn));
+
+  EXPECT_EQ(AIn.data(), nullptr);
+  EXPECT_EQ(AIn.size(), 0U);
+}


        


More information about the llvm-commits mailing list