Skip to content

Commit b576701

Browse files
committed
[lld][WebAssembly] Early error if output file cannot be created.
This matches the behaviour of the ELF driver. Also move the `createFiles` to be `checkConfig` and report `no input files` there. Again this is mostly to match the structure of the ELF linker better. Differential Revision: https://reviews.llvm.org/D76960
1 parent 6dd696a commit b576701

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
2+
3+
# RUN: not wasm-ld %t.o -o does_not_exist/output 2>&1 | \
4+
# RUN: FileCheck %s -check-prefixes=NO-DIR-OUTPUT,CHECK
5+
# RUN: not wasm-ld %t.o -o %s/dir_is_a_file 2>&1 | \
6+
# RUN: FileCheck %s -check-prefixes=DIR-IS-OUTPUT,CHECK
7+
# TODO(sbc): check similar check for -Map file once we add that option
8+
9+
# NO-DIR-OUTPUT: error: cannot open output file does_not_exist/output:
10+
# DIR-IS-OUTPUT: error: cannot open output file {{.*}}/dir_is_a_file:
11+
12+
# We should exit before doing the actual link. If an undefined symbol error is
13+
# discovered we haven't bailed out early as expected.
14+
# CHECK-NOT: undefined_symbol
15+
16+
# RUN: not wasm-ld %t.o -o / 2>&1 | FileCheck %s -check-prefixes=ROOT,CHECK
17+
# ROOT: error: cannot open output file /
18+
19+
_start:
20+
.functype _start () -> ()
21+
call undefined_symbol
22+
end_function

lld/test/wasm/lto/opt-level.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
; RUN: FileCheck --check-prefix=INVALID %s
1212
; INVALID: invalid optimization level for LTO: 6
1313

14-
; RUN: not wasm-ld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
14+
; RUN: not wasm-ld -o %t3 -e main --lto-O-1 %t.o 2>&1 | \
1515
; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s
1616
; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295
1717

lld/test/wasm/responsefile.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ RUN: FileCheck --check-prefix=INVRSP %s
1010
INVRSP: invalid response file quoting: foobar
1111

1212
RUN: echo "blah\foo" > %t.rsp
13-
RUN: not wasm-ld --rsp-quoting=windows @%t.rsp 2>&1 | \
13+
RUN: not wasm-ld -o a.out --rsp-quoting=windows @%t.rsp 2>&1 | \
1414
RUN: FileCheck --check-prefix=WINRSP %s
1515
WINRSP: error: cannot open blah\foo:
1616

1717
RUN: echo "blah\foo" > %t.rsp
18-
RUN: not wasm-ld --rsp-quoting=posix @%t.rsp 2>&1 | \
18+
RUN: not wasm-ld -o a.out --rsp-quoting=posix @%t.rsp 2>&1 | \
1919
RUN: FileCheck --check-prefix=POSRSP %s
2020
POSRSP: error: cannot open blahfoo:

lld/wasm/Driver.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Writer.h"
1616
#include "lld/Common/Args.h"
1717
#include "lld/Common/ErrorHandler.h"
18+
#include "lld/Common/Filesystem.h"
1819
#include "lld/Common/Memory.h"
1920
#include "lld/Common/Reproduce.h"
2021
#include "lld/Common/Strings.h"
@@ -304,6 +305,8 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
304305
break;
305306
}
306307
}
308+
if (files.empty() && errorCount() == 0)
309+
error("no input files");
307310
}
308311

309312
static StringRef getEntry(opt::InputArgList &args) {
@@ -728,16 +731,27 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
728731
errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20);
729732

730733
readConfigs(args);
734+
735+
createFiles(args);
736+
if (errorCount())
737+
return;
738+
731739
setConfigs();
732740
checkOptions(args);
741+
if (errorCount())
742+
return;
733743

734744
if (auto *arg = args.getLastArg(OPT_allow_undefined_file))
735745
readImportFile(arg->getValue());
736746

737-
if (!args.hasArg(OPT_INPUT)) {
738-
error("no input files");
747+
// Fail early if the output file or map file is not writable. If a user has a
748+
// long link, e.g. due to a large LTO link, they do not wish to run it and
749+
// find that it failed because there was a mistake in their command-line.
750+
if (auto e = tryCreateFile(config->outputFile))
751+
error("cannot open output file " + config->outputFile + ": " + e.message());
752+
// TODO(sbc): add check for map file too once we add support for that.
753+
if (errorCount())
739754
return;
740-
}
741755

742756
// Handle --trace-symbol.
743757
for (auto *arg : args.filtered(OPT_trace_symbol))
@@ -748,10 +762,6 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
748762

749763
createSyntheticSymbols();
750764

751-
createFiles(args);
752-
if (errorCount())
753-
return;
754-
755765
// Add all files to the symbol table. This will add almost all
756766
// symbols that we need to the symbol table.
757767
for (InputFile *f : files)

0 commit comments

Comments
 (0)