Index: COFF/Config.h =================================================================== --- COFF/Config.h +++ COFF/Config.h @@ -94,7 +94,8 @@ bool DoICF = true; bool TailMerge; bool Relocatable = true; - bool Force = false; + bool ForceUnresolved = false; + bool ForceMultiple = false; bool Debug = false; bool DebugDwarf = false; bool DebugGHashes = false; Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -944,9 +944,11 @@ Config->Verbose = true; errorHandler().Verbose = Config->Verbose; - // Handle /force or /force:unresolved + // Handle /force, /force:unresolved, and /force:multiple if (Args.hasArg(OPT_force, OPT_force_unresolved)) - Config->Force = true; + Config->ForceUnresolved = true; + if (Args.hasArg(OPT_force, OPT_force_multiple)) + Config->ForceMultiple = true; // Handle /debug if (Args.hasArg(OPT_debug, OPT_debug_dwarf, OPT_debug_ghash)) { Index: COFF/InputFiles.cpp =================================================================== --- COFF/InputFiles.cpp +++ COFF/InputFiles.cpp @@ -55,7 +55,8 @@ if (auto *U = dyn_cast(Source)) { if (U->WeakAlias && U->WeakAlias != Target) Symtab->reportDuplicate(Source, F); - U->WeakAlias = Target; + else + U->WeakAlias = Target; } } @@ -430,7 +431,7 @@ // If type is function, we need to create a thunk which jump to an // address pointed by the __imp_ symbol. (This allows you to call // DLL functions just like regular non-DLL functions.) - if (Hdr->getType() == llvm::COFF::IMPORT_CODE) + if (Hdr->getType() == llvm::COFF::IMPORT_CODE && ImpSym) ThunkSym = Symtab->addImportThunk(Name, ImpSym, Hdr->Machine); } Index: COFF/Options.td =================================================================== --- COFF/Options.td +++ COFF/Options.td @@ -97,8 +97,9 @@ def wholearchive_flag : F<"wholearchive">; def force : F<"force">, - HelpText<"Allow undefined symbols when creating executables">; + HelpText<"Allow undefined or duplicate symbols when creating executables">; def force_unresolved : F<"force:unresolved">; +def force_multiple : F<"force:multiple">; defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">; defm allowbind : B<"allowbind", "Enable DLL binding (default)", Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -59,8 +59,8 @@ Driver->parseDirectives(S); } -static void errorOrWarn(const Twine &S) { - if (Config->Force) +static void errorOrWarn(bool just_warn, const Twine &S) { + if (just_warn) warn(S); else error(S); @@ -171,7 +171,7 @@ // Remaining undefined symbols are not fatal if /force is specified. // They are replaced with dummy defined symbols. - if (Config->Force) + if (Config->ForceUnresolved) replaceSymbol(Sym, Name, 0); Undefs.insert(Sym); } @@ -181,7 +181,8 @@ for (Symbol *B : Config->GCRoot) { if (Undefs.count(B)) - errorOrWarn(": undefined symbol: " + B->getName()); + errorOrWarn(Config->ForceUnresolved, + ": undefined symbol: " + B->getName()); if (Config->WarnLocallyDefinedImported) if (Symbol *Imp = LocalImports.lookup(B)) warn(": locally defined symbol imported: " + Imp->getName() + @@ -195,7 +196,8 @@ if (!Sym) continue; if (Undefs.count(Sym)) - errorOrWarn("undefined symbol: " + Sym->getName() + + errorOrWarn(Config->ForceUnresolved, + "undefined symbol: " + Sym->getName() + getSymbolLocations(File, SymIndex)); if (Config->WarnLocallyDefinedImported) if (Symbol *Imp = LocalImports.lookup(Sym)) @@ -253,8 +255,9 @@ } void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { - error("duplicate symbol: " + toString(*Existing) + " in " + - toString(Existing->getFile()) + " and in " + toString(NewFile)); + errorOrWarn(Config->ForceMultiple, + "duplicate symbol: " + toString(*Existing) + " in " + + toString(Existing->getFile()) + " and in " + toString(NewFile)); } Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) { @@ -353,7 +356,7 @@ } reportDuplicate(S, F); - return nullptr; + return dyn_cast(S); } DefinedImportThunk *SymbolTable::addImportThunk(StringRef Name, @@ -369,7 +372,7 @@ } reportDuplicate(S, ID->File); - return nullptr; + return dyn_cast(S); } std::vector SymbolTable::getChunks() {