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,81 @@ +//===- 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; +using namespace testing; + +static const char ArchiveWithMember[] = "!\n" // Global header + "test/ " // Member name + "0 " // Timestamp + "0 " // Owner ID + "0 " // Group ID + "0 " // File mode + "9999999999" // Size + "`\n"; + +static const char ThinArchiveWithMember[] = "!\n" // Global header + "test/ " // Member name + "0 " // Timestamp + "0 " // Owner ID + "0 " // Group ID + "0 " // File mode + "9999999999" // Size + "`\n"; + +struct ArchiveTestsFixture : Test { + Expected createChild(StringRef Src) { + MemoryBufferRef Source(Src, "archive"); + Expected> AOrErr = Archive::create(Source); + if (!AOrErr) + return AOrErr.takeError(); + A = std::move(*AOrErr); + + Error ChildErr = Error::success(); + auto Child = A->child_begin(ChildErr); + if (ChildErr) + return std::move(ChildErr); + return Child; + } + + std::unique_ptr A; +}; + +TEST_F(ArchiveTestsFixture, ArchiveChildGetSizeRegularArchive) { + auto Child = createChild(ArchiveWithMember); + ASSERT_THAT_EXPECTED(Child, Succeeded()); + + Expected Size = (*Child)->getSize(); + ASSERT_THAT_EXPECTED(Size, Succeeded()); + EXPECT_EQ(9999999999, *Size); +} + +TEST_F(ArchiveTestsFixture, ArchiveChildGetSizeThinArchive) { + auto Child = createChild(ThinArchiveWithMember); + ASSERT_THAT_EXPECTED(Child, Succeeded()); + + Expected Size = (*Child)->getSize(); + ASSERT_THAT_EXPECTED(Size, Succeeded()); + EXPECT_EQ(9999999999, *Size); +} + +TEST_F(ArchiveTestsFixture, ArchiveChildGetBuffer) { + auto Child = createChild(ArchiveWithMember); + ASSERT_THAT_EXPECTED(Child, 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((bool)Buffer); + 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