Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -430,26 +430,28 @@ assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN && "must handle /subsystem before calling this"); - // As a special case, if /nodefaultlib is given, we directly look for an - // entry point. This is because, if no default library is linked, users - // need to define an entry point instead of a "main". - bool FindMain = !Config->NoDefaultLibAll; if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) { - if (findUnderscoreMangle(FindMain ? "WinMain" : "WinMainCRTStartup")) - return mangle("WinMainCRTStartup"); - if (findUnderscoreMangle(FindMain ? "wWinMain" : "wWinMainCRTStartup")) - return mangle("wWinMainCRTStartup"); - } - if (findUnderscoreMangle(FindMain ? "main" : "mainCRTStartup")) - return mangle("mainCRTStartup"); - if (findUnderscoreMangle(FindMain ? "wmain" : "wmainCRTStartup")) - return mangle("wmainCRTStartup"); - return ""; + if (findUnderscoreMangle("wWinMain")) { + if (!findUnderscoreMangle("WinMain")) + return mangle("wWinMainCRTStartup"); + warn("found both wWinMain and WinMain; using latter"); + } + return mangle("WinMainCRTStartup"); + } + if (findUnderscoreMangle("wmain")) { + if (!findUnderscoreMangle("main")) + return mangle("wmainCRTStartup"); + warn("found both wmain and main; using latter"); + } + return mangle("mainCRTStartup"); } WindowsSubsystem LinkerDriver::inferSubsystem() { if (Config->DLL) return IMAGE_SUBSYSTEM_WINDOWS_GUI; + // Note that link.exe infers the subsystem from the presence of these + // functions even if /entry: or /nodefaultlib are passed which causes them + // to not be called. bool HaveMain = findUnderscoreMangle("main"); bool HaveWMain = findUnderscoreMangle("wmain"); bool HaveWinMain = findUnderscoreMangle("WinMain"); Index: test/COFF/entry-inference.test =================================================================== --- test/COFF/entry-inference.test +++ test/COFF/entry-inference.test @@ -1,18 +1,26 @@ # RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=MAIN %s < %t.log +# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: FileCheck -check-prefix=MAIN %s < %t.log # RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=WMAIN %s < %t.log +# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: FileCheck -check-prefix=WMAIN %s < %t.log # RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=WINMAIN %s < %t.log +# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log # RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log +# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log # MAIN: error: : undefined symbol: mainCRTStartup # WMAIN: error: : undefined symbol: wmainCRTStartup Index: test/COFF/entry-inference4.test =================================================================== --- test/COFF/entry-inference4.test +++ test/COFF/entry-inference4.test @@ -14,10 +14,22 @@ # RUN: not lld-link /subsystem:console /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=WMAIN %s < %t.log -# MAIN: error: : undefined symbol: mainCRTStartup -# WMAIN: error: : undefined symbol: wmainCRTStartup -# WINMAIN: error: : undefined symbol: WinMainCRTStartup -# WWINMAIN: error: : undefined symbol: wWinMainCRTStartup +# RUN: sed 's/ENTRY1/wmain/;s/ENTRY2/main/' %s | yaml2obj > %t.obj +# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: FileCheck -check-prefix=MAINWMAIN %s < %t.log + +# RUN: sed 's/ENTRY1/wWinMain/;s/ENTRY2/WinMain/' %s | yaml2obj > %t.obj +# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: FileCheck -check-prefix=WINMAINWWINMAIN %s < %t.log + +# MAIN: error: : undefined symbol: mainCRTStartup +# WMAIN: error: : undefined symbol: wmainCRTStartup +# MAINWMAIN: warning: found both wmain and main; using latter +# MAINWMAIN: error: : undefined symbol: mainCRTStartup +# WINMAIN: error: : undefined symbol: WinMainCRTStartup +# WWINMAIN: error: : undefined symbol: wWinMainCRTStartup +# WINMAINWWINMAIN: warning: found both wWinMain and WinMain; using latter +# WINMAINWWINMAIN: error: : undefined symbol: WinMainCRTStartup --- !COFF header: