Index: Common/Args.cpp =================================================================== --- Common/Args.cpp +++ Common/Args.cpp @@ -40,16 +40,16 @@ uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id, StringRef Key, uint64_t Default) { + uint64_t Result = Default; for (auto *Arg : Args.filtered(Id)) { std::pair KV = StringRef(Arg->getValue()).split('='); if (KV.first == Key) { - uint64_t Result = Default; if (!to_integer(KV.second, Result)) error("invalid " + Key + ": " + KV.second); - return Result; + Arg->claim(); } } - return Default; + return Result; } std::vector lld::args::getLines(MemoryBufferRef MB) { Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -307,7 +307,15 @@ return getenv("LLD_REPRODUCE"); } +static void claimZOptions(opt::InputArgList &Args, ArrayRef Keys) { + for (auto *Arg : Args.filtered(OPT_z)) + for (StringRef K : Keys) + if (Arg->getValue() == K) + Arg->claim(); +} + static bool hasZOption(opt::InputArgList &Args, StringRef Key) { + claimZOptions(Args, {Key}); for (auto *Arg : Args.filtered(OPT_z)) if (Key == Arg->getValue()) return true; @@ -316,6 +324,7 @@ static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2, bool Default) { + claimZOptions(Args, {K1, K2}); for (auto *Arg : Args.filtered_reverse(OPT_z)) { if (K1 == Arg->getValue()) return true; @@ -417,6 +426,8 @@ // Determines what we should do if there are remaining unresolved // symbols after the name resolution. static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) { + claimZOptions(Args, {"defs"}); + if (Args.hasArg(OPT_relocatable)) return UnresolvedPolicy::IgnoreAll; @@ -679,9 +690,9 @@ ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); Config->AllowMultipleDefinition = + hasZOption(Args, "muldefs") || Args.hasFlag(OPT_allow_multiple_definition, - OPT_no_allow_multiple_definition, false) || - hasZOption(Args, "muldefs"); + OPT_no_allow_multiple_definition, false); Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary); Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); @@ -1205,6 +1216,10 @@ Config->MaxPageSize = getMaxPageSize(Args); Config->ImageBase = getImageBase(Args); + for (auto *Arg : Args.filtered(OPT_z)) + if (!Arg->isClaimed()) + warn("unknown -z value: " + StringRef(Arg->getValue())); + // If a -hash-style option was not given, set to a default value, // which varies depending on the target. if (!Args.hasArg(OPT_hash_style)) { Index: test/ELF/invalid-z.s =================================================================== --- test/ELF/invalid-z.s +++ test/ELF/invalid-z.s @@ -4,6 +4,10 @@ # CHECK: invalid max-page-size # CHECK-NOT: error +# RUN: ld.lld %t.o -o %t -z foobar 2>&1 | \ +# RUN: FileCheck %s --check-prefix=UNKNOWN +# UNKNOWN: warning: unknown -z value: foobar + .global _start _start: nop