Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -341,6 +341,13 @@ if (Config->Relocatable) return UnresolvedPolicy::Ignore; + if (auto *Arg = Args.getLastArg(OPT_warn_undef, OPT_error_undef)) { + if (Arg->getOption().getID() == OPT_warn_undef) + return UnresolvedPolicy::Warn; + + return UnresolvedPolicy::ReportError; + } + if (auto *Arg = Args.getLastArg(OPT_unresolved_symbols)) { StringRef S = Arg->getValue(); if (S == "ignore-all" || S == "ignore-in-object-files") Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -79,6 +79,9 @@ def error_limit: S<"error-limit">, HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">; +def error_undef: F<"error-unresolved-symbols">, + HelpText<"Report unresolved symbols as errors">; + def export_dynamic: F<"export-dynamic">, HelpText<"Put symbols in the dynamic symbol table">; @@ -248,6 +251,9 @@ def warn_common: F<"warn-common">, HelpText<"Warn about duplicate common symbols">; +def warn_undef: F<"warn-unresolved-symbols">, + HelpText<"Report unresolved symbols as warnings">; + def whole_archive: F<"whole-archive">, HelpText<"Force load of all members in a static library">; Index: test/ELF/warn-unresolved-symbols.s =================================================================== --- /dev/null +++ test/ELF/warn-unresolved-symbols.s @@ -0,0 +1,39 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/unresolved-symbols.s -o %t2.o + +## The link should fail with an undef error by default +# RUN: not ld.lld %t1.o %t2.o -o %t3 2>&1 | \ +# RUN: FileCheck -check-prefix=ERRUND %s + +## --error-unresolved-symbols should generate an error +# RUN: not ld.lld %t1.o %t2.o -o %t4 --error-unresolved-symbols 2>&1 | \ +# RUN: FileCheck -check-prefix=ERRUND %s + +## --warn-unresolved-symbols should generate a warning +# RUN: ld.lld %t1.o %t2.o -o %t5 --warn-unresolved-symbols 2>&1 | \ +# RUN: FileCheck -check-prefix=WARNUND %s + +## Test that the last option wins +# RUN: ld.lld %t1.o %t2.o -o %t5 --error-unresolved-symbols --warn-unresolved-symbols 2>&1 | \ +# RUN: FileCheck -check-prefix=WARNUND %s +# RUN: not ld.lld %t1.o %t2.o -o %t6 --warn-unresolved-symbols --error-unresolved-symbols 2>&1 | \ +# RUN: FileCheck -check-prefix=ERRUND %s + +## Do not report undefines if linking relocatable or shared. +# RUN: ld.lld -r %t1.o %t2.o -o %t7 --error-unresolved-symbols 2>&1 | \ +# RUN: FileCheck -allow-empty -check-prefix=NOERR %s +# RUN: ld.lld -shared %t1.o %t2.o -o %t8.so --error-unresolved-symbols 2>&1 | \ +# RUN: FileCheck -allow-empty -check-prefix=NOERR %s +# RUN: ld.lld -r %t1.o %t2.o -o %t9 --warn-unresolved-symbols 2>&1 | \ +# RUN: FileCheck -allow-empty -check-prefix=NOWARN %s +# RUN: ld.lld -shared %t1.o %t2.o -o %t10.so --warn-unresolved-symbols 2>&1 | \ +# RUN: FileCheck -allow-empty -check-prefix=NOWARN %s + +# ERRUND: error: {{.*}}:(.text+0x1): undefined symbol 'undef' +# WARNUND: warning: {{.*}}:(.text+0x1): undefined symbol 'undef' +# NOERR-NOT: error: {{.*}}:(.text+0x1): undefined symbol 'undef' +# NOWARN-NOT: warning: {{.*}}:(.text+0x1): undefined symbol 'undef' + +.globl _start +_start: