Re: [PATCH v1 03/13] aarch64: Mark x18 register as a fixed register for MS ABI
On 22.02.2024 18:45, Andrew Pinski wrote: On Thu, Feb 22, 2024 at 3:56 AM Richard Earnshaw (lists) wrote: On 21/02/2024 18:30, Evgeny Karpov wrote: +/* X18 reserved for the TEB on Windows. */ +#ifdef TARGET_ARM64_MS_ABI +# define FIXED_X18 1 +# define CALL_USED_X18 0 +#else +# define FIXED_X18 0 +# define CALL_USED_X18 1 +#endif I'm not overly keen on ifdefs like this (and the one below), it can get quite confusing if we have to support more than a couple of ABIs. Perhaps we could create a couple of new headers, one for the EABI (which all existing targets would then need to include) and one for the MS ABI. Then the mingw port would use that instead of the EABI header. An alternative is to make all this dynamic, based on the setting of the aarch64_calling_abi enum and to make the adjustments in aarch64_conditional_register_usage. Dynamically might be needed also if we want to support ms_abi attribute and/or -mabi=ms to support the wine folks. Wine no longer needs ms_abi, it was needed for PE-in-ELF modules in the past. We use use proper PE files now, so we need a cross compiler, but no special attributes. aarch64-w64-mingw32 is already well supported by Wine when using llvm-mingw, so as soon as GCC properly supports the ABI, Wine should just work with it, in theory. I didn't try it, but I don't see things like vararg support in this patchset nor in the repo, so I assume it won't work yet. Thanks for the work! Jacek
Re: Enable UTF-8 code page in driver and compiler on 64-bit mingw host [PR108865]
Hi Costas, On 3/7/23 15:00, Costas Argyris wrote: Hi Jacek, "Is there a reason to make it specific to x86_64? It seems to me that all mingw hosts could use it." Are you referring to the 32-bit host? My concern here is that this functionality (embedding the UTF-8 manifest file into the executable) is only truly supported in recent versions of Windows. From: https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page It says that Windows Version 1903 (May 2019 Update) enables this, so we are looking at the 64-bit version of Windows. I suppose you are referring to the scenario where one has a 32-bit gcc + mingw running in a 64-bit Windows that is recent enough to support this? It is not clear to me based on the above doc what would happen encoding-wise in that situation, and I haven't tried it either because I assumed that most people would want the 64-bit version of gcc since they are probably running a 64-bit OS. If you think it is useful, I could look into that as a separate task to try and keep this one simple, if that makes sense. Yes, realistically it's mostly about 32-bit gcc on 64-bit Windows (perhaps aarch64 as well at some point in the future). It's probably indeed not very popular configuration those days, but I think it should work just fine if you didn't explicitly limit the patch to x86_64. "I think that .manifest file should also be a dependency here." Why is that? Windres takes only the .rc file as its input, as per its own doc, and it successfully compiles it into an object file. The .manifest file is only referenced by the .rc file, and it doesn't get passed to windres, so I don't see why it has to be listed as a prerequisite in the make rule. The point that when winnt-utf8.manifest is modified, utf8-mingw32.o should be rebuilt. Anyway, it's probably not a big deal (I should disclaim that I'm not very familiar with gcc build system; I'm mostly on this ML due to mingw-w64 contributions). Thanks, Jacek
Re: Enable UTF-8 code page in driver and compiler on 64-bit mingw host [PR108865]
Hi Costas, On 3/7/23 01:52, Costas Argyris via Gcc-patches wrote: This is a proposal for addressing https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108865 by integrating the UTF-8 manifest file into gcc's build process for the 64-bit mingw host. Is there a reason to make it specific to x86_64? It seems to me that all mingw hosts could use it. +# The resource .rc file references the utf8 .manifest file. +# Compile it into an object file using windres. +# The resulting .o file gets added to host_extra_gcc_objs in +# config.host for x86_64-*-mingw* host and gets linked into +# the driver as a .o file, so it's lack of symbols is OK. +utf8rc-mingw32.o : $(srcdir)/config/i386/utf8-mingw32.rc + $(WINDRES) $< $@ I think that .manifest file should also be a dependency here. Thanks, Jacek
Re: Adding a new thread model to GCC
On 10/24/22 05:40, LIU Hao via Gcc-patches wrote: 在 2022/10/21 20:34, i.nix...@autistici.org 写道: got it... anyway it seems logical to me the way I proposed :) Below is a message forwarded from mingw-w64-public, elaborating the necessity of a new thread model. As there are objections from other mingw-w64 developers, I am putting those patches against mingw-w64-crt on hold for now. Despite that, all threading facilities - mutexes, condition variables, once flags, etc. - are still fully functional within the mcf thread model. In addition, I will keep maintaining my personal builds (from GCC 12 release branch) with these patches at https://gcc-mcf.lhmouse.com/. Forwarded Message 在 2022/10/23 18:06, Jacek Caban 写道: > > Please, let's not do that. It's possible to fix existing implementations, we don't need to make > things more complicated than they are. > Okay okay, I think I have to compose a thorough list of problems that we are facing at the moment, and had better have a permalink to the mailing list archive that I can reference elsewhere. I have been tired of repeating the same grounds of arguments again and again: 1. In a DLL, destructors of static objects and callbacks that are registered with `atexit()`, are executed by `LdrShutdownProcess()`, after all the other thread have been terminated `ZwTerminateProcessO(NULL, status)`. This means that, if another thread has been terminated while holding a mutex, the mutex can never get unlocked. If a destructor attempts to lock the same mutex, deadlocks will occur. Destructors of executables do not suffer from this issue, because they are executed before `RtlExitUserProcess()`. Standard behavior: Static destructors and exit callbacks should be executed while other threads are running. If another thread attempts to access a destroyed object, the behavior is undefined; the user is responsible to prevent this from happening, by joining or suspending it. 2. Following 1, in a DLL, static destructors and exit callbacks are still invoked when `_Exit()` or `quick_exit()` is called. Standard behavior: `_Exit()` should not perform any cleanup; not even open files are flushed. `quick_exit()` shall invoke all quick-exit callbacks in reverse order, then call `_Exit()`. 3. There is a use-after-free bug [1] about thread-local destructors. I suspect this is caused by emutls, because GCC uses `__cxa_thread_atexit()` to register thread-local destructors, which could interleave with `emutls_destroy()`. Standard behavior: This is not allowed to happen. mcfgthread solves this issue by running thread-local destructors and thread-specific key destructors as two separate passes [3]. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80816 [2] https://github.com/gcc-mirror/gcc/blob/f84e4fb44aa26b71fbc64e0532fd24d96e5caa3f/libgcc/emutls.c#L96 [3] https://github.com/lhmouse/mcfgthread/blob/63e034d375caf585e2921cd3455f1048feb2172d/src/xglobals.c#L249 4. In the win32 thread model, thread-specific key destructors are called at process exit [4], after static destructors. Standard behavior: They shall be called only when a thread exits, and the associated thread-specific values are not a null pointer. They shall not be called when a program terminates; instead, users are responsible for deallocating such resources before calling `exit()`. This requirement is missing in POSIX, but formally specified by ISO/IEC 9899:2017, as the 4th paragraph in '7.26.6.1 The tss_create function'. [4] https://github.com/mingw-w64/mingw-w64/blob/d0a034a04d312434b842c4869a8a900568d8db98/mingw-w64-crt/crt/tlsthrd.c#L134 Those 4 points describes problems that you solve in the new threading model, but there is no reason they can't be fixed for existing threading models. In fact, ideally they would be fixed for all threading models. Except now we need to worry about one more threading model, meaning that future bugs will be even harder to fix. 5. Wait operations, of timed mutexes and condition variables, should take absolute time points as `struct timespec`. Standard behavior: Both POSIX and ISO C specifies them as such, while all Windows APIs take relative durations as a 32-bit integer of milliseconds, which can also easily get overflown. This also may be supported in existing threading models. Overflow is trivial to fix by waiting in a loop. (There are other reasons why OS support for absolute timeout is slightly better, but the price of this design decision makes it questionable. I plan to elaborate more on that on mingw ML, but I need to find time to do a bit of research first). Jacek
Re: Adding a new thread model to GCC
On 10/21/22 14:29, LIU Hao wrote: 在 2022/10/21 20:13, Jacek Caban 写道: This is not true for past 15 years, CRITICAL_SECTIONS use something like RtlWaitOnAddress (an equivalent of futexes) since Vista, see Wine implementation for details: https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/sync.c#L190 Ah Jacek, nice to see you here. I haven't dug into this too much, though. From my limited knowledge (mostly from reading disassembly) now CRITICAL_SECTION uses `NtWaitForAlertByThreadId` (and no longer keyed events or semaphores). As with `WaitOnAddress()`, there seems to be some global data structure, protected by a spin lock. It's just another undocumented syscall. Keyed events are still functional. NtWaitForAlertByThreadId() is an underlying syscall that's used by WaitOnAddress(). Anyway, you don't need to worry about that if you just use public CRITICAL_SECTION APIs. Jacek
Re: Adding a new thread model to GCC
On 2022-10-21 11:44, Eric Botcazou via Libstdc++ wrote: /How does this compare with Eric B's proposal at />>>/https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ? />>//>>/My proposal was to reimplement (and extend) the native thread model />>/(win32) />>/instead of adding a new one, the advantage being that you don't need an />>/extra />/> threading layer between GCC and Windows. /> I agree! I agree as well and I expressed that on mingw-w64 ML when the patch was introduced [1]. My main concern with the new threading model is that instead of solving root of the problem, it introduces more fragmentation with no clear benefit. On top of that, mcfgthread library is way more invasive than it needs to be. It requires maintaining per-thread struct and reimplements a number of things instead of leveraging OS capabilities. Author also plans to make invasive changes to mingw-w64-crt, which go against it current approach of being agnostic to threading model. Jacek [1] https://sourceforge.net/p/mingw-w64/mailman/message/37719727/
Re: Adding a new thread model to GCC
The problem about this approach is that, semaphores are valuable kernel objects, and the maximum number of HANDLEs that a process can open concurrently has a limit (like FDs on Linux), while 'many critical sections are used only occasionally (or never at all), meaning the auto-reset event often isn’t even necessary' [1], the semaphores are actually allocated on demand. This means that locking can fail. There is a story in article [1] which also explains the origination of keyed events; it's worth reading. This is not true for past 15 years, CRITICAL_SECTIONS use something like RtlWaitOnAddress (an equivalent of futexes) since Vista, see Wine implementation for details: https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/sync.c#L190 Jacek
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02/07/2019 12:12, Jacek Caban wrote: On 02/07/2019 11:57, Liu Hao wrote: 在 2019/7/2 下午5:19, Eric Botcazou 写道: It seems inappropriate to use handles as thread identifiers (as handles imply resource ownership and are not unique identifiers); thread IDs (as `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. The `OpenThread()` function can obtain a handle by thread ID. It returns a real handle that has to be closed when it is out of use. Using the pseudo handle returned by `GetCurrentThread()` may be more efficient if the target thread ID is equal to `GetCurrentThreadId()`. The problem with thread id is that it's not valid nor guaranteed to be identical after the thread is terminated. A handle needs to be used for that. I meant unique, not identical. Jacek
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02/07/2019 11:57, Liu Hao wrote: 在 2019/7/2 下午5:19, Eric Botcazou 写道: It seems inappropriate to use handles as thread identifiers (as handles imply resource ownership and are not unique identifiers); thread IDs (as `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. The `OpenThread()` function can obtain a handle by thread ID. It returns a real handle that has to be closed when it is out of use. Using the pseudo handle returned by `GetCurrentThread()` may be more efficient if the target thread ID is equal to `GetCurrentThreadId()`. The problem with thread id is that it's not valid nor guaranteed to be identical after the thread is terminated. A handle needs to be used for that. Jacek
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
Hi Eric, On 6/28/19 3:42 PM, NightStrike wrote: FYI, Eric posted this today to the GCC patches list. This may be of great interest to many who would prefer native threads instead of the winpthreads posix style interface. Great work, Eric! I look forward to trying this out! -- Forwarded message - From: Eric Botcazou Date: Fri, Jun 28, 2019 at 6:51 AM Subject: [patch] Reimplement GNU threads library on native Windows To: Cc: Hi, this reimplements the GNU threads library on native Windows (except for the Objective-C specific subset) using direct Win32 API calls, in lieu of the implementation based on semaphores. This base implementations requires Windows XP/Server 2003, which is the default minimal setting of MinGW-W64. This also adds the support required for the C++11 threads, using again direct Win32 API calls; this additional layer requires Windows Vista/Server 2008 and is enabled only if _GTHREADS_USE_COND is defined to 1. This also changes libstdc++ to setting _GTHREADS_USE_COND to 1 when the switch --enable-libstdcxx-threads is passed, which means that C++11 threads are still disabled by default on native Windows and that you need to explicitly pass the switch to enable them. The 30_threads chapter of the testsuite is clean. Tested on i686-pc-mingw32 and x86_64-pc-mingw32, OK for the mainline? It's indeed great to see this. Thank you! +/* The implementation strategy for the c++0x thread support is as follows. + + A GNU thread is represented by a Win32 HANDLE that is obtained when the + Win32 thread is created, except of course for the initial thread. This + Win32 HANDLE is stored in a descriptor keyed from TLS memory for every + thread, so the self routine can return it instead of having to duplicate + the pseudo-handle returned by GetCurrentThread each time it is invoked. + For the initial thread, this Win32 HANDLE is created during the first + call to the self routine using the aforementioned technique. + + Note that the equal routine compares the identifier of threads instead + of their Win32 HANDLE, which will give the correct positive answer even + in the case where distinct Win32 HANDLEs have been created for the same + thread by multiple instances of libgcc included in the link. */ Note that this will cause handle leaks if used across multiple libgcc instances, through. +#include "gthr-win32.h" + +/* The thread descriptor keyed from TLS memory. */ +struct __gthr_win32_thr_desc +{ + void *(*func) (void*); + void *args; + HANDLE h; +}; + +/* The TLS key used by one instance of the library. */ +static __gthread_key_t __gthr_win32_tls = TLS_OUT_OF_INDEXES; + +/* The initialization device for the TLS key. */ +static __gthread_once_t __gthr_win32_tls_once = __GTHREAD_ONCE_INIT; + +/* Initialize the TLS key. */ + +static void +__gthr_win32_tls_init (void) +{ + if (__gthread_key_create (&__gthr_win32_tls, free)) +abort (); +} You don't really need to store the whole __gthr_win32_thr_desc in TLS. If you stored just the handle, this wouldn't need a destructor. Thanks, Jacek
Re: Use CreateSemaphoreW instead of CreateSemaphoreA in libgcc.
On 09/18/13 10:57, Pedro Alves wrote: On 09/17/2013 12:19 PM, Jacek Caban wrote: This is no-op for usual GCC targets, because we don't pass any string to CreateSemaphore anyway. However this trivial change will help mingw-w64's efforts to support WinRT, where only unicode variant is available. libgcc/Changelog: config/i386/gthr-win32.c: CreateSemaphoreW instead of CreateSemaphoreA. config/i386/gthr-win32.h: Likewise. I'm a bit puzzled and curious about why you actually need this (and other similar patches), since the Windows CE port manages without them, and there, likewise only the W variants are available (for the whole Win32 API). The w32api headers do things like: WINBASEAPI HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR); WINBASEAPI HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR); #ifdef UNICODE #define CreateSemaphore CreateSemaphoreW #else #define CreateSemaphore CreateSemaphoreA #endif AFAICS, the mingw-w64 headers do something equivalent. For Windows CE, UNICODE is always defined, so uses of CreateSemaphore end up calling CreateSemaphoreW. Doesn't WinRT always define UNICODE similarly? If not, shouldn't it? Current mingw-w64 solution uses regular GCC build and adds a compatibility library for building for winrt target. This means that libgcc is not aware of winrt and is built for regular win32 target. Also, I think that being explicit about API variant we use is a good thing. UNICODE macro may be useful for stuff that has any reason to be changed by a switch, which is not the case here, IMO. Jacek
Use CreateSemaphoreW instead of CreateSemaphoreA in libgcc.
This is no-op for usual GCC targets, because we don't pass any string to CreateSemaphore anyway. However this trivial change will help mingw-w64's efforts to support WinRT, where only unicode variant is available. libgcc/Changelog: config/i386/gthr-win32.c: CreateSemaphoreW instead of CreateSemaphoreA. config/i386/gthr-win32.h: Likewise.
Re: Use CreateSemaphoreW instead of CreateSemaphoreA in libgcc.
On 09/17/13 13:41, Kai Tietz wrote: 2013/9/17 Jacek Caban cja...@gmail.com: This is no-op for usual GCC targets, because we don't pass any string to CreateSemaphore anyway. However this trivial change will help mingw-w64's efforts to support WinRT, where only unicode variant is available. libgcc/Changelog: config/i386/gthr-win32.c: CreateSemaphoreW instead of CreateSemaphoreA. config/i386/gthr-win32.h: Likewise. Please attach (or inline) patch. It's attached now, sorry. Jacek commit eea3738e6103da1d1bc391b99734c93737d292a4 Author: Jacek Caban ja...@codeweavers.com Date: Tue May 7 17:22:01 2013 +0200 Use CreateSemaphoreW instead of CreateSemaphoreA in libgcc. libgcc/Changelog: config/i386/gthr-win32.c: CreateSemaphoreW instead of CreateSemaphoreA. config/i386/gthr-win32.h: Likewise. diff --git a/libgcc/config/i386/gthr-win32.c b/libgcc/config/i386/gthr-win32.c index f6f661a..f323031 100644 --- a/libgcc/config/i386/gthr-win32.c +++ b/libgcc/config/i386/gthr-win32.c @@ -147,7 +147,7 @@ void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex) { mutex-counter = -1; - mutex-sema = CreateSemaphore (NULL, 0, 65535, NULL); + mutex-sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } void @@ -195,7 +195,7 @@ __gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) mutex-counter = -1; mutex-depth = 0; mutex-owner = 0; - mutex-sema = CreateSemaphore (NULL, 0, 65535, NULL); + mutex-sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } int diff --git a/libgcc/config/i386/gthr-win32.h b/libgcc/config/i386/gthr-win32.h index d2e729a..1e437fc 100644 --- a/libgcc/config/i386/gthr-win32.h +++ b/libgcc/config/i386/gthr-win32.h @@ -635,7 +635,7 @@ static inline void __gthread_mutex_init_function (__gthread_mutex_t *__mutex) { __mutex-counter = -1; - __mutex-sema = CreateSemaphore (NULL, 0, 65535, NULL); + __mutex-sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } static inline void @@ -697,7 +697,7 @@ __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) __mutex-counter = -1; __mutex-depth = 0; __mutex-owner = 0; - __mutex-sema = CreateSemaphore (NULL, 0, 65535, NULL); + __mutex-sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } static inline int
Add implicit C linkage for win32-specific entry points
Hi, This is a resend after I'm done with assignment paper work. gcc/c-family/ChangeLog: c-target.def: New hook gcc/ChangeLog: config/config.gcc: Use new winnt-c.c target hooks config/t-winnt: New file config/winnt-c.c: New file doc/tm.texi.in: Document new hook doc/tm.texi: Regenerated gcc/cp/Changelog: decl.c: Use new cxx_implicit_extern_c hook gcc/testsuite/ChangeLog: g++.dg/abi/main.C: Added implicit C linkage tests commit f35cdda381f8213b3d005363e557f1b76732be3b Author: Jacek Caban ja...@codeweavers.com Date: Sat Dec 29 18:06:39 2012 +0100 Add implicit C linkage for win32-specific entry points gcc/c-family/ChangeLog: c-target.def: New hook gcc/ChangeLog: config/config.gcc: Use new winnt-c.c target hooks config/t-winnt: New file config/winnt-c.c: New file doc/tm.texi.in: Document new hook doc/tm.texi: Regenerated gcc/cp/Changelog: decl.c: Use new cxx_implicit_extern_c hook gcc/testsuite/ChangeLog: g++.dg/abi/main.C: Added implicit C linkage tests diff --git a/gcc/c-family/c-target.def b/gcc/c-family/c-target.def index 80042df..b9efae5 100644 --- a/gcc/c-family/c-target.def +++ b/gcc/c-family/c-target.def @@ -102,5 +102,12 @@ DEFHOOK than just the compiler., const char *, (void), hook_constcharptr_void_null) + +DEFHOOK +(cxx_implicit_extern_c, + Define this hook to add target-specific C++ implicit extern C functions.\ + An example of such function is WinMain on Win32 targets., + bool, (const char*), + NULL) HOOK_VECTOR_END (C90_EMPTY_HACK) diff --git a/gcc/config.gcc b/gcc/config.gcc index 36d5ae8..22f30f4 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1526,6 +1526,9 @@ x86_64-*-cygwin*) i[34567]86-*-mingw* | x86_64-*-mingw*) tm_file=${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h xm_file=i386/xm-mingw32.h + c_target_objs=${c_target_objs} winnt-c.o + cxx_target_objs=${cxx_target_objs} winnt-c.o + target_has_targetcm=yes case ${target} in x86_64-*-* | *-w64-*) need_64bit_isa=yes @@ -1565,7 +1568,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) ;; esac tm_file=${tm_file} i386/mingw-stdint.h - tmake_file=${tmake_file} i386/t-cygming t-slibgcc + tmake_file=${tmake_file} t-winnt i386/t-cygming t-slibgcc case ${target} in x86_64-w64-*) tmake_file=${tmake_file} i386/t-mingw-w64 diff --git a/gcc/config/t-winnt b/gcc/config/t-winnt new file mode 100644 index 000..4cc3339 --- /dev/null +++ b/gcc/config/t-winnt @@ -0,0 +1,22 @@ +# Copyright (C) 2004, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# http://www.gnu.org/licenses/. + +winnt-c.o: config/winnt-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(C_TARGET_H) $(C_TARGET_DEF_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ + $ $(OUTPUT_OPTION) diff --git a/gcc/config/winnt-c.c b/gcc/config/winnt-c.c new file mode 100644 index 000..da0f49c --- /dev/null +++ b/gcc/config/winnt-c.c @@ -0,0 +1,39 @@ +/* Default C-family target hooks initializer. + Copyright (C) 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +http://www.gnu.org/licenses/. */ + +#include config.h +#include system.h +#include coretypes.h +#include c-family/c-target.h +#include c-family/c-target-def.h + +static bool +winnt_implicit_extern_c (const char *ident) +{ + return !strcmp(ident, wmain) + || !strcmp(ident, DllMain) + || !strcmp(ident, WinMain) + || !strcmp(ident, wWinMain); +} + +#undef TARGET_CXX_IMPLICIT_EXTERN_C +#define
Re: Add implicit C linkage for win32-specific entry points
On 09/12/13 12:20, Kai Tietz wrote: Hi Jacek, 2013/9/12 Jacek Caban cja...@gmail.com: Hi, This is a resend after I'm done with assignment paper work. gcc/c-family/ChangeLog: c-target.def: New hook gcc/ChangeLog: config/config.gcc: Use new winnt-c.c target hooks config/t-winnt: New file config/winnt-c.c: New file doc/tm.texi.in: Document new hook doc/tm.texi: Regenerated gcc/cp/Changelog: decl.c: Use new cxx_implicit_extern_c hook gcc/testsuite/ChangeLog: g++.dg/abi/main.C: Added implicit C linkage tests I have the following comments about this patch. For gcc/config/t-winnt: +# Copyright (C) 2004, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# Please use here only 2013 as copyright year. It is an new file and current year should be mentioned. For gcc/config/winnt-c.c the same as above. The rest looks to me ok, but a c++ maintainer should take also a look to it. I attached a fixed version. Thanks for review. Jacek commit b0d56c97c651b1d91e66fb8153e0270dd2e8817c Author: Jacek Caban ja...@codeweavers.com Date: Sat Dec 29 18:06:39 2012 +0100 Add implicit C linkage for win32-specific entry points gcc/c-family/ChangeLog: c-target.def: New hook gcc/ChangeLog: config/config.gcc: Use new winnt-c.c target hooks config/t-winnt: New file config/winnt-c.c: New file doc/tm.texi.in: Document new hook doc/tm.texi: Regenerated gcc/cp/Changelog: decl.c: Use new cxx_implicit_extern_c hook gcc/testsuite/ChangeLog: g++.dg/abi/main.C: Added implicit C linkage tests diff --git a/gcc/c-family/c-target.def b/gcc/c-family/c-target.def index 80042df..b9efae5 100644 --- a/gcc/c-family/c-target.def +++ b/gcc/c-family/c-target.def @@ -102,5 +102,12 @@ DEFHOOK than just the compiler., const char *, (void), hook_constcharptr_void_null) + +DEFHOOK +(cxx_implicit_extern_c, + Define this hook to add target-specific C++ implicit extern C functions.\ + An example of such function is WinMain on Win32 targets., + bool, (const char*), + NULL) HOOK_VECTOR_END (C90_EMPTY_HACK) diff --git a/gcc/config.gcc b/gcc/config.gcc index 36d5ae8..22f30f4 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1526,6 +1526,9 @@ x86_64-*-cygwin*) i[34567]86-*-mingw* | x86_64-*-mingw*) tm_file=${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h xm_file=i386/xm-mingw32.h + c_target_objs=${c_target_objs} winnt-c.o + cxx_target_objs=${cxx_target_objs} winnt-c.o + target_has_targetcm=yes case ${target} in x86_64-*-* | *-w64-*) need_64bit_isa=yes @@ -1565,7 +1568,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) ;; esac tm_file=${tm_file} i386/mingw-stdint.h - tmake_file=${tmake_file} i386/t-cygming t-slibgcc + tmake_file=${tmake_file} t-winnt i386/t-cygming t-slibgcc case ${target} in x86_64-w64-*) tmake_file=${tmake_file} i386/t-mingw-w64 diff --git a/gcc/config/t-winnt b/gcc/config/t-winnt new file mode 100644 index 000..1751622 --- /dev/null +++ b/gcc/config/t-winnt @@ -0,0 +1,22 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# http://www.gnu.org/licenses/. + +winnt-c.o: config/winnt-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(C_TARGET_H) $(C_TARGET_DEF_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ + $ $(OUTPUT_OPTION) diff --git a/gcc/config/winnt-c.c b/gcc/config/winnt-c.c new file mode 100644 index 000..d52db62 --- /dev/null +++ b/gcc/config/winnt-c.c @@ -0,0 +1,39 @@ +/* Default C-family target hooks initializer. + Copyright (C) 2013 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You
Re: Add implicit C linkage for win32-specific entry points
On 09/12/13 14:38, Jason Merrill wrote: On 09/12/2013 06:26 AM, Jacek Caban wrote: +@deftypefn {C Target Hook} bool TARGET_CXX_IMPLICIT_EXTERN_C (const char*@var{}) +Define this hook to add target-specific C++ implicit extern C functions. An example of such function is WinMain on Win32 targets. +@end deftypefn Let's clarify this a bit. Perhaps add a middle sentence, If this function returns true for the name of a file-scope function, that function implicitly gets extern C linkage rather than whatever language linkage the declaration would normally have. OK with that change. Thanks for review, a patch with that change is attached. Jacek commit 2647e6d0a095658829e275a96b63814b488e0451 Author: Jacek Caban ja...@codeweavers.com Date: Sat Dec 29 18:06:39 2012 +0100 Add implicit C linkage for win32-specific entry points gcc/c-family/ChangeLog: c-target.def: New hook gcc/ChangeLog: config/config.gcc: Use new winnt-c.c target hooks config/t-winnt: New file config/winnt-c.c: New file doc/tm.texi.in: Document new hook doc/tm.texi: Regenerated gcc/cp/Changelog: decl.c: Use new cxx_implicit_extern_c hook gcc/testsuite/ChangeLog: g++.dg/abi/main.C: Added implicit C linkage tests diff --git a/gcc/c-family/c-target.def b/gcc/c-family/c-target.def index 80042df..925dbd1 100644 --- a/gcc/c-family/c-target.def +++ b/gcc/c-family/c-target.def @@ -102,5 +102,15 @@ DEFHOOK than just the compiler., const char *, (void), hook_constcharptr_void_null) + +DEFHOOK +(cxx_implicit_extern_c, + Define this hook to add target-specific C++ implicit extern C functions.\ + If this function returns true for the name of a file-scope function, that\ + function implicitly gets extern \C\ linkage rather than whatever language\ + linkage the declaration would normally have. An example of such function\ + is WinMain on Win32 targets., + bool, (const char*), + NULL) HOOK_VECTOR_END (C90_EMPTY_HACK) diff --git a/gcc/config.gcc b/gcc/config.gcc index 36d5ae8..22f30f4 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1526,6 +1526,9 @@ x86_64-*-cygwin*) i[34567]86-*-mingw* | x86_64-*-mingw*) tm_file=${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h xm_file=i386/xm-mingw32.h + c_target_objs=${c_target_objs} winnt-c.o + cxx_target_objs=${cxx_target_objs} winnt-c.o + target_has_targetcm=yes case ${target} in x86_64-*-* | *-w64-*) need_64bit_isa=yes @@ -1565,7 +1568,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) ;; esac tm_file=${tm_file} i386/mingw-stdint.h - tmake_file=${tmake_file} i386/t-cygming t-slibgcc + tmake_file=${tmake_file} t-winnt i386/t-cygming t-slibgcc case ${target} in x86_64-w64-*) tmake_file=${tmake_file} i386/t-mingw-w64 diff --git a/gcc/config/t-winnt b/gcc/config/t-winnt new file mode 100644 index 000..1751622 --- /dev/null +++ b/gcc/config/t-winnt @@ -0,0 +1,22 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# http://www.gnu.org/licenses/. + +winnt-c.o: config/winnt-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(C_TARGET_H) $(C_TARGET_DEF_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ + $ $(OUTPUT_OPTION) diff --git a/gcc/config/winnt-c.c b/gcc/config/winnt-c.c new file mode 100644 index 000..d52db62 --- /dev/null +++ b/gcc/config/winnt-c.c @@ -0,0 +1,39 @@ +/* Default C-family target hooks initializer. + Copyright (C) 2013 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +http://www.gnu.org/licenses/. */ + +#include config.h +#include system.h
[PATCH] Add implicit C linkage for win32-specific entry points
Hi, This is another version of my old patch, changed to use target hooks as requested by Steven Bosscher. Tested on i686-w64-mingw32, x86_64-w64-mingw32 and x86_64-unknown-linux-gnu, bootstrapped on x86_64-unknown-linux-gnu. Disclaimer: the patch is in public domain. (because I don't have copyright assignment done). gcc/c-family/ChangeLog: c-target.def: New hook gcc/ChangeLog: config/config.gcc: Use new winnt-c.c target hooks config/t-winnt: New file config/winnt-c.c: New file doc/tm.texi.in: Document new hook doc/tm.texi: Regenerated gcc/cp/Changelog: decl.c: Use new cxx_implicit_extern_c hook gcc/testsuite/ChangeLog: g++.dg/abi/main.C: Added implicit C linkage tests --- gcc/c-family/c-target.def | 7 +++ gcc/config.gcc | 5 - gcc/config/t-winnt | 22 ++ gcc/config/winnt-c.c| 39 +++ gcc/cp/decl.c | 5 - gcc/doc/tm.texi | 4 gcc/doc/tm.texi.in | 2 ++ gcc/testsuite/g++.dg/abi/main.C | 24 8 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 gcc/config/t-winnt create mode 100644 gcc/config/winnt-c.c create mode 100644 gcc/testsuite/g++.dg/abi/main.C diff --git a/gcc/c-family/c-target.def b/gcc/c-family/c-target.def index 80042df..b9efae5 100644 --- a/gcc/c-family/c-target.def +++ b/gcc/c-family/c-target.def @@ -102,5 +102,12 @@ DEFHOOK than just the compiler., const char *, (void), hook_constcharptr_void_null) + +DEFHOOK +(cxx_implicit_extern_c, + Define this hook to add target-specific C++ implicit extern C functions.\ + An example of such function is WinMain on Win32 targets., + bool, (const char*), + NULL) HOOK_VECTOR_END (C90_EMPTY_HACK) diff --git a/gcc/config.gcc b/gcc/config.gcc index 5a205df..0cf61b0 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1475,6 +1475,9 @@ x86_64-*-cygwin*) i[34567]86-*-mingw* | x86_64-*-mingw*) tm_file=${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h xm_file=i386/xm-mingw32.h + c_target_objs=${c_target_objs} winnt-c.o + cxx_target_objs=${cxx_target_objs} winnt-c.o + target_has_targetcm=yes case ${target} in x86_64-*-* | *-w64-*) need_64bit_isa=yes @@ -1514,7 +1517,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) ;; esac tm_file=${tm_file} i386/mingw-stdint.h - tmake_file=${tmake_file} i386/t-cygming t-slibgcc + tmake_file=${tmake_file} t-winnt i386/t-cygming t-slibgcc case ${target} in x86_64-w64-*) tmake_file=${tmake_file} i386/t-mingw-w64 diff --git a/gcc/config/t-winnt b/gcc/config/t-winnt new file mode 100644 index 000..4cc3339 --- /dev/null +++ b/gcc/config/t-winnt @@ -0,0 +1,22 @@ +# Copyright (C) 2004, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# http://www.gnu.org/licenses/. + +winnt-c.o: config/winnt-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(C_TARGET_H) $(C_TARGET_DEF_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ + $ $(OUTPUT_OPTION) diff --git a/gcc/config/winnt-c.c b/gcc/config/winnt-c.c new file mode 100644 index 000..da0f49c --- /dev/null +++ b/gcc/config/winnt-c.c @@ -0,0 +1,39 @@ +/* Default C-family target hooks initializer. + Copyright (C) 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +http://www.gnu.org/licenses/. */ + +#include config.h +#include system.h +#include coretypes.h +#include c-family/c-target.h +#include c-family/c-target-def.h + +static bool +winnt_implicit_extern_c (const char *ident) +{ + return !strcmp(ident, wmain) + || !strcmp(ident, DllMain) + || !strcmp(ident, WinMain) + ||
[PATCH resend] Add implicit C linkage for win32-specific entry points
gcc/ChangeLog: * config/i386/mingw-w64.h: Specify entry points with implicit C linkage gcc/cp/ChangeLog: * decl.c: Allow custom target implicit C linkage gcc/testsuite/ChangeLog: * g++.dg/ext/main.C: Added implicit C linkage tests --- gcc/config/i386/mingw-w64.h |6 ++ gcc/cp/decl.c |8 ++-- gcc/testsuite/g++.dg/ext/main.C | 24 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/main.C diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h index a45ce28..1ce940a 100644 --- a/gcc/config/i386/mingw-w64.h +++ b/gcc/config/i386/mingw-w64.h @@ -85,3 +85,9 @@ along with GCC; see the file COPYING3. If not see %{static:-Bstatic} %{!static:-Bdynamic} \ %{shared|mdll: SUB_LINK_ENTRY --enable-auto-image-base} \ %(shared_libgcc_undefs) + +#define CPP_IMPLICIT_TARGET_CLANG(ident) \ +( !strcmp(ident, wmain) \ +|| !strcmp(ident, DllMain) \ +|| !strcmp(ident, WinMain) \ +|| !strcmp(ident, wWinMain)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index da23bda..ddbe9b0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7279,12 +7279,16 @@ grokfndecl (tree ctype, else if (!ctype) DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ()); - /* `main' and builtins have implicit 'C' linkage. */ + /* `main', builtins and some target specific functions have implicit 'C' linkage. */ if ((MAIN_NAME_P (declarator) || (IDENTIFIER_LENGTH (declarator) 10 IDENTIFIER_POINTER (declarator)[0] == '_' IDENTIFIER_POINTER (declarator)[1] == '_' - strncmp (IDENTIFIER_POINTER (declarator)+2, builtin_, 8) == 0)) + strncmp (IDENTIFIER_POINTER (declarator)+2, builtin_, 8) == 0) +#ifdef CPP_IMPLICIT_TARGET_CLANG + || CPP_IMPLICIT_TARGET_CLANG(IDENTIFIER_POINTER (declarator)) +#endif + ) current_lang_name == lang_name_cplusplus ctype == NULL_TREE DECL_FILE_SCOPE_P (decl)) diff --git a/gcc/testsuite/g++.dg/ext/main.C b/gcc/testsuite/g++.dg/ext/main.C new file mode 100644 index 000..4c5f1ea --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/main.C @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +/* Check if entry points get implicit C linkage. If they don't, compiler will + * error on incompatible declarations */ + +int main(); +extern C int main(); + +#ifdef __MINGW32__ + +int wmain(); +extern C int wmain(); + +int DllMain(); +extern C int DllMain(); + +int WinMain(); +extern C int WinMain(); + +int wWinMain(); +extern C int wWinMain(); + +#endif +
[PATCH] Add implicit C linkage for win32-specific entry points
This is my first patch to GCC, so please let me know if I did something wrong. This patch fixes common annoyance on w64-mingw32 targets, where once needs to add explicit C linkage to make C++ app work with wmain entry point. * decl.c: Allow custom target implicit C linkage * mingw-w64.h: Specify entry points with implicit C linkage * main.C: Added implicit C linkage tests --- gcc/config/i386/mingw-w64.h |6 ++ gcc/cp/decl.c |8 ++-- gcc/testsuite/g++.dg/ext/main.C | 24 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/main.C diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h index a45ce28..1ce940a 100644 --- a/gcc/config/i386/mingw-w64.h +++ b/gcc/config/i386/mingw-w64.h @@ -85,3 +85,9 @@ along with GCC; see the file COPYING3. If not see %{static:-Bstatic} %{!static:-Bdynamic} \ %{shared|mdll: SUB_LINK_ENTRY --enable-auto-image-base} \ %(shared_libgcc_undefs) + +#define CPP_IMPLICIT_TARGET_CLANG(ident) \ +( !strcmp(ident, wmain) \ +|| !strcmp(ident, DllMain) \ +|| !strcmp(ident, WinMain) \ +|| !strcmp(ident, wWinMain)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a89523d..307e5c1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7290,12 +7290,16 @@ grokfndecl (tree ctype, else if (!ctype) DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ()); - /* `main' and builtins have implicit 'C' linkage. */ + /* `main', builtins and some target specific functions have implicit 'C' linkage. */ if ((MAIN_NAME_P (declarator) || (IDENTIFIER_LENGTH (declarator) 10 IDENTIFIER_POINTER (declarator)[0] == '_' IDENTIFIER_POINTER (declarator)[1] == '_' - strncmp (IDENTIFIER_POINTER (declarator)+2, builtin_, 8) == 0)) + strncmp (IDENTIFIER_POINTER (declarator)+2, builtin_, 8) == 0) +#ifdef CPP_IMPLICIT_TARGET_CLANG + || CPP_IMPLICIT_TARGET_CLANG(IDENTIFIER_POINTER (declarator)) +#endif + ) current_lang_name == lang_name_cplusplus ctype == NULL_TREE DECL_FILE_SCOPE_P (decl)) diff --git a/gcc/testsuite/g++.dg/ext/main.C b/gcc/testsuite/g++.dg/ext/main.C new file mode 100644 index 000..4c5f1ea --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/main.C @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +/* Check if entry points get implicit C linkage. If they don't, compiler will + * error on incompatible declarations */ + +int main(); +extern C int main(); + +#ifdef __MINGW32__ + +int wmain(); +extern C int wmain(); + +int DllMain(); +extern C int DllMain(); + +int WinMain(); +extern C int WinMain(); + +int wWinMain(); +extern C int wWinMain(); + +#endif +
[PATCH] Add implicit C linkage for win32-specific entry points
Fixed Changelog as requested by Eric. Thanks. gcc/ChangeLog * config/i386/mingw-w64.h: Specify entry points with implicit C linkage gcc/cp/ChangeLog: * decl.c: Allow custom target implicit C linkage gcc/testsuite/ChangeLog: * g++.dg/ext/main.C: Added implicit C linkage tests --- gcc/config/i386/mingw-w64.h |6 ++ gcc/cp/decl.c |8 ++-- gcc/testsuite/g++.dg/ext/main.C | 24 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/main.C diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h index a45ce28..1ce940a 100644 --- a/gcc/config/i386/mingw-w64.h +++ b/gcc/config/i386/mingw-w64.h @@ -85,3 +85,9 @@ along with GCC; see the file COPYING3. If not see %{static:-Bstatic} %{!static:-Bdynamic} \ %{shared|mdll: SUB_LINK_ENTRY --enable-auto-image-base} \ %(shared_libgcc_undefs) + +#define CPP_IMPLICIT_TARGET_CLANG(ident) \ +( !strcmp(ident, wmain) \ +|| !strcmp(ident, DllMain) \ +|| !strcmp(ident, WinMain) \ +|| !strcmp(ident, wWinMain)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a89523d..307e5c1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7290,12 +7290,16 @@ grokfndecl (tree ctype, else if (!ctype) DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ()); - /* `main' and builtins have implicit 'C' linkage. */ + /* `main', builtins and some target specific functions have implicit 'C' linkage. */ if ((MAIN_NAME_P (declarator) || (IDENTIFIER_LENGTH (declarator) 10 IDENTIFIER_POINTER (declarator)[0] == '_' IDENTIFIER_POINTER (declarator)[1] == '_' - strncmp (IDENTIFIER_POINTER (declarator)+2, builtin_, 8) == 0)) + strncmp (IDENTIFIER_POINTER (declarator)+2, builtin_, 8) == 0) +#ifdef CPP_IMPLICIT_TARGET_CLANG + || CPP_IMPLICIT_TARGET_CLANG(IDENTIFIER_POINTER (declarator)) +#endif + ) current_lang_name == lang_name_cplusplus ctype == NULL_TREE DECL_FILE_SCOPE_P (decl)) diff --git a/gcc/testsuite/g++.dg/ext/main.C b/gcc/testsuite/g++.dg/ext/main.C new file mode 100644 index 000..4c5f1ea --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/main.C @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +/* Check if entry points get implicit C linkage. If they don't, compiler will + * error on incompatible declarations */ + +int main(); +extern C int main(); + +#ifdef __MINGW32__ + +int wmain(); +extern C int wmain(); + +int DllMain(); +extern C int DllMain(); + +int WinMain(); +extern C int WinMain(); + +int wWinMain(); +extern C int wWinMain(); + +#endif +