Index: lld/MachO/LTO.cpp =================================================================== --- lld/MachO/LTO.cpp +++ lld/MachO/LTO.cpp @@ -138,8 +138,21 @@ saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o"); } - if (!config->ltoObjPath.empty()) - fs::create_directories(config->ltoObjPath); + // In ThinLTO mode, Clang passes a temporary directory in -object_path_lto, + // while the argument is a single file in FullLTO mode. + bool objPathIsDir = true; + if (!config->ltoObjPath.empty()) { + if (!fs::exists(config->ltoObjPath)) { + fs::create_directories(config->ltoObjPath); + } else if (!fs::is_directory(config->ltoObjPath)) { + objPathIsDir = false; + + unsigned objCount = + count_if(buf, [](const SmallString<0> &b) { return !b.empty(); }); + if (objCount > 1) + fatal("-object_path_lto must specify a directory when using ThinLTO"); + } + } std::vector ret; for (unsigned i = 0; i != maxTasks; ++i) { @@ -149,9 +162,10 @@ uint32_t modTime = 0; if (!config->ltoObjPath.empty()) { filePath = config->ltoObjPath; - path::append(filePath, Twine(i) + "." + - getArchitectureName(config->arch()) + - ".lto.o"); + if (objPathIsDir) + path::append(filePath, Twine(i) + "." + + getArchitectureName(config->arch()) + + ".lto.o"); saveBuffer(buf[i], filePath); modTime = getModTime(filePath); } Index: lld/test/MachO/lto-object-path.ll =================================================================== --- lld/test/MachO/lto-object-path.ll +++ lld/test/MachO/lto-object-path.ll @@ -8,16 +8,21 @@ ; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes CHECK,NOOBJPATH ; RUN: %lld %t/test.o -o %t/test -object_path_lto %t/lto-temps -; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes CHECK,OBJPATH -DDIR=%t/lto-temps +; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes CHECK,OBJPATH-DIR -DDIR=%t/lto-temps -; CHECK: 0000000000000000 - 00 0000 SO /tmp/test.cpp -; NOOBJPATH-NEXT: 0000000000000000 - 03 0001 OSO /tmp/lto.tmp +; RUN: %lld %t/test.o -o %t/test -object_path_lto %t/lto-tmp.o +; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes CHECK,OBJPATH-FILE -DFILE=%t/lto-tmp.o + + +; CHECK: 0000000000000000 - 00 0000 SO /tmp/test.cpp +; NOOBJPATH-NEXT: 0000000000000000 - 03 0001 OSO /tmp/lto.tmp ;; check that modTime is nonzero when `-object_path_lto` is provided -; OBJPATH-NEXT: {{[0-9a-f]*[1-9a-f]+[0-9a-f]*}} - 03 0001 OSO [[DIR]]/0.x86_64.lto.o -; CHECK-NEXT: {{[0-9a-f]+}} - 01 0000 FUN _main -; CHECK-NEXT: 0000000000000001 - 00 0000 FUN -; CHECK-NEXT: 0000000000000000 - 01 0000 SO -; CHECK-NEXT: {{[0-9a-f]+}} T _main +; OBJPATH-DIR-NEXT: {{[0-9a-f]*[1-9a-f]+[0-9a-f]*}} - 03 0001 OSO [[DIR]]/0.x86_64.lto.o +; OBJPATH-FILE-NEXT: {{[0-9a-f]*[1-9a-f]+[0-9a-f]*}} - 03 0001 OSO [[FILE]] +; CHECK-NEXT: {{[0-9a-f]+}} - 01 0000 FUN _main +; CHECK-NEXT: 0000000000000001 - 00 0000 FUN +; CHECK-NEXT: 0000000000000000 - 01 0000 SO +; CHECK-NEXT: {{[0-9a-f]+}} T _main target triple = "x86_64-apple-macosx10.15.0" target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"