diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp --- a/llvm/lib/Object/Archive.cpp +++ b/llvm/lib/Object/Archive.cpp @@ -392,12 +392,8 @@ } Expected Archive::Child::getSize() const { - if (Parent->IsThin) { - Expected Size = Header.getSize(); - if (!Size) - return Size.takeError(); - return Size.get(); - } + if (Parent->IsThin) + return Header.getSize(); return Data.size() - StartOfFile; } @@ -437,7 +433,7 @@ return isThinOrErr.takeError(); bool isThin = isThinOrErr.get(); if (!isThin) { - Expected Size = getSize(); + Expected Size = getSize(); if (!Size) return Size.takeError(); return StringRef(Data.data() + StartOfFile, Size.get()); diff --git a/llvm/unittests/Object/ArchiveTest.cpp b/llvm/unittests/Object/ArchiveTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/Object/ArchiveTest.cpp @@ -0,0 +1,74 @@ +//===- ArchiveTest.cpp ----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/Archive.h" +#include "llvm/Testing/Support/Error.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace object; + +static char const ArchiveWithMember[] = "!\n" // Global header + "test/ " // Member name + "0 " // Timestamp + "0 " // Owner ID + "0 " // Group ID + "0 " // File mode + "9999999999" // Size + "`\n"; + +static char const ThinArchiveWithMember[] = "!\n" // Global header + "test/ " // Member name + "0 " // Timestamp + "0 " // Owner ID + "0 " // Group ID + "0 " // File mode + "9999999999" // Size + "`\n"; + +TEST(ArchiveTests, ArchiveChildGetSizeRegularArchive) { + MemoryBufferRef Source(ArchiveWithMember, "regular"); + Expected> A = Archive::create(Source); + ASSERT_THAT_EXPECTED(A, Succeeded()); + Error ChildErr = Error::success(); + auto Child = (*A)->child_begin(ChildErr); + ASSERT_THAT_ERROR(std::move(ChildErr), Succeeded()); + + Expected Size = Child->getSize(); + ASSERT_THAT_EXPECTED(Size, Succeeded()); + EXPECT_EQ(9999999999, *Size); +} + +TEST(ArchiveTests, ArchiveChildGetSizeThinArchive) { + MemoryBufferRef Source(ThinArchiveWithMember, "thin"); + Expected> A = Archive::create(Source); + ASSERT_THAT_EXPECTED(A, Succeeded()); + Error ChildErr = Error::success(); + auto Child = (*A)->child_begin(ChildErr); + ASSERT_THAT_ERROR(std::move(ChildErr), Succeeded()); + + Expected Size = Child->getSize(); + ASSERT_THAT_EXPECTED(Size, Succeeded()); + EXPECT_EQ(9999999999, *Size); +} + +TEST(ArchiveTests, ArchiveChildGetBuffer) { + MemoryBufferRef Source(ArchiveWithMember, "regular"); + Expected> A = Archive::create(Source); + ASSERT_THAT_EXPECTED(A, Succeeded()); + Error ChildErr = Error::success(); + auto Child = (*A)->child_begin(ChildErr); + ASSERT_THAT_ERROR(std::move(ChildErr), Succeeded()); + + Expected Buffer = Child->getBuffer(); + // Cannot use ASSERT_THAT_EXPECTED, as that will attempt to print the + // StringRef (which has an invalid size). + ASSERT_TRUE(Buffer.operator bool()); + EXPECT_EQ(9999999999, Buffer->size()); + EXPECT_EQ(ArchiveWithMember + sizeof(ArchiveWithMember) - 1, Buffer->data()); +} diff --git a/llvm/unittests/Object/CMakeLists.txt b/llvm/unittests/Object/CMakeLists.txt --- a/llvm/unittests/Object/CMakeLists.txt +++ b/llvm/unittests/Object/CMakeLists.txt @@ -4,6 +4,7 @@ ) add_llvm_unittest(ObjectTests + ArchiveTest.cpp MinidumpTest.cpp ObjectFileTest.cpp SymbolSizeTest.cpp