diff --git a/lld/test/wasm/early-exit-for-bad-paths.s b/lld/test/wasm/early-exit-for-bad-paths.s new file mode 100644 --- /dev/null +++ b/lld/test/wasm/early-exit-for-bad-paths.s @@ -0,0 +1,22 @@ +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o + +# RUN: not wasm-ld %t.o -o does_not_exist/output 2>&1 | \ +# RUN: FileCheck %s -check-prefixes=NO-DIR-OUTPUT,CHECK +# RUN: not wasm-ld %t.o -o %s/dir_is_a_file 2>&1 | \ +# RUN: FileCheck %s -check-prefixes=DIR-IS-OUTPUT,CHECK +# TODO(sbc): check similar check for -Map file once we add that option + +# NO-DIR-OUTPUT: error: cannot open output file does_not_exist/output: +# DIR-IS-OUTPUT: error: cannot open output file {{.*}}/dir_is_a_file: + +# We should exit before doing the actual link. If an undefined symbol error is +# discovered we haven't bailed out early as expected. +# CHECK-NOT: undefined_symbol + +# RUN: not wasm-ld %t.o -o / 2>&1 | FileCheck %s -check-prefixes=ROOT,CHECK +# ROOT: error: cannot open output file / + +_start: + .functype _start () -> () + call undefined_symbol + end_function diff --git a/lld/test/wasm/lto/opt-level.ll b/lld/test/wasm/lto/opt-level.ll --- a/lld/test/wasm/lto/opt-level.ll +++ b/lld/test/wasm/lto/opt-level.ll @@ -11,7 +11,7 @@ ; RUN: FileCheck --check-prefix=INVALID %s ; INVALID: invalid optimization level for LTO: 6 -; RUN: not wasm-ld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \ +; RUN: not wasm-ld -o %t3 -e main --lto-O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s ; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295 diff --git a/lld/test/wasm/responsefile.test b/lld/test/wasm/responsefile.test --- a/lld/test/wasm/responsefile.test +++ b/lld/test/wasm/responsefile.test @@ -10,11 +10,11 @@ INVRSP: invalid response file quoting: foobar RUN: echo "blah\foo" > %t.rsp -RUN: not wasm-ld --rsp-quoting=windows @%t.rsp 2>&1 | \ +RUN: not wasm-ld -o a.out --rsp-quoting=windows @%t.rsp 2>&1 | \ RUN: FileCheck --check-prefix=WINRSP %s WINRSP: error: cannot open blah\foo: RUN: echo "blah\foo" > %t.rsp -RUN: not wasm-ld --rsp-quoting=posix @%t.rsp 2>&1 | \ +RUN: not wasm-ld -o a.out --rsp-quoting=posix @%t.rsp 2>&1 | \ RUN: FileCheck --check-prefix=POSRSP %s POSRSP: error: cannot open blahfoo: diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -15,6 +15,7 @@ #include "Writer.h" #include "lld/Common/Args.h" #include "lld/Common/ErrorHandler.h" +#include "lld/Common/Filesystem.h" #include "lld/Common/Memory.h" #include "lld/Common/Reproduce.h" #include "lld/Common/Strings.h" @@ -304,6 +305,8 @@ break; } } + if (files.empty() && errorCount() == 0) + error("no input files"); } static StringRef getEntry(opt::InputArgList &args) { @@ -716,16 +719,27 @@ errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20); readConfigs(args); + + createFiles(args); + if (errorCount()) + return; + setConfigs(); checkOptions(args); + if (errorCount()) + return; if (auto *arg = args.getLastArg(OPT_allow_undefined_file)) readImportFile(arg->getValue()); - if (!args.hasArg(OPT_INPUT)) { - error("no input files"); + // Fail early if the output file or map file is not writable. If a user has a + // long link, e.g. due to a large LTO link, they do not wish to run it and + // find that it failed because there was a mistake in their command-line. + if (auto e = tryCreateFile(config->outputFile)) + error("cannot open output file " + config->outputFile + ": " + e.message()); + // TODO(sbc): add check for map file too once we add support for that. + if (errorCount()) return; - } // Handle --trace-symbol. for (auto *arg : args.filtered(OPT_trace_symbol)) @@ -736,10 +750,6 @@ createSyntheticSymbols(); - createFiles(args); - if (errorCount()) - return; - // Add all files to the symbol table. This will add almost all // symbols that we need to the symbol table. for (InputFile *f : files)