Skip to content

Commit 1a18e43

Browse files
committed
Fix thin archive member reproducer paths
Use the parent archive path hash and thin archive member name to form the generated input identity. This prevents members with identical basenames from colliding in --reproduce archives without depending on child offsets. Resolves #1737
1 parent 63cdf1b commit 1a18e43

5 files changed

Lines changed: 40 additions & 1 deletion

File tree

lib/Support/OutputTarWriter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,16 @@ void OutputTarWriter::addInputFile(const InputFile *File, bool IsLTOObject) {
7474
}
7575

7676
std::string OutputTarWriter::getHashAndExtension(const Input *Ipt) const {
77+
uint64_t InputHash = Ipt->getResolvedPathHash();
78+
if (const auto *ArchiveMember = llvm::dyn_cast<ArchiveMemberInput>(Ipt))
79+
// Thin archive members share the parent archive's resolved path. Include
80+
// the member identity so members with the same basename cannot collide.
81+
InputHash = llvm::hash_combine(InputHash, ArchiveMember->getMemberName());
82+
7783
// Returns filename passed to the linker along with the file hash.
7884
return std::string(
7985
llvm::sys::path::filename(Ipt->getInputFile()->getMappedPath())) +
80-
"." + std::to_string(Ipt->getResolvedPathHash());
86+
"." + std::to_string(InputHash);
8187
}
8288

8389
/// Create mapping.ini file of input filepath to its sha2 hash + file extension
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int only_a(void) { return 1; }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int only_b(void) { return 2; }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
extern int only_a(void);
2+
extern int only_b(void);
3+
4+
int main(void) { return only_a() + only_b(); }
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#---ReproduceThinArchiveSameBasename.test----------------- Executable -----------------#
2+
3+
#BEGIN_COMMENT
4+
# Checks that --reproduce preserves thin-archive members with the same basename.
5+
#END_COMMENT
6+
#START_TEST
7+
RUN: %rm -rf %t.tmpdir
8+
RUN: %mkdir %t.tmpdir
9+
RUN: %mkdir %t.tmpdir/a
10+
RUN: %mkdir %t.tmpdir/b
11+
RUN: %clang %clangopts -c %p/Inputs/a/foo.c -o %t.tmpdir/a/foo.o
12+
RUN: %clang %clangopts -c %p/Inputs/b/foo.c -o %t.tmpdir/b/foo.o
13+
RUN: %clang %clangopts -c %p/Inputs/thin-main.c -o %t.tmpdir/main.o
14+
RUN: cd %t.tmpdir
15+
RUN: %ar cr %aropts --thin %t.tmpdir/libsame.a a/foo.o b/foo.o
16+
RUN: %link --no-threads %t.tmpdir/main.o %t.tmpdir/libsame.a -o %t.same.out \
17+
RUN: --reproduce %t.repro.tar --dump-mapping-file %t.mapping.ini
18+
RUN: %filecheck %s < %t.mapping.ini
19+
RUN: %mkdir %t.replay
20+
RUN: %tar %gnutaropts -xf %t.repro.tar -C %t.replay --strip-components=1
21+
RUN: cd %t.replay
22+
RUN: %python -c "import shlex, subprocess; args = shlex.split(open('response.txt').read())[1:]; args[args.index('-o') + 1] = r'%t.same.replay.out'; subprocess.check_call(shlex.split(r'%link') + args)"
23+
RUN: %diff %t.same.out %t.same.replay.out
24+
#END_TEST
25+
26+
CHECK-DAG: Object/foo.o.{{[0-9]+}}
27+
CHECK-DAG: Object/foo.o.{{[0-9]+}}

0 commit comments

Comments
 (0)