]> granicus.if.org Git - llvm/commitdiff
Only computeRelativePath() on new members
authorDavid Callahan <dcallahan@fb.com>
Wed, 30 Nov 2016 22:32:58 +0000 (22:32 +0000)
committerDavid Callahan <dcallahan@fb.com>
Wed, 30 Nov 2016 22:32:58 +0000 (22:32 +0000)
Summary:
When using thin archives, and processing the same archive multiple times, we were mangling existing entries.  The root cause is that we were calling computeRelativePath() more than once.   Here, we only call it when adding new members to an archive.

Note that D27218 changes the way thin archives are printed, and will break the new unit test included here.  Depending on which one lands first, the other will need to be slightly modified.

Reviewers: rafael, davide

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D27217

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288280 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/ArchiveWriter.h
lib/Object/ArchiveWriter.cpp
test/Object/archive-thin-create.test [new file with mode: 0644]

index 6b4084351ddcd13231e986f2bc75aa991f7bc8e5..3e84a5814d796403b247c41b1e15f499940ddcf2 100644 (file)
@@ -25,6 +25,7 @@ struct NewArchiveMember {
   sys::TimePoint<std::chrono::seconds> ModTime;
   unsigned UID = 0, GID = 0, Perms = 0644;
 
+  bool IsNew = false;
   NewArchiveMember() = default;
   NewArchiveMember(MemoryBufferRef BufRef);
 
index 64d04a0c72949c56843ebe68c41f191fa901861d..f8e3c5a0a03f7f04ba14fe65ea291212776d0c82 100644 (file)
@@ -45,6 +45,7 @@ NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
     return BufOrErr.takeError();
 
   NewArchiveMember M;
+  assert(M.IsNew == false);
   M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
   if (!Deterministic) {
     auto ModTimeOrErr = OldMember.getLastModified();
@@ -93,6 +94,7 @@ Expected<NewArchiveMember> NewArchiveMember::getFile(StringRef FileName,
     return errorCodeToError(std::error_code(errno, std::generic_category()));
 
   NewArchiveMember M;
+  M.IsNew = true;
   M.Buf = std::move(*MemberBufferOrErr);
   if (!Deterministic) {
     M.ModTime = std::chrono::time_point_cast<std::chrono::seconds>(
@@ -231,9 +233,12 @@ static void writeStringTable(raw_fd_ostream &Out, StringRef ArcName,
     }
     StringMapIndexes.push_back(Out.tell() - StartOffset);
 
-    if (Thin)
-      Out << computeRelativePath(ArcName, Path);
-    else
+    if (Thin) {
+      if (M.IsNew)
+        Out << computeRelativePath(ArcName, Path);
+      else
+        Out << M.Buf->getBufferIdentifier();
+    } else
       Out << Name;
 
     Out << "/\n";
diff --git a/test/Object/archive-thin-create.test b/test/Object/archive-thin-create.test
new file mode 100644 (file)
index 0000000..d9ee518
--- /dev/null
@@ -0,0 +1,14 @@
+RUN: mkdir -p %t
+RUN: cd %t
+RUN: mkdir -p foo
+RUN: touch foo/test1.o
+RUN: touch foo/test2.o
+RUN: llvm-ar qcT foo/libtest.a foo/test1.o
+RUN: llvm-ar qcT foo/libtest.a foo/test1.o
+RUN: llvm-ar qcT foo/libtest.a foo/test2.o
+RUN: llvm-ar t foo/libtest.a | FileCheck %s
+
+CHECK: test1.o
+CHECK: test1.o
+CHECK: test2.o
+