Re: [PATCH] Add MinGW option -mcrtdll= for choosing C RunTime DLL library

2023-06-13 Thread LIU Hao via Gcc-patches

在 2023/6/13 14:29, Pali Rohár 写道:

Of course, just I'm not sure where to put the new paragraph. At the
beginning? Or after the text? What do you think?


Maybe just in front of 'This option is available for MinGW targets.' Also you 
may reword it as you like.



--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] Add MinGW option -mcrtdll= for choosing C RunTime DLL library

2023-06-11 Thread LIU Hao via Gcc-patches

在 2023/6/12 07:08, Jonathan Yong 写道:

+preprocessor is done. MinGW import library @code{msvcrt} is just a
+symlink (or file copy) to the other MinGW CRT import library 


I suggest a change to this line:

   symlink to (or a copy of) another MinGW CRT import library


Also, as discussed earlier, linking against a CRT version different from the value of 
`__MSVCRT_VERSION__` in _mingw.h is not officially supported and should be warned. So maybe we can 
append a paragraph to the documentation:


   Generally speaking, changing the CRT DLL requires recompiling
   the entire MinGW CRT. This option is for experimental and testing
   purposes only.



--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


[PATCH] gcc: Remove size limit of PCH for *-*-mingw32 hosts

2023-02-16 Thread LIU Hao via Gcc-patches


--
Best regards,
LIU Hao
From a4d5e161fbaa5b9994077ffb474e2b55c6c3b3cb Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Tue, 10 May 2022 13:19:07 +0800
Subject: [PATCH] gcc: Remove size limit of PCH for *-*-mingw32 hosts

PCHs can now be relocated, so the size limit makes no sense any more.

This patch was submited to MSYS2 9 months ago for GCC 12. No issue has been 
reported so far.

Reference: 
https://github.com/msys2/MINGW-packages/blob/717d5a5a09e2370e3bd7e12b393a26dbfbe48921/mingw-w64-gcc/0010-Fix-using-large-PCH.patch
Signed-off-by: LIU Hao 

gcc/ChangeLog:

PR pch/14940
* gcc/config/i386/host-mingw32.cc (mingw32_gt_pch_get_address):
Remove the size limit `pch_VA_max_size`
---
 gcc/config/i386/host-mingw32.cc | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/gcc/config/i386/host-mingw32.cc b/gcc/config/i386/host-mingw32.cc
index aeee956ed11..acff6138d63 100644
--- a/gcc/config/i386/host-mingw32.cc
+++ b/gcc/config/i386/host-mingw32.cc
@@ -44,9 +44,6 @@ static size_t mingw32_gt_pch_alloc_granularity (void);
 
 static inline void w32_error(const char*, const char*, int, const char*);
 
-/* FIXME: Is this big enough?  */
-static const size_t pch_VA_max_size  = 128 * 1024 * 1024;
-
 /* Granularity for reserving address space.  */
 static size_t va_granularity = 0x1;
 
@@ -88,9 +85,6 @@ static void *
 mingw32_gt_pch_get_address (size_t size, int)
 {
   void* res;
-  size = (size + va_granularity - 1) & ~(va_granularity - 1);
-  if (size > pch_VA_max_size)
-return NULL;
 
   /* FIXME: We let system determine base by setting first arg to NULL.
  Allocating at top of available address space avoids unnecessary
@@ -100,7 +94,7 @@ mingw32_gt_pch_get_address (size_t size, int)
  If we allocate at bottom we need to reserve the address as early
  as possible and at the same point in each invocation. */
  
-  res = VirtualAlloc (NULL, pch_VA_max_size,
+  res = VirtualAlloc (NULL, size,
  MEM_RESERVE | MEM_TOP_DOWN,
  PAGE_NOACCESS);
   if (!res)
@@ -150,7 +144,7 @@ mingw32_gt_pch_use_address (void *, size_t size, int 
fd,
 
   /* Offset must be also be a multiple of allocation granularity for
  this to work.  We can't change the offset. */ 
-  if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
+  if ((offset & (va_granularity - 1)) != 0)
 return -1;
 
 
-- 
2.39.2



OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH 3/4] libbacktrace: work with aslr on windows

2023-01-21 Thread LIU Hao via Gcc-patches

在 2023-01-21 12:05, Eli Zaretskii via Gcc 写道:

I'm not sure I follow the logic.  A program that calls
GetModuleHandleW will refuse to start on Windows that doesn't have
that API.  So any version before XP is automatically excluded the
moment you use code which calls that API directly (i.e. not through a
function pointer or somesuch).


Are _you_ still willing to maintain backward compatibility with Windows 9x? Even mingw-w64 has been 
defaulting to Windows Server 2003 since 2007. Why would anyone build a modern compiler for such old 
operating systems?


With any Windows that is modern enough, wide APIs should always be preferred to ANSI ones, 
especially when the argument is constant. Almost all ANSI APIs (the only exception I know of is 
`OutputDebugStringA` which does the inverse) translate their ANSI string arguments to wide strings 
and delegate to wide ones, so by calling wide APIs explicitly, such overhead can be avoided.



--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


[PATCH] Always define `WIN32_LEAN_AND_MEAN` before

2023-01-06 Thread LIU Hao via Gcc-patches

This fixes bootstrap issues with current mingw-w64 headers:

   ```
   ../../gcc/gcc/system.h:791:30: error: expected identifier before string 
constant
 791 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
 |  ^~~~
   ```


The changes in this commit were generated by the following command, with some 
post-processing:

   ```
   sed -Ei 's,^( *)#( *)include ,\1#\2define 
WIN32_LEAN_AND_MEAN\n&,'  \
 $(grep -Flr "")
   ```


This has been tested with C, C++, LTO, Fortran, Objective-C, Objective-C++ and JIT, on 
{i868,x86_64}-w64-mingw32; but it contains changes to Ada, libgo, libgomp and libvtv, which I don't 
usually build and test.





--
Best regards,
LIU Hao
From 6600e2b135bd06b2aad77e538b47a480c8deebdd Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Fri, 6 Jan 2023 23:18:15 +0800
Subject: [PATCH] Always define `WIN32_LEAN_AND_MEAN` before 

Recently, mingw-w64 has got updated  from Wine which is included
indirectly by  if `WIN32_LEAN_AND_MEAN` is not defined. The
`IXMLDOMDocument` class has a member function named `abort()`, which gets
affected by our `abort()` macro in "system.h".

`WIN32_LEAN_AND_MEAN` should, nevertheless, always be defined. This
can exclude 'APIs such as Cryptography, DDE, RPC, Shell, and Windows
Sockets' [1], and speed up compilation of these files a bit.

[1] 
https://learn.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers

gcc/

PR middle-end/108300
* config/xtensa/xtensa-dynconfig.c: Define `WIN32_LEAN_AND_MEAN`
before .
* diagnostic-color.cc: Likewise.
* plugin.cc: Likewise.
* prefix.cc: Likewise.

gcc/ada/

PR middle-end/108300
* adaint.c: Define `WIN32_LEAN_AND_MEAN` before `#include
`.
* cio.c: Likewise.
* ctrl_c.c: Likewise.
* expect.c: Likewise.
* gsocket.h: Likewise.
* mingw32.h: Likewise.
* mkdir.c: Likewise.
* rtfinal.c: Likewise.
* rtinit.c: Likewise.
* seh_init.c: Likewise.
* sysdep.c: Likewise.
* terminals.c: Likewise.
* tracebak.c: Likewise.

gcc/jit/

PR middle-end/108300
* jit-w32.h: Define `WIN32_LEAN_AND_MEAN` before .

libatomic/

PR middle-end/108300
* config/mingw/lock.c: Define `WIN32_LEAN_AND_MEAN` before
.

libffi/

PR middle-end/108300
* src/aarch64/ffi.c: Define `WIN32_LEAN_AND_MEAN` before
.

libgcc/

PR middle-end/108300
* config/i386/enable-execute-stack-mingw32.c: Define
`WIN32_LEAN_AND_MEAN` before .
* libgcc2.c: Likewise.
* unwind-generic.h: Likewise.

libgfortran/

PR middle-end/108300
* intrinsics/sleep.c: Define `WIN32_LEAN_AND_MEAN` before
.

libgo/

PR middle-end/108300
* misc/cgo/test/callback_c.c: Define `WIN32_LEAN_AND_MEAN` before
.

libgomp/

PR middle-end/108300
* config/mingw32/proc.c: Define `WIN32_LEAN_AND_MEAN` before
.

libiberty/

PR middle-end/108300
* make-temp-file.c: Define `WIN32_LEAN_AND_MEAN` before .
* pex-win32.c: Likewise.

libssp/

PR middle-end/108300
* ssp.c: Define `WIN32_LEAN_AND_MEAN` before .

libstdc++-v3/

PR middle-end/108300
* src/c++11/system_error.cc: Define `WIN32_LEAN_AND_MEAN` before
.
* src/c++11/thread.cc: Likewise.
* src/c++17/fs_ops.cc: Likewise.
* src/filesystem/ops.cc: Likewise.

libvtv/

PR middle-end/108300
* vtv_malloc.cc: Define `WIN32_LEAN_AND_MEAN` before .
* vtv_rts.cc: Likewise.
* vtv_utils.cc: Likewise.
---
 gcc/ada/adaint.c  | 1 +
 gcc/ada/cio.c | 1 +
 gcc/ada/ctrl_c.c  | 1 +
 gcc/ada/expect.c  | 1 +
 gcc/ada/gsocket.h | 1 +
 gcc/ada/mingw32.h | 1 +
 gcc/ada/mkdir.c   | 1 +
 gcc/ada/rtfinal.c | 1 +
 gcc/ada/rtinit.c  | 1 +
 gcc/ada/seh_init.c| 1 +
 gcc/ada/sysdep.c  | 2 ++
 gcc/ada/terminals.c   | 1 +
 gcc/ada/tracebak.c| 2 ++
 gcc/config/xtensa/xtensa-dynconfig.c  | 1 +
 gcc/diagnostic-color.cc   | 1 +
 gcc/jit/jit-w32.h | 1 +
 gcc/plugin.cc | 1 +
 gcc/prefix.cc | 1 +
 libatomic/config/mingw/lock.c | 1 +
 libffi/src/aarch64/ffi.c  | 1 +
 libgcc/config/i386/enable-execute-stack-mingw32.c | 1 +
 libgcc/libgcc2.c  | 1 +
 

Re: why does gcc jit require pthread?

2022-11-19 Thread LIU Hao via Gcc-patches

在 2022-11-19 19:27, Jonathan Wakely 写道:

I rebased the patch and re-tested with those options, and all tests
passed again:


=== jit Summary ===

# of expected passes15081





The patch is OK for trunk if you have favorable answers for the above
two questions.


Thanks, I've pushed it to trunk now.


Thank you for taking care of it!


--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


Re: why does gccgit require pthread?

2022-11-14 Thread LIU Hao via Gcc-patches

在 2022/11/12 02:27, Jonathan Wakely 写道:


A clean build fixed that. This patch bootstraps and passes testing on
x86_64-pc-linux-gnu (CentOS 8 Stream).

OK for trunk?


What should we do if no one has been approving this patch?


--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


Re: why does gccgit require pthread?

2022-11-07 Thread LIU Hao via Gcc-patches

在 2022-11-07 20:57, Jonathan Wakely 写道:

It would be a lot nicer if playback::context met the C++ Lockable
requirements, and playback::context::compile () could just take a
scoped lock on *this:




Yeah yeah that makes a lot of sense. Would you please just commit that? I don't have write access to 
GCC repo, and it takes a couple of hours for me to bootstrap GCC just for this tiny change.



--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


Re: why does gccgit require pthread?

2022-11-06 Thread LIU Hao via Gcc-patches

在 2022/11/7 15:03, Andrew Pinski 写道:


The win32 thread model does not have `std::mutex`; but there is no 
`pthread_mutex_t` either, so it
does not build either way.

Oh, but I would assume it will later on right?



There has been effort on C++11 threading support for win32 thread model, but I have a negative 
attitude on that.


Another solution is to use `__gthread_mutex_t` instead of `pthread_mutex_t`, which is also available 
in the win32 thread model. Actually I prefer this approach as it keeps code structure like what we 
have at this moment.




Also I think you might need to change some more than you did.
That is:
-#define INCLUDE_PTHREAD_H
  #include "system.h"

You must likely have a macro, INCLUDE_MUTEX, and define that and
include mutex in system.h like it was done for pthread.h.
GCC loves to poison identifiers while lexing to make sure those
identifiers are not used inside GCC and the include of mutex should be
done early.



Well I am not familiar with such behavior. Feel free to amend the patch, until it looks good to you. 
I hope we can check this in before GCC 13 RC.




--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


Re: why does gccgit require pthread?

2022-11-06 Thread LIU Hao via Gcc-patches

在 2022-11-07 12:37, Andrew Pinski 写道:


The original code which used pthread was added in GCC 5 way before GCC
moved to being written in C++11 which was only in the last 3 years.
pthread_* functions were the best choice at the time (2014) but now
GCC is written in C++11, I don't see any reason not to move them over
to using C++11 threading code.




Attached is the proposed patch.

The win32 thread model does not have `std::mutex`; but there is no `pthread_mutex_t` either, so it 
does not build either way.


Tested bootstrapping GCC on `{i686,x86_64}-w64-mingw32` with languages 
`c,lto,c++,fortran,objc,obj-c++` and with the `mcf` thread model; no errors observed. The built 
`libgccjit-0.dll` does not have imports from winpthread any more.


Please review.


--
Best regards,
LIU Hao

From ceb65f21b5ac23ce218efee82f40f641ebe44361 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Mon, 7 Nov 2022 13:00:12 +0800
Subject: [PATCH] gcc/jit: Use C++11 mutex instead of pthread's

This allows JIT to be built with a different thread model from `posix`
where pthread isn't available

gcc/jit/ChangeLog:

* jit-playback.cc: Use `std::mutex` instead of `pthread_mutex_t`
(playback::context::acquire_mutex): Likewise
(playback::context::release_mutex): Likewise
* jit-recording.cc: Remove the unused `INCLUDE_PTHREAD_H`
* libgccjit.cc: Use `std::mutex` instead of `pthread_mutex_t`
---
 gcc/jit/jit-playback.cc  | 9 +
 gcc/jit/jit-recording.cc | 1 -
 gcc/jit/libgccjit.cc | 8 
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index d227d36283a..17ff98c149b 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -19,7 +19,6 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
-#define INCLUDE_PTHREAD_H
 #include "system.h"
 #include "coretypes.h"
 #include "target.h"
@@ -51,6 +50,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-w32.h"
 #endif
 
+#include 
+
 /* Compare with gcc/c-family/c-common.h: DECL_C_BIT_FIELD,
SET_DECL_C_BIT_FIELD.
These are redefined here to avoid depending from the C frontend.  */
@@ -2662,7 +2663,7 @@ playback::compile_to_file::copy_file (const char 
*src_path,
 /* This mutex guards gcc::jit::recording::context::compile, so that only
one thread can be accessing the bulk of GCC's state at once.  */
 
-static pthread_mutex_t jit_mutex = PTHREAD_MUTEX_INITIALIZER;
+static std::mutex jit_mutex;
 
 /* Acquire jit_mutex and set "this" as the active playback ctxt.  */
 
@@ -2673,7 +2674,7 @@ playback::context::acquire_mutex ()
 
   /* Acquire the big GCC mutex. */
   JIT_LOG_SCOPE (get_logger ());
-  pthread_mutex_lock (_mutex);
+  jit_mutex.lock ();
   gcc_assert (active_playback_ctxt == NULL);
   active_playback_ctxt = this;
 }
@@ -2687,7 +2688,7 @@ playback::context::release_mutex ()
   JIT_LOG_SCOPE (get_logger ());
   gcc_assert (active_playback_ctxt == this);
   active_playback_ctxt = NULL;
-  pthread_mutex_unlock (_mutex);
+  jit_mutex.unlock ();
 }
 
 /* Callback used by gcc::jit::playback::context::make_fake_args when
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index f78daed2d71..6ae5a667e90 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -19,7 +19,6 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
-#define INCLUDE_PTHREAD_H
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index ca862662777..a5105fbc1f9 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -19,7 +19,6 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
-#define INCLUDE_PTHREAD_H
 #include "system.h"
 #include "coretypes.h"
 #include "timevar.h"
@@ -30,6 +29,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-recording.h"
 #include "jit-result.h"
 
+#include 
+
 /* The opaque types used by the public API are actually subclasses
of the gcc::jit::recording classes.  */
 
@@ -4060,7 +4061,7 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context 
*ctxt,
Ideally this would be within parse_basever, but the mutex is only needed
by libgccjit.  */
 
-static pthread_mutex_t version_mutex = PTHREAD_MUTEX_INITIALIZER;
+static std::mutex version_mutex;
 
 struct jit_version_info
 {
@@ -4068,9 +4069,8 @@ struct jit_version_info
  guarded by version_mutex.  */
   jit_version_info ()
   {
-pthread_mutex_lock (_mutex);
+std::lock_guard g (version_mutex);
 parse_basever (, , );
-pthread_mutex_unlock (_mutex);
   }
 
   int major;
-- 
2.38.1



OpenPGP_signature
Description: OpenPGP digital signature


Re: Adding a new thread model to GCC

2022-10-23 Thread LIU Hao via Gcc-patches

在 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



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.


--
Best regards,
LIU Hao


OpenPGP_signature
Description: OpenPGP digital signature


[PATCH] libgcc: Update 'gthr-mcf.h' to include a dedicated header for libobjc

2022-10-22 Thread LIU Hao via Gcc-patches

This allows building libobjc and enabling Objective-C. Tested against GCC 12 
branch on i686-w64-mingw32.


--
Best regards,
LIU Hao
From c05cceb2f3baa96c9381be38717bdf6f1f3adb76 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Sat, 22 Oct 2022 17:31:46 +0800
Subject: [PATCH] libgcc: Update 'gthr-mcf.h' to include a dedicated header for
 libobjc

'libobjc/thr.c' includes 'gthr.h'. While all the other gthread headers
have `#ifdef _LIBOBJC` checks, and provide a different set of inline
functions, I think having one header provide two completely unrelated
set of APIs is unsatisfactory, complicates maintenance, and hinders
further development.

This commit references a new header for libobjc, and adds a copyright
notice, as in other headers.

libgcc/ChangeLog:
* config/i386/gthr-mcf.h: Include 'gthr_libobjc.h' when building
libobjc, instead of 'gthr.h'
---
 libgcc/config/i386/gthr-mcf.h | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/libgcc/config/i386/gthr-mcf.h b/libgcc/config/i386/gthr-mcf.h
index 58131bb7ca9..40da86802b6 100644
--- a/libgcc/config/i386/gthr-mcf.h
+++ b/libgcc/config/i386/gthr-mcf.h
@@ -1 +1,36 @@
+/* Threads compatibility routines for libgcc and libobjc.  */
+/* Copyright (C) 2022 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+.  */
+
+#ifdef _LIBOBJC
+
+/* libobjc references some internal structures and requires a
+ * dedicated set of functions.  */
+#include 
+
+#else  /* _LIBOBJC  */
+
+/* This is for libgcc and libstdc++.  */
 #include 
+
+#endif  /* _LIBOBJC  */
-- 
2.38.1



OpenPGP_signature
Description: OpenPGP digital signature


Re: Adding a new thread model to GCC

2022-10-21 Thread LIU Hao via Gcc-patches

在 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.



--
Best regards,
LIU Hao


OpenPGP_signature
Description: OpenPGP digital signature


Re: Adding a new thread model to GCC

2022-10-21 Thread LIU Hao via Gcc-patches

在 2022/10/21 19:54, i.nix...@autistici.org 写道:


I have a questions:
1) wouldn't it be logical not to write yet another implementation of pthreads-wor-windows, but to 
make changes to the winpthreads library because it's already supported by GCC? (maybe I don’t know 
about some reasons why it wasn’t done ...)




While it is possible to rebuild winpthreads from scratch, I don't think it's 
worth:

  * There are many POSIX facilities that we don't support: rwlock,
cancellation, signals, etc.

  * GCC can choose to implement `std::thread` etc. on C11 ,
which libcxx already has, but I haven't tested it.
(mcfgthread also has a C11 header, but not one for libcxx.)


It seems to me the ideal and logical option is to make your implementation part of GCC, as suggested 
by Eric B.

the advantages are as follows:
1) we will get a high-quality native implementation.
2) there is no need to add another thread model for GCC.
3) with dynamic linking there is no need to ship another dll with the program. (Windows users really 
don't like this =))




Jacek Caban, who is also a mingw-w64 developer, expressed the same idea a few 
days ago.

While integrating mcfgthread into gcc is practically possible, my concerns are:

  * GCC never provides a threading library. It always depends on glibc,
musl, win32 APIs, winpthreads, etc.

  * Tampering with the win32 thread model in a dramatic way is not
acceptiable due to backwards compatibility. There are distributions
that have win32 as the default thread model, such as Debian.

  * I personally need more control for future development, for example,
re-implement pthread or adding libcxx support, which doesn't fit in
GCC.


--
Best regards,
LIU Hao


OpenPGP_signature
Description: OpenPGP digital signature


Re: Adding a new thread model to GCC

2022-10-21 Thread LIU Hao via Gcc-patches

在 2022/10/21 18:09, i.nix...@autistici.org 写道:

On 2022-10-21 09:58, Jonathan Wakely 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 ?

It would be good if we can accept one of them for GCC 13, but I don't
know Windows well enough to determine which is better.


I had the same question...
I would like to understand what is the difference?
Moreover I would like to understand what is the difference with the already added support for the 
winpthreads library?


@LIU Hao, could you explain please?





Thank you for your interest. I'm glad to make an introduction of it.


I have read this patch before. Let's take the mutex as an example:

There are a lot of ways to implement a mutex on Windows. Basically, a non-recursive mutex can be 
implemented with an atomic counter + a binary semaphore / auto-reset event. This proposed patch 
contains a `__gthr_win32_CRITICAL_SECTION` definition that I think is a duplicate of the internal 
`CRITICAL_SECTION` structure, so should also work the same way as it.


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.


And, since Vista we also have native win32 condition variables, also 
implemented basing on keyed events.


The keyed events are undocumented and are only exposed via syscalls. However, as with other 
documented syscalls, available from Windows Drivers Kit, there are several advantages:


  * There is a global keyed event, which requires no initialization, but
can be utilized by all processes. Basing on that, mcfgthread provides
mutexs, condition variables, once flags, etc. that are all one-pointer
size structs, consume absolutely no additional resource, allow
constexpr initialization, and require no cleanup, much like on Linux.

  * The wait syscalls take a 64-bit integer, whose positive value denotes
the number of 10^-7 seconds since 1600-01-01 00:00:00 Z, and whose
negative value denotes a relative timeout. Hence it's much more simpler
to implement `__gthread_mutex_timedlock()` and `__gthread_cond_wait()`
which take absolute timeouts. On the other hand, Win32 APIs generally
take a 32-bit relative timeout in milliseconds, which not only requires
translation from an absolute timepoint argument, but can also easily
get overflown.

  * Building mutexes on top of syscalls allows a better designed algorithm
[2], and sometimes it can even outperform native `SRWLOCK`s [3].

  * mcfgthread also provides standard-conforming `__cxa_atexit()` and
`__cxa_thread_atexit()` functions, for working around some strange,
weird, and broken behaviors [4][5][6]. On Linux it's glibc that
provides them, so this as a whole requires a little modification in
mingw-w64. I am working on it however; hopefully we can land it soon.


[1] 
http://joeduffyblog.com/2006/11/28/windows-keyed-events-critical-sections-and-new-vista-synchronization-features/


[2] https://github.com/lhmouse/mcfgthread/blob/master/MUTEX.md
[3] https://github.com/lhmouse/mcfgthread#benchmarking

[4] https://sourceforge.net/p/mingw-w64/mailman/message/37268447/
[5] https://reviews.llvm.org/D102944
[6] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80816

--
Best regards,
LIU Hao


OpenPGP_signature
Description: OpenPGP digital signature


Re: Adding a new thread model to GCC

2022-10-19 Thread LIU Hao via Gcc-patches

在 2022/10/20 03:53, Bernhard Reutner-Fischer 写道:


which has kernel32 twice, which might not be ideal for the speed of linking?
I'm not familiar with the content of ntdll so cannot judge if you'd put that in
MCFGTHREAD_SPEC and drop kernel32 there, though, and put the whole
MCFG spec simply before the kernel32 in the REAL_LIBGCC_SPEC.

i.e.
+#define MCFGTHREAD_SPEC  " -lmcfgthread -lntdll "
...
+   -lmoldname -lmingwex -lmsvcrt " MCFGTHREAD_SPEC " -lkernel32 "

I hope this is constructive.
thanks,


NTDLL is the user-mode syscall library i.e. it mainly provides syscalls as 
functions.

Putting `-lmcfgthread` before `-lkernel32` was what I did in the beginning. However, I had an 
impression that NTDLL and KERNEL32 may both export some functions (I believe this is no longer the 
case now). Since MSVCRT in mingw-w64 is not a 'pure' import library and contains some functions that 
we implement on top of KERNEL32, the ideal solution would be


   ```
   #define MCFGTHREAD_SPEC  " -lmcfgthread "
   #define MCFGTHREAD_NTDLL_SPEC  " -lntdll "
 ...
   -lmsvcrt " MCFGTHREAD_SPEC " -lkernel32 " MCFGTHREAD_NTDLL_SPEC
   ```

(NTDLL is only necessary when linking against the shared library.)

The committed patch inserted MCFGTHREAD after KERNEL32 for simplicity, but if you do think we had 
better not repeat KERNEL32 twice, I can propose another patch.



--
Best regards,
LIU Hao


OpenPGP_signature
Description: OpenPGP digital signature


Re: Adding a new thread model to GCC

2022-10-11 Thread LIU Hao via Gcc-patches

在 2022-10-10 23:56, LIU Hao 写道:

在 2022-10-04 20:44, LIU Hao 写道:

Attached are revised patches. These are exported from trunk.



Revised further. The patch for libgfortran has been committed to trunk today, so I include only the 
other two.


   * In the second patch, a space character has been inserted after
     `(int)` for clearness.

   * The macro controlling how to build GCC itself has been renamed to
     `TARGET_USING_MCFGTHREAD` for consistency.

   * Checks against `TARGET_USING_MCFGTHREAD` have been updated in a
     more friendly way.

   * When not using mcfgthread, NTDLL is no longer a default library.
     Although all recent Windows versions are based on the NT kernel,
     there could still be people who want to target 9x or CE; thus
     NTDLL is only added when it is potentially necessary, for example
     when linking against the static libgcc.




Attached is the (previous) third patch, with configure scripts regenerated.


--
Best regards,
LIU Hao

From c32690fa4878d8824a0e05e54f614a8dd9ed68b7 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Sat, 16 Apr 2022 00:46:23 +0800
Subject: [PATCH 2/2] gcc: Add 'mcf' thread model support from mcfgthread

This patch adds the new thread model `mcf`, which implements mutexes
and condition variables with the mcfgthread library.

Source code for mcfgthread is available at 
.

config/ChangeLog:
* gthr.m4 (GCC_AC_THREAD_HEADER): Add new case for `mcf` thread
model

gcc/config/ChangeLog:
* i386/mingw-mcfgthread.h: New file
* i386/mingw32.h: Add builtin macro and default libraries for
mcfgthread when thread model is `mcf`

gcc/ChangeLog:
* config.gcc: Include 'i386/mingw-mcfgthread.h' when thread model
is `mcf`
* configure.ac: Recognize `mcf` as a valid thread model
* configure: Regenerate

libatomic/ChangeLog:
* configure.tgt: Add new case for `mcf` thread model

libgcc/ChangeLog:
* config.host: Add new cases for `mcf` thread model
* config/i386/gthr-mcf.h: New file
* config/i386/t-mingw-mcfgthread: New file
* config/i386/t-slibgcc-cygming: Add mcfgthread for libgcc DLL
* configure: Regenerate

libstdc++-v3/ChangeLog:
* libsupc++/atexit_thread.cc (__cxa_thread_atexit): Use
implementation from mcfgthread if available
* libsupc++/guard.cc (__cxa_guard_acquire, __cxa_guard_release,
__cxa_guard_abort): Use implementations from mcfgthread if
available
* configure: Regenerate
---
 config/gthr.m4  |  1 +
 gcc/config.gcc  |  3 +++
 gcc/config/i386/mingw-mcfgthread.h  |  1 +
 gcc/config/i386/mingw32.h   | 13 ++-
 gcc/configure   |  2 +-
 gcc/configure.ac|  2 +-
 libatomic/configure.tgt |  2 +-
 libgcc/config.host  |  6 +
 libgcc/config/i386/gthr-mcf.h   |  1 +
 libgcc/config/i386/t-mingw-mcfgthread   |  1 +
 libgcc/config/i386/t-slibgcc-cygming|  6 -
 libgcc/configure|  1 +
 libstdc++-v3/configure  | 13 ++-
 libstdc++-v3/libsupc++/atexit_thread.cc | 20 
 libstdc++-v3/libsupc++/guard.cc | 31 +
 15 files changed, 92 insertions(+), 11 deletions(-)
 create mode 100644 gcc/config/i386/mingw-mcfgthread.h
 create mode 100644 libgcc/config/i386/gthr-mcf.h
 create mode 100644 libgcc/config/i386/t-mingw-mcfgthread

diff --git a/config/gthr.m4 b/config/gthr.m4
index 4b937306ad08..11996247f150 100644
--- a/config/gthr.m4
+++ b/config/gthr.m4
@@ -22,6 +22,7 @@ case $1 in
 tpf)   thread_header=config/s390/gthr-tpf.h ;;
 vxworks)   thread_header=config/gthr-vxworks.h ;;
 win32) thread_header=config/i386/gthr-win32.h ;;
+mcf)   thread_header=config/i386/gthr-mcf.h ;;
 esac
 AC_SUBST(thread_header)
 ])
diff --git a/gcc/config.gcc b/gcc/config.gcc
index eec544ff1bac..1f6adea1ab9b 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2091,6 +2091,9 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
if test x$enable_threads = xposix ; then
tm_file="${tm_file} i386/mingw-pthread.h"
fi
+   if test x$enable_threads = xmcf ; then
+   tm_file="${tm_file} i386/mingw-mcfgthread.h"
+   fi
tm_file="${tm_file} i386/mingw32.h"
# This makes the logic if mingw's or the w64 feature set has to be used
case ${target} in
diff --git a/gcc/config/i386/mingw-mcfgthread.h 
b/gcc/config/i386/mingw-mcfgthread.h
new file mode 100644
index ..7d4eda3ed494
--- /dev/null
+++ b/gcc/config/i386/mingw-mcfgthread.h
@@ -0,0 +1 @@
+#define TARGET_USING_MCFGTHREAD  1
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index d3ca0cd0279d..b5f31c3da0ac 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ 

Re: Adding a new thread model to GCC

2022-10-10 Thread LIU Hao via Gcc-patches

在 2022-10-04 20:44, LIU Hao 写道:

Attached are revised patches. These are exported from trunk.



Revised further. The patch for libgfortran has been committed to trunk today, so I include only the 
other two.


  * In the second patch, a space character has been inserted after
`(int)` for clearness.

  * The macro controlling how to build GCC itself has been renamed to
`TARGET_USING_MCFGTHREAD` for consistency.

  * Checks against `TARGET_USING_MCFGTHREAD` have been updated in a
more friendly way.

  * When not using mcfgthread, NTDLL is no longer a default library.
Although all recent Windows versions are based on the NT kernel,
there could still be people who want to target 9x or CE; thus
NTDLL is only added when it is potentially necessary, for example
when linking against the static libgcc.



--
Best regards,
LIU Hao

From b371849927adba290d1e17e2a43866cc3465eb4c Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Sun, 2 Oct 2022 00:57:08 +0800
Subject: [PATCH 1/2] libstdc++/thread: Implement `_GLIBCXX_NPROCS` for Windows

This makes `std::thread::hardware_concurrency()` return the number of
logical processors, instead of zero.

libstdc++-v3/ChangeLog:
* src/c++11/thread.cc (get_nprocs): Add new implementation
for native Windows targets
---
 libstdc++-v3/src/c++11/thread.cc | 9 +
 1 file changed, 9 insertions(+)

diff --git a/libstdc++-v3/src/c++11/thread.cc b/libstdc++-v3/src/c++11/thread.cc
index 707a4ad415b9..a54bc3e939a0 100644
--- a/libstdc++-v3/src/c++11/thread.cc
+++ b/libstdc++-v3/src/c++11/thread.cc
@@ -68,6 +68,15 @@ static inline int get_nprocs()
 #elif defined(_GLIBCXX_USE_SC_NPROC_ONLN)
 # include 
 # define _GLIBCXX_NPROCS sysconf(_SC_NPROC_ONLN)
+#elif defined(_WIN32)
+# include 
+static inline int get_nprocs()
+{
+  SYSTEM_INFO sysinfo;
+  GetSystemInfo();
+  return (int) sysinfo.dwNumberOfProcessors;
+}
+# define _GLIBCXX_NPROCS get_nprocs()
 #else
 # define _GLIBCXX_NPROCS 0
 #endif
-- 
2.37.3

From 5df9fa2b8d6ea3c357e7a9fcd42721811ea376ce Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Sat, 16 Apr 2022 00:46:23 +0800
Subject: [PATCH 2/2] gcc: Add 'mcf' thread model support from mcfgthread

This patch adds the new thread model `mcf`, which implements mutexes
and condition variables with the mcfgthread library.

Source code for mcfgthread is available at 
.

config/ChangeLog:
* gthr.m4 (GCC_AC_THREAD_HEADER): Add new case for `mcf` thread
model

gcc/config/ChangeLog:
* i386/mingw-mcfgthread.h: New file
* i386/mingw32.h: Add builtin macro and default libraries for
mcfgthread when thread model is `mcf`

gcc/ChangeLog:
* config.gcc: Include 'i386/mingw-mcfgthread.h' when thread model
is `mcf`
* configure.ac: Recognize `mcf` as a valid thread model

libatomic/ChangeLog:
* configure.tgt: Add new case for `mcf` thread model

libgcc/ChangeLog:
* config.host: Add new cases for `mcf` thread model
* config/i386/gthr-mcf.h: New file
* config/i386/t-mingw-mcfgthread: New file
* config/i386/t-slibgcc-cygming: Add mcfgthread for libgcc DLL

libstdc++-v3/ChangeLog:
* libsupc++/atexit_thread.cc (__cxa_thread_atexit): Use
implementation from mcfgthread if available
* libsupc++/guard.cc (__cxa_guard_acquire, __cxa_guard_release,
__cxa_guard_abort): Use implementations from mcfgthread if
available
---
 config/gthr.m4  |  1 +
 gcc/config.gcc  |  3 +++
 gcc/config/i386/mingw-mcfgthread.h  |  1 +
 gcc/config/i386/mingw32.h   | 13 ++-
 gcc/configure.ac|  2 +-
 libatomic/configure.tgt |  2 +-
 libgcc/config.host  |  6 +
 libgcc/config/i386/gthr-mcf.h   |  1 +
 libgcc/config/i386/t-mingw-mcfgthread   |  1 +
 libgcc/config/i386/t-slibgcc-cygming|  6 -
 libstdc++-v3/libsupc++/atexit_thread.cc | 20 
 libstdc++-v3/libsupc++/guard.cc | 31 +
 12 files changed, 83 insertions(+), 4 deletions(-)
 create mode 100644 gcc/config/i386/mingw-mcfgthread.h
 create mode 100644 libgcc/config/i386/gthr-mcf.h
 create mode 100644 libgcc/config/i386/t-mingw-mcfgthread

diff --git a/config/gthr.m4 b/config/gthr.m4
index 4b937306ad08..11996247f150 100644
--- a/config/gthr.m4
+++ b/config/gthr.m4
@@ -22,6 +22,7 @@ case $1 in
 tpf)   thread_header=config/s390/gthr-tpf.h ;;
 vxworks)   thread_header=config/gthr-vxworks.h ;;
 win32) thread_header=config/i386/gthr-win32.h ;;
+mcf)   thread_header=config/i386/gthr-mcf.h ;;
 esac
 AC_SUBST(thread_header)
 ])
diff --git a/gcc/config.gcc b/gcc/config.gcc
index eec544ff1bac..1f6adea1ab9b 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2091,6 +2091,9 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
if test x$enable_threads = xposix ; then
 

Re: Adding a new thread model to GCC

2022-10-04 Thread LIU Hao via Gcc-patches

在 2022-10-04 21:13, Xi Ruoyao 写道:


In GCC development we usually include the configure regeneration in the
patch because the scripts are also version controlled.



There is a reason for not doing that: Generated contents can't be reviewed.

In mingw-w64 we do the opposite: The person who commits a patch is responsible for update configure, 
Makefile.in, etc. The patch itself doesn't include generated contents.




It's better to include the ID in the subject and ChangeLog of the patch.
Like:

[PATCH 1/3] libgfortran: Use `__gthread_t` instead of `pthread_t` [PR 
105764]

It used to cause errors if a thread model other than `posix` was selected,

which looks like a leftover from a79878585a1c5e32bafbc6d1e73f91fd6e4293bf.

libgfortran/ChangeLog:

	PR libgfortran/105764

* io/async.h (struct async_unit): Use `__gthread_t` instead
of `pthread_t`.



Yes I think this change is good.




And, from https://gcc.gnu.org/contribute.html#patches:

"It is strongly discouraged to post patches as MIME parts of type
application/whatever, disposition attachment or encoded as base64 or
quoted-printable."

Just try "git send-email", it will do the correct thing.  Mimicking its
behavior in a mail client is also possible but error-prune (the mail
client can destroy your patch by replacing your tabs with spaces, etc.)



It's 'discouraged'. It is not forbidden. I expect everywhere people who receive emails to accept 
attachments. Thunderbird has a nice feature to display text attachments inline, so there is no need 
to download it and open it with an external editor, or whatever.



And, I never get `git send-mail` work on my machine:

   ```
   Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): y
   Unable to initialize SMTP properly. Check config and use --smtp-debug. VA
   LUES: server=smtp.126.com encryption=tls hello=localhost.localdomain port
   =465 at /usr/lib/git-core/git-send-email line 1684,  line 3.
   ```




--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


Re: Adding a new thread model to GCC

2022-10-04 Thread LIU Hao via Gcc-patches

Attached are revised patches. These are exported from trunk.


There is a change since my last message:

  * A new Makefile variable `SHLIB_MCFGTHREAD_LIBS` has been introduced, to keep
the other thread models from being affected.


After applying these patches, configure scripts in these subdirectories need to 
be regenerated:

  * gcc
  * libgcc
  * libatomic
  * libstdc++-v3


The patch for libgfortran fixes

  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105764


I have successfully bootstrapped GCC 12 with these patches, on i686-w64-mingw32 (with MSVCRT) and 
x86_64-w64-mingw32 (with MSVCRT and UCRT). No errors have been observed so far.


Once these patches land in GCC, we can start the work in mingw-w64 basing on 
`__USING_MCFGTHREAD__`.



--
Best regards,
LIU Hao

From e1ab15fc95ac8180156feed410cacb64a41a9567 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Fri, 27 May 2022 23:12:48 +0800
Subject: [PATCH 1/3] libgfortran: Use `__gthread_t` instead of `pthread_t`

It used to cause errors if a thread model other than `posix` was selected,
which looks like a leftover from a79878585a1c5e32bafbc6d1e73f91fd6e4293bf.

libgfortran/ChangeLog:
* io/async.h (struct async_unit): Use `__gthread_t` instead
of `pthread_t`.

---
 libgfortran/io/async.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgfortran/io/async.h b/libgfortran/io/async.h
index efd542a45e82..d57722a95e44 100644
--- a/libgfortran/io/async.h
+++ b/libgfortran/io/async.h
@@ -351,7 +351,7 @@ typedef struct async_unit
   struct adv_cond work;
   struct adv_cond emptysignal;
   struct st_parameter_dt *pdt;
-  pthread_t thread;
+  __gthread_t thread;
   struct transfer_queue *head;
   struct transfer_queue *tail;
 
-- 
2.37.3

From 0376949aae74b92a7ba327881672e038c3c0d825 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Sun, 2 Oct 2022 00:57:08 +0800
Subject: [PATCH 2/3] libstdc++/thread: Implement `_GLIBCXX_NPROCS` for Windows

This makes `std::thread::hardware_concurrency()` return the number of
logical processors, instead of zero.

libstdc++-v3/ChangeLog:
* src/c++11/thread.cc (get_nprocs): Add new implementation
for native Windows targets

---
 libstdc++-v3/src/c++11/thread.cc | 9 +
 1 file changed, 9 insertions(+)

diff --git a/libstdc++-v3/src/c++11/thread.cc b/libstdc++-v3/src/c++11/thread.cc
index 707a4ad415b9..b39d9f4a9e29 100644
--- a/libstdc++-v3/src/c++11/thread.cc
+++ b/libstdc++-v3/src/c++11/thread.cc
@@ -68,6 +68,15 @@ static inline int get_nprocs()
 #elif defined(_GLIBCXX_USE_SC_NPROC_ONLN)
 # include 
 # define _GLIBCXX_NPROCS sysconf(_SC_NPROC_ONLN)
+#elif defined(_WIN32)
+# include 
+static inline int get_nprocs()
+{
+  SYSTEM_INFO sysinfo;
+  GetSystemInfo();
+  return (int)sysinfo.dwNumberOfProcessors;
+}
+# define _GLIBCXX_NPROCS get_nprocs()
 #else
 # define _GLIBCXX_NPROCS 0
 #endif
-- 
2.37.3

From d69cbaca07cd7b0e2d725574c8d5913b1c5e0bd5 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Sat, 16 Apr 2022 00:46:23 +0800
Subject: [PATCH 3/3] gcc: Add 'mcf' thread model support from mcfgthread

This patch adds the new thread model `mcf`, which implements mutexes
and condition variables with the mcfgthread library.

Source code for mcfgthread is available at 
.

config/ChangeLog:
* gthr.m4 (GCC_AC_THREAD_HEADER): Add new case for `mcf` thread
model

gcc/config/ChangeLog:
* i386/mingw-mcfgthread.h: New file
* i386/mingw32.h: Add builtin macro and default libraries for
mcfgthread when thread model is `mcf`

gcc/ChangeLog:
* config.gcc: Include 'i386/mingw-mcfgthread.h' when thread model
is `mcf`
* configure.ac: Recognize `mcf` as a valid thread model

libatomic/ChangeLog:
* configure.tgt: Add new case for `mcf` thread model

libgcc/ChangeLog:
* config.host: Add new cases for `mcf` thread model
* config/i386/gthr-mcf.h: New file
* config/i386/t-mingw-mcfgthread: New file
* config/i386/t-slibgcc-cygming: Add mcfgthread for libgcc DLL

libstdc++-v3/ChangeLog:
* libsupc++/atexit_thread.cc (__cxa_thread_atexit): Use
implementation from mcfgthread if available
* libsupc++/guard.cc (__cxa_guard_acquire, __cxa_guard_release,
__cxa_guard_abort): Use implementations from mcfgthread if
available

---
 config/gthr.m4  |  1 +
 gcc/config.gcc  |  3 +++
 gcc/config/i386/mingw-mcfgthread.h  |  1 +
 gcc/config/i386/mingw32.h   | 11 -
 gcc/configure.ac|  2 +-
 libatomic/configure.tgt |  2 +-
 libgcc/config.host  |  6 +
 libgcc/config/i386/gthr-mcf.h   |  1 +
 libgcc/config/i386/t-mingw-mcfgthread   |  1 +
 libgcc/config/i386/t-slibgcc-cygming|  6 -
 libstdc++-v3/libsupc++/atexit_thread.cc | 20 
 libstdc++-v3/libsupc++/guard.cc | 31 

Re: Adding a new thread model to GCC

2022-10-04 Thread LIU Hao via Gcc-patches

在 2022-10-03 13:03, Bernhard Reutner-Fischer 写道:


No, sorry for my brevity.
Using __gthread_t like in your patch is correct.



I see. In 'libgfortran/io/async.c' there is

  ```
async_unit *au = u->au;
LOCK (>lock);
thread_unit = u;
au->thread = __gthread_self ();
  ```

so indeed `thread` should be `__gthread_t`. By the way I reported this issue four months ago and 
haven't received any response so far:


  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105764


--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


Re: Adding a new thread model to GCC

2022-10-02 Thread LIU Hao via Gcc-patches

在 2022-10-02 04:02, Bernhard Reutner-Fischer 写道:

On 1 October 2022 20:34:45 CEST, LIU Hao via Gcc-patches 
 wrote:

Greetings.



The first patch is necessary because somewhere in libgfortran, `pthread_t` is 
referenced. If the thread model is not `posix`, it fails to compile.


One of several shortcomings mentioned already on Sun, 02 Sep 2018 15:40:28 
-0700 in
https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg196212.html



Forgive me but I didn't get your point. Is the 'shortcoming' the fact that `pthread_t` must be 
preferred to `__gthread_t`?


For non-posix thread models,  is not included, so `pthread_t` is not declared. I haven't 
looked at other code in libgfortran, but changing `pthread_t` to `__gthread_t` does allow 
libgfortran to build. I don't know how to test it though, as I don't write Fortran myself.



--
Best regards,
LIU Hao



OpenPGP_signature
Description: OpenPGP digital signature


Adding a new thread model to GCC

2022-10-01 Thread LIU Hao via Gcc-patches

Greetings.

After some years I think it's time to put on this topic again.

This patch series is an attempt to add a new thread model basing on the mcfgthread library 
(https://github.com/lhmouse/mcfgthread), which provides efficient implementations of mutexes, 
condition variables, once flags, etc. for native Windows.



The first patch is necessary because somewhere in libgfortran, `pthread_t` is referenced. If the 
thread model is not `posix`, it fails to compile.


The second patch implements `std::thread::hardware_concurrency()` for non-posix thread models. This 
would also work for the win32 thread model if `std::thread` would be supported in the future.


The third patch adds the `mcf` thread model for GCC and its libraries. A new builtin macro 
`__USING_MCFGTHREAD__` is added to indicate whether this new thread model is in effect. This grants 
`std::mutex` and `std::once_flag` trivial destructors; `std::condition_variable` is a bit 
unfortunate because its destructor is non-trivial, but in reality no cleanup is performed.



I have been bootstrapping GCC with the MCF thread model for more than five years. At the moment, C, 
C++ and Fortran are supported. Ada is untested because I don't know how to bootstrap it. Objective-C 
is not supported, because threading APIs for libobjc have not been implemented.


Please review. If there are any changes that I have to make, let me know.


--
Best regards,
LIU Hao
From c522fa74c791ee8904b5906c6e18908b56071db5 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Fri, 27 May 2022 23:12:48 +0800
Subject: [PATCH 1/3] libgfortran: Use `__gthread_t` instead of `pthread_t`

It used to cause errors if a thread model other than `posix` was selected,
which looks like a leftover from a79878585a1c5e32bafbc6d1e73f91fd6e4293bf.

libgfortran/ChangeLog:
* io/async.h (struct async_unit): Use `__gthread_t` instead
of `pthread_t`.
---
 libgfortran/io/async.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgfortran/io/async.h b/libgfortran/io/async.h
index efd542a45e82..d57722a95e44 100644
--- a/libgfortran/io/async.h
+++ b/libgfortran/io/async.h
@@ -351,7 +351,7 @@ typedef struct async_unit
   struct adv_cond work;
   struct adv_cond emptysignal;
   struct st_parameter_dt *pdt;
-  pthread_t thread;
+  __gthread_t thread;
   struct transfer_queue *head;
   struct transfer_queue *tail;
 
-- 
2.37.3

From fcae3b25b859a207152927797c5ebc520ef3d61a Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Sun, 2 Oct 2022 00:57:08 +0800
Subject: [PATCH 2/3] libstdc++/thread: Implement `_GLIBCXX_NPROCS` for Windows

This makes `std::thread::hardware_concurrency()` return the number of
logical processors, instead of zero.

libstdc++-v3/ChangeLog:
* src/c++11/thread.cc (get_nprocs): Add new implementation
for native Windows targets
---
 libstdc++-v3/src/c++11/thread.cc | 9 +
 1 file changed, 9 insertions(+)

diff --git a/libstdc++-v3/src/c++11/thread.cc b/libstdc++-v3/src/c++11/thread.cc
index 707a4ad415b9..b39d9f4a9e29 100644
--- a/libstdc++-v3/src/c++11/thread.cc
+++ b/libstdc++-v3/src/c++11/thread.cc
@@ -68,6 +68,15 @@ static inline int get_nprocs()
 #elif defined(_GLIBCXX_USE_SC_NPROC_ONLN)
 # include 
 # define _GLIBCXX_NPROCS sysconf(_SC_NPROC_ONLN)
+#elif defined(_WIN32)
+# include 
+static inline int get_nprocs()
+{
+  SYSTEM_INFO sysinfo;
+  GetSystemInfo();
+  return (int)sysinfo.dwNumberOfProcessors;
+}
+# define _GLIBCXX_NPROCS get_nprocs()
 #else
 # define _GLIBCXX_NPROCS 0
 #endif
-- 
2.37.3

From d0f78f3f83d134d91b59e553b115521f8d67ef52 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Sat, 16 Apr 2022 00:46:23 +0800
Subject: [PATCH 3/3] gcc: Add 'mcf' thread model support from mcfgthread

This patch adds the new thread model `mcf`, which implements mutexes
and condition variables with the mcfgthread library.

Source code for mcfgthread is available at 
.

config/ChangeLog:
* gthr.m4 (GCC_AC_THREAD_HEADER): Add new case for `mcf` thread
model

gcc/config/ChangeLog:
* i386/mingw-mcfgthread.h: New file
* i386/mingw32.h: Add builtin macro and default libraries for
mcfgthread when thread model is `mcf`

gcc/ChangeLog:
* config.gcc: Include 'i386/mingw-mcfgthread.h' when thread model
is `mcf`
* configure.ac: Recognize `mcf` as a valid thread model

libatomic/ChangeLog:
* configure.tgt: Add new case for `mcf` thread model

libgcc/ChangeLog:
* config.host: Add new cases for `mcf` thread model
* config/i386/gthr-mcf.h: New file
* config/i386/t-mingw-mcfgthread: New file
* config/i386/t-slibgcc-cygming: Make CRT depend on threading
library, not vice versa

libstdc++-v3/ChangeLog:
* libsupc++/atexit_thread.cc (__cxa_thread_atexit): Use
implementation from mcfgthread if available
* libsupc++/guard.cc (__cxa_guard_acquire, __cxa_guard_release,
__cxa_guard_abort): 

[PATCH] libgfortran: Use `__gthread_t` instead of `pthread_t`

2022-05-27 Thread LIU Hao via Gcc-patches

The attached patch addresses a build issue when  is not included. 
Please review.


--
Best regards,
LIU Hao
From 7b573e4cdb7c3b666baac4c38046c64a01b6dcb5 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Fri, 27 May 2022 23:12:48 +0800
Subject: [PATCH] libgfortran: Use `__gthread_t` instead of `pthread_t`

It used to cause errors if a thread model other than `posix` was selected,
which looks like a leftover from a79878585a1c5e32bafbc6d1e73f91fd6e4293bf.

2022-05-27  LIU Hao 

libgfortran/
* io/async.h (struct async_unit): Use `__gthread_t` instead
of `pthread_t`.
---
 libgfortran/io/async.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgfortran/io/async.h b/libgfortran/io/async.h
index efd542a45e8..d57722a95e4 100644
--- a/libgfortran/io/async.h
+++ b/libgfortran/io/async.h
@@ -351,7 +351,7 @@ typedef struct async_unit
   struct adv_cond work;
   struct adv_cond emptysignal;
   struct st_parameter_dt *pdt;
-  pthread_t thread;
+  __gthread_t thread;
   struct transfer_queue *head;
   struct transfer_queue *tail;
 
-- 
2.20.1



OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] Remove size limit of PCH

2022-05-11 Thread LIU Hao via Gcc-patches

在 2022-05-10 22:28, Jakub Jelinek 写道:


This looks reasonable, but doesn't contain the most important part.
As mentioned in https://gcc.gnu.org/r12-5855
the generic part can now support relocation of PCH, so it is fine if it is
mapped at some other address, it is preferrable if it is mapped at the same
address as it was written for, but if not, the generic code can relocate it.

(... ...)

IMHO you can just drop the loop, sleep of half a second is almost certainly
slower than the relocation handling, so I'd just


Thanks for the hint. I have very little knowledge about how PCH works in GCC, thus I'm gonna propose 
a patch to MSYS2 and see how it works. This can be committed to GCC later, after having been tested 
through many packages.



--
Best regards,
LIU Hao


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] Remove size limit of PCH

2022-05-10 Thread LIU Hao via Gcc-patches

在 2022-05-10 20:00, Xi Ruoyao 写道:

On Tue, 2022-05-10 at 19:35 +0800, LIU Hao via Gcc-patches wrote:


Subject: [PATCH] Remove size limit of PCH


Make it "Remove size limit of PCH [PR14940]", so once it's committed a
message will show up in bugzilla.



Here is the revised patch.





--
Best regards,
LIU Hao
From 2e314baed84fd80b3b3c4c67787a032b86dd54dc Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Tue, 10 May 2022 13:19:07 +0800
Subject: [PATCH] [PR14940] Remove size limit of PCH

There shouldn't be such a limit in practice.

2022-05-03  LIU Hao 

PR pch/14940
* config/i386/host-mingw32.cc (pch_VA_max_size): Remove.
(mingw32_gt_pch_get_address): Remove size limit.
---
 gcc/config/i386/host-mingw32.cc | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/gcc/config/i386/host-mingw32.cc b/gcc/config/i386/host-mingw32.cc
index 3b0d83ffc606..f915b85abd06 100644
--- a/gcc/config/i386/host-mingw32.cc
+++ b/gcc/config/i386/host-mingw32.cc
@@ -44,9 +44,6 @@ static size_t mingw32_gt_pch_alloc_granularity (void);
 
 static inline void w32_error(const char*, const char*, int, const char*);
 
-/* FIXME: Is this big enough?  */
-static const size_t pch_VA_max_size  = 128 * 1024 * 1024;
-
 /* Granularity for reserving address space.  */
 static size_t va_granularity = 0x1;
 
@@ -88,9 +85,6 @@ static void *
 mingw32_gt_pch_get_address (size_t size, int)
 {
   void* res;
-  size = (size + va_granularity - 1) & ~(va_granularity - 1);
-  if (size > pch_VA_max_size)
-return NULL;
 
   /* FIXME: We let system determine base by setting first arg to NULL.
  Allocating at top of available address space avoids unnecessary
@@ -100,7 +94,7 @@ mingw32_gt_pch_get_address (size_t size, int)
  If we allocate at bottom we need to reserve the address as early
  as possible and at the same point in each invocation. */
  
-  res = VirtualAlloc (NULL, pch_VA_max_size,
+  res = VirtualAlloc (NULL, size,
  MEM_RESERVE | MEM_TOP_DOWN,
  PAGE_NOACCESS);
   if (!res)
@@ -150,7 +144,7 @@ mingw32_gt_pch_use_address (void *, size_t size, int 
fd,
 
   /* Offset must be also be a multiple of allocation granularity for
  this to work.  We can't change the offset. */ 
-  if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
+  if ((offset & (va_granularity - 1)) != 0)
 return -1;
 
 
-- 
2.36.1



OpenPGP_signature
Description: OpenPGP digital signature


[PATCH] Remove size limit of PCH

2022-05-10 Thread LIU Hao via Gcc-patches

Remove the limit and solve https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14940.

I have tested the patch on `x86_64-w64-mingw32` with MSVCRT, by pre-compiling a header of many 
standard and boost headers to generate a 313-MiB-large .gch file and using it to compile a simple 
'hello world' program, and seen no problems so far.



After eighteen years this has eventually been settled. (sigh)


--
Best regards,
LIU Hao
From c084ab275f47cc27621e664d1c63e177525cf321 Mon Sep 17 00:00:00 2001
From: LIU Hao 
Date: Tue, 10 May 2022 13:19:07 +0800
Subject: [PATCH] Remove size limit of PCH

Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14940
Signed-off-by: LIU Hao 
---
 gcc/config/i386/host-mingw32.cc | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/gcc/config/i386/host-mingw32.cc b/gcc/config/i386/host-mingw32.cc
index 3b0d83ffc60..f915b85abd0 100644
--- a/gcc/config/i386/host-mingw32.cc
+++ b/gcc/config/i386/host-mingw32.cc
@@ -44,9 +44,6 @@ static size_t mingw32_gt_pch_alloc_granularity (void);
 
 static inline void w32_error(const char*, const char*, int, const char*);
 
-/* FIXME: Is this big enough?  */
-static const size_t pch_VA_max_size  = 128 * 1024 * 1024;
-
 /* Granularity for reserving address space.  */
 static size_t va_granularity = 0x1;
 
@@ -88,9 +85,6 @@ static void *
 mingw32_gt_pch_get_address (size_t size, int)
 {
   void* res;
-  size = (size + va_granularity - 1) & ~(va_granularity - 1);
-  if (size > pch_VA_max_size)
-return NULL;
 
   /* FIXME: We let system determine base by setting first arg to NULL.
  Allocating at top of available address space avoids unnecessary
@@ -100,7 +94,7 @@ mingw32_gt_pch_get_address (size_t size, int)
  If we allocate at bottom we need to reserve the address as early
  as possible and at the same point in each invocation. */
  
-  res = VirtualAlloc (NULL, pch_VA_max_size,
+  res = VirtualAlloc (NULL, size,
  MEM_RESERVE | MEM_TOP_DOWN,
  PAGE_NOACCESS);
   if (!res)
@@ -150,7 +144,7 @@ mingw32_gt_pch_use_address (void *, size_t size, int 
fd,
 
   /* Offset must be also be a multiple of allocation granularity for
  this to work.  We can't change the offset. */ 
-  if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
+  if ((offset & (va_granularity - 1)) != 0)
 return -1;
 
 
-- 
2.36.0



OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89

2020-11-14 Thread Liu Hao via Gcc-patches
This is the third revision of my patch:

1. Two typos in the commit message have been fixed.
2. Support for `%a` and `%A` has been added. Documentation can be
   found on the same page in the commit message.
3. GCC will no longer warn about 'ISO C does not support the ‘L’
   ms_printf length modifier'. This was caused by mistaken array
   indices in `TARGET_OVERRIDES_FORMAT_INIT`.


-- 
Best regards,
LH_Mouse
From f73d5dcdc61a5da1a4265b144739067b4ec40ec2 Mon Sep 17 00:00:00 2001
From: Liu Hao 
Date: Thu, 12 Nov 2020 22:20:29 +0800
Subject: [PATCH] gcc: Add `ll` and `L` length modifiers for `ms_printf`

Previous code abused `FMT_LEN_L` for the `I` modifier. As `L` is a
valid modifier for `f`, `e`, `g`, etc. and `I` has the same semantics
as the C99 `z` modifier, `FMT_LEN_z` is now used instead.

First, in the Microsoft ABI, type `long double` has the same layout as
type `double`, so `%Lg` behaves identically to `%g`. Users should pass
in `double`s instead of `long double`s, as GCC uses the 10-byte format.

Second, with a CRT that is recent enough (MSVCRT since Vista, MSVCR80,
UCRT, or mingw-w64 8.0), `printf`-family functions can handle the `ll`
length modifier correctly. This ability is assumed to be available
universally. A lot of libraries (such as libgomp) that use the
`format(printf, ...)` attribute used to suffer from warnings about
unknown format specifiers.

Reference: 
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/tcxf1dw6(v=vs.90)
Reference: 
https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015#new-crt-features
Signed-off-by: Liu Hao 

gcc/:
* config/i386/msformat-c.c: Add more length modifiers
---
 gcc/config/i386/msformat-c.c  | 53 ++-
 gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c | 22 +++-
 2 files changed, 49 insertions(+), 26 deletions(-)

diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c
index 4ceec633a6e..085ac88789a 100644
--- a/gcc/config/i386/msformat-c.c
+++ b/gcc/config/i386/msformat-c.c
@@ -32,10 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 static format_length_info ms_printf_length_specs[] =
 {
   { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
-  { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
+  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
+  { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 },
   { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
   { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
-  { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
+  { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
   { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
 };
 
@@ -90,33 +91,35 @@ static const format_flag_pair ms_strftime_flag_pairs[] =
 static const format_char_info ms_print_char_table[] =
 {
   /* C89 conversion specifiers.  */
-  { "di",  0, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  T99_SST, 
 BADLEN, BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +'",  "i",  NULL 
},
-  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, T99_ST, 
BADLEN, BADLEN, BADLEN, BADLEN,  BADLEN,  BADLEN }, "-wp0#", "i",  NULL },
-  { "u",   0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, T99_ST, 
BADLEN, BADLEN, BADLEN, BADLEN,  BADLEN,  BADLEN }, "-wp0'","i",  NULL },
-  { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "",   NULL },
-  { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN, BADLEN, BADLEN }, "-wp0 +#",  "",   NULL },
-  { "c",   0, STD_C89, { T89_I,   BADLEN,  T89_S,  T94_WI,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-w","",   NULL 
},
-  { "s",   1, STD_C89, { T89_C,   BADLEN,  T89_S,  T94_W,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp",   "cR", NULL 
},
-  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-w","c",  NULL 
},
-  { "n",   1, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  BADLEN,  
BADLEN, BADLEN,  T99_IM,  BADLEN,  BADLEN,  BADLEN }, "",  "W",  NULL },
+  { "di",  0, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  BADLEN, 
T99_SST, BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0 +'",  "i",  NULL },
+  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, BADLEN, 
T99_ST,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0#","i",  NULL },
+  { "u",   0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, BADLEN, 
T99_ST,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0'","i",  NULL },
+  { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_D,  
BADLEN,  

Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89

2020-11-13 Thread Liu Hao via Gcc-patches
在 2020/11/14 上午8:12, Joseph Myers 写道:
> On Fri, 13 Nov 2020, Liu Hao via Gcc-patches wrote:
> 
>> 在 2020/11/13 2:46, Joseph Myers 写道:
>>> I'd expect these patches to include updates to the gcc.dg/format/ms_*.c 
>>> tests to reflect the changed semantics (or new tests there if some of the 
>>> changes don't result in any failures in the existing tests).
>>>
>>
>> Does the attached patch suffice?
> 
> This is testing the sort of thing I'd expect tests for regarding 'L' and 
> 'll'.  What about the changes for 'I' - do those result in changes to how 
> the compiler behaves, which should also have tests?
> 

There is already a test for `%Ix` in 'ms_c99-printf-2.c', but there is no test 
(in all 'ms_*printf*'
files) which checks for absence of warnings.


-- 
Best regards,
LH_Mouse



signature.asc
Description: OpenPGP digital signature


Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89

2020-11-12 Thread Liu Hao via Gcc-patches
在 2020/11/13 2:46, Joseph Myers 写道:
> I'd expect these patches to include updates to the gcc.dg/format/ms_*.c 
> tests to reflect the changed semantics (or new tests there if some of the 
> changes don't result in any failures in the existing tests).
> 

Does the attached patch suffice?

I know very little about Deja GNU. I only tried compiling the function in that 
test and verified
that lines without `dg-warning` didn't result in any warnings with my 
bootstrapped GCC last night,
both on i686 and x86_64.



-- 
Best regards,
LH_Mouse
From 3f58912fb369fd1f645d880a3d967e6523b87507 Mon Sep 17 00:00:00 2001
From: Liu Hao 
Date: Thu, 12 Nov 2020 22:20:29 +0800
Subject: [PATCH] gcc: Add `ll` and `L` length modifiers for `ms_printf`

Previous code abuse `FMT_LEN_L` for the `I` modifier. As `L` is a valid
modifier for `f`, `e`, `g`, etc. and `I` has the same semantics as the
C99 `z` modifier, `FMT_LEN_z` is now used.

First, in the Microsoft ABI, type `long double` has the same layout as
type `double`, so `%Lg` behaves identically to `%g`. Users should pass
in `double`s instead as `long double`s, as GCC uses the 10-byte format.

Second, with a CRT that is recent enough (MSVCRT since Vista, MSVCR80,
UCRT, or mingw-w64 8.0), `printf`-family functions can handle the `ll`
length modifier correctly. This ability is assumed to be available
universally. A lot of libraries (such as libgomp) that use the
`format(printf, ...)` attribute used to suffer from warnings about
unknown format specifiers.

Reference: 
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/tcxf1dw6(v=vs.90)
Reference: 
https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015#new-crt-features
Signed-off-by: Liu Hao 

gcc/:
* config/i386/msformat-c.c: Add more length modifiers
---
 gcc/config/i386/msformat-c.c  | 45 ++-
 gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c | 22 -
 2 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c
index 4ceec633a6e..1902b3c73d0 100644
--- a/gcc/config/i386/msformat-c.c
+++ b/gcc/config/i386/msformat-c.c
@@ -32,10 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 static format_length_info ms_printf_length_specs[] =
 {
   { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
-  { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
+  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
+  { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 },
   { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
   { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
-  { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
+  { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
   { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
 };
 
@@ -90,33 +91,33 @@ static const format_flag_pair ms_strftime_flag_pairs[] =
 static const format_char_info ms_print_char_table[] =
 {
   /* C89 conversion specifiers.  */
-  { "di",  0, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  T99_SST, 
 BADLEN, BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +'",  "i",  NULL 
},
-  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, T99_ST, 
BADLEN, BADLEN, BADLEN, BADLEN,  BADLEN,  BADLEN }, "-wp0#", "i",  NULL },
-  { "u",   0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, T99_ST, 
BADLEN, BADLEN, BADLEN, BADLEN,  BADLEN,  BADLEN }, "-wp0'","i",  NULL },
-  { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "",   NULL },
-  { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN, BADLEN, BADLEN }, "-wp0 +#",  "",   NULL },
-  { "c",   0, STD_C89, { T89_I,   BADLEN,  T89_S,  T94_WI,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-w","",   NULL 
},
-  { "s",   1, STD_C89, { T89_C,   BADLEN,  T89_S,  T94_W,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp",   "cR", NULL 
},
-  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-w","c",  NULL 
},
-  { "n",   1, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  BADLEN,  
BADLEN, BADLEN,  T99_IM,  BADLEN,  BADLEN,  BADLEN }, "",  "W",  NULL },
+  { "di",  0, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  BADLEN, 
T99_SST, BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0 +'",  "i",  NULL },
+  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, BADLEN, 
T99_ST,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0#","i",  NULL },
+  { "u",   0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, BADLEN, 
T99_ST,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, 

Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89

2020-11-12 Thread Liu Hao via Gcc-patches
在 2020/11/12 23:12, Liu Hao 写道:
> 
> My humble opinion is that people should have gotten used to the `ll` 
> specifier so I propose a
> different patch that enables it unconditionally. As Jonathan Yong pointed 
> out, GCC is impossible to

The previous patch missed a `double_name` field. A revised version has been 
attached.



-- 
Best regards,
LH_Mouse
From 1d61adae0695e7067e35f36e607a754a7cf12796 Mon Sep 17 00:00:00 2001
From: Liu Hao 
Date: Thu, 12 Nov 2020 22:20:29 +0800
Subject: [PATCH] gcc: Add `ll` and `L` length modifiers for `ms_printf`

Previous code abuse `FMT_LEN_L` for the `I` modifier. As `L` is a valid
modifier for `f`, `e`, `g`, etc. and `I` has the same semantics as the
C99 `z` modifier, `FMT_LEN_z` is now used.

First, in the Microsoft ABI, type `long double` has the same layout as
type `double`, so `%Lg` behaves identically to `%g`. Users should pass
in `double`s instead as `long double`s, as GCC uses the 10-byte format.

Second, with a CRT that is recent enough (MSVCRT since Vista, MSVCR80,
UCRT, or mingw-w64 8.0), `printf`-family functions can handle the `ll`
length modifier correctly. This ability is assumed to be available
universally. A lot of libraries (such as libgomp) that use the
`format(printf, ...)` attribute used to suffer from warnings about
unknown format specifiers.

Reference: 
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/tcxf1dw6(v=vs.90)
Reference: 
https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015#new-crt-features
Signed-off-by: Liu Hao 

gcc/:
* config/i386/msformat-c.c: Add more length modifiers
---
 gcc/config/i386/msformat-c.c | 45 ++--
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c
index 4ceec633a6e..1629b866976 100644
--- a/gcc/config/i386/msformat-c.c
+++ b/gcc/config/i386/msformat-c.c
@@ -32,10 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 static format_length_info ms_printf_length_specs[] =
 {
   { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
-  { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
+  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
+  { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 },
   { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
   { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
-  { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
+  { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
   { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
 };
 
@@ -90,33 +91,33 @@ static const format_flag_pair ms_strftime_flag_pairs[] =
 static const format_char_info ms_print_char_table[] =
 {
   /* C89 conversion specifiers.  */
-  { "di",  0, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  T99_SST, 
 BADLEN, BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +'",  "i",  NULL 
},
-  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, T99_ST, 
BADLEN, BADLEN, BADLEN, BADLEN,  BADLEN,  BADLEN }, "-wp0#", "i",  NULL },
-  { "u",   0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, T99_ST, 
BADLEN, BADLEN, BADLEN, BADLEN,  BADLEN,  BADLEN }, "-wp0'","i",  NULL },
-  { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "",   NULL },
-  { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN, BADLEN, BADLEN }, "-wp0 +#",  "",   NULL },
-  { "c",   0, STD_C89, { T89_I,   BADLEN,  T89_S,  T94_WI,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-w","",   NULL 
},
-  { "s",   1, STD_C89, { T89_C,   BADLEN,  T89_S,  T94_W,   BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp",   "cR", NULL 
},
-  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-w","c",  NULL 
},
-  { "n",   1, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  BADLEN,  
BADLEN, BADLEN,  T99_IM,  BADLEN,  BADLEN,  BADLEN }, "",  "W",  NULL },
+  { "di",  0, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  BADLEN, 
T99_SST, BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0 +'",  "i",  NULL },
+  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, BADLEN, 
T99_ST,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0#","i",  NULL },
+  { "u",   0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, BADLEN, 
T99_ST,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0'","i",  NULL },
+  { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_D,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN }, "-wp0 +#'", "",   NULL },
+  { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   

Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89

2020-11-12 Thread Liu Hao via Gcc-patches
在 2020/11/12 18:18, Jonathan Yong 写道:
> libgomp build fails because of the false -Wformat error, even though:
> 1. Correct C99 inttypes.h macros are used.
> 2. __mingw_* C99 wrappers are used.
> 3. The printf attribute is used, but it was aliased to ms_printf
> 
> The attached patch makes mingw-w64 printf attribute equivalent to other 
> platforms on C99 or later.
> This allows libgomp to build again with -Werror on. This patch should not 
> affect the original
> mingw.org distribution in any way.
> 

According to the conversation on IRC, I personally consider this inappropriate. 
Although the `ll`
modifier is specified by C99 for `long long`, there are many more that don't 
conform to C99 without
UCRT:

1. The `z` modifier for `size_t` is unrecognized.
2. The `t` modifier for `ptrdiff_t` is unrecognized.
3. The `L` modifier for `long double` is accepted but ignored due to
   the fact that MSABI uses an 8-byte type.


> For C99 or later, the mingw-w64 headers already wrap printf/scanf properly, 
> and inttypes.h also
> gives the correct C99 specifiers, so it makes sense to treat the printf 
> attribute as C99 compliant.
> Under C89 mode, the headers would produce MS specific specifiers, so the 
> printf attribute under C89
> reverts to the old behavior of being aliased to ms_printf.
> 
> This might break other code that assumes differently however. I don't think 
> there is a solution to
> satisfy everyone, but at least this allows C99/C++11 compliant code to build 
> again with -Werror.
> Comments?

My humble opinion is that people should have gotten used to the `ll` specifier 
so I propose a
different patch that enables it unconditionally. As Jonathan Yong pointed out, 
GCC is impossible to
predict where the target executable will run. It may be reasonable to expect 
Vista+ instead of an
ancient one. Users who still code for XP- should probably handle such 
differentiation themselves. In
comparison, MSVC does not have such format checks at all.

I started bootstrapping GCC a few minutes ago. It's not gonna finish very soon 
so I send this patch
for your comments.



-- 
Best regards,
LH_Mouse
From 1d61adae0695e7067e35f36e607a754a7cf12796 Mon Sep 17 00:00:00 2001
From: Liu Hao 
Date: Thu, 12 Nov 2020 22:20:29 +0800
Subject: [PATCH] gcc: Add `ll` and `L` length modifiers for `ms_printf`

Previous code abuse `FMT_LEN_L` for the `I` modifier. As `L` is a valid
modifier for `f`, `e`, `g`, etc. and `I` has the same semantics as the
C99 `z` modifier, `FMT_LEN_z` is now used.

First, in the Microsoft ABI, type `long double` has the same layout as
type `double`, so `%Lg` behaves identically to `%g`. Users should pass
in `double`s instead as `long double`s, as GCC uses the 10-byte format.

Second, with a CRT that is recent enough (MSVCRT since Vista, MSVCR80,
UCRT, or mingw-w64 8.0), `printf`-family functions can handle the `ll`
length modifier correctly. This ability is assumed to be available
universally. A lot of libraries (such as libgomp) that use the
`format(printf, ...)` attribute used to suffer from warnings about
unknown format specifiers.

Reference: 
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/tcxf1dw6(v=vs.90)
Reference: 
https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015#new-crt-features
Signed-off-by: Liu Hao 

gcc/:
* config/i386/msformat-c.c: Add more length modifiers
---
 gcc/config/i386/msformat-c.c | 45 ++--
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c
index 4ceec633a6e..1629b866976 100644
--- a/gcc/config/i386/msformat-c.c
+++ b/gcc/config/i386/msformat-c.c
@@ -32,10 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 static format_length_info ms_printf_length_specs[] =
 {
   { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
-  { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
+  { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_ll, STD_C9L, 0 },
+  { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 },
   { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
   { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
-  { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
+  { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
   { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
 };
 
@@ -90,33 +91,33 @@ static const format_flag_pair ms_strftime_flag_pairs[] =
 static const format_char_info ms_print_char_table[] =
 {
   /* C89 conversion specifiers.  */
-  { "di",  0, STD_C89, { T89_I,   BADLEN,  T89_S,   T89_L,   T9L_LL,  T99_SST, 
 BADLEN, BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +'",  "i",  NULL 
},
-  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL,  T9L_ULL, T99_ST, 
BADLEN, BADLEN, BADLEN, BADLEN,  BADLEN,  BADLEN }, "-wp0#", "i",  NULL },
-  { "u",   0, STD_C89, { T89_UI,  BADLEN,  T89_US,  T89_UL, 

Re: Fwd: libstdc++: Attempt to resolve PR83562

2020-11-06 Thread Liu Hao via Gcc-patches
Ping?






在 2020/10/29 下午3:56, Liu Hao 写道:
> I forward it here for comments.
> 
> Basing on the behavior of both GCC and Clang, `__cxa_thread_atexit` is used 
> to register the
> destructor of thread_local objects directly, suggesting the first parameter 
> should have `__thiscall`
> convention.
> 
> libstdc++ used the default `__cdecl` convention and caused crashes on 
> 1686-w64-mingw32 (see
> PR83562). But to my surprise, libcxxabi uses `__cdecl` too [1], but I haven't 
> heard any of relevant
> reports so far.
> 
> Original patch is attached in case you can't find it in gcc-patches.
> 
> 
> [1]
> https://github.com/llvm/llvm-project/blob/97b351a827677ebbedc10bfbce8ef8844c246553/libcxxabi/src/cxa_thread_atexit.cpp#L22
> 
> 



-- 
Best regards,
LH_Mouse



signature.asc
Description: OpenPGP digital signature


Fwd: libstdc++: Attempt to resolve PR83562

2020-10-29 Thread Liu Hao via Gcc-patches
I forward it here for comments.

Basing on the behavior of both GCC and Clang, `__cxa_thread_atexit` is used to 
register the
destructor of thread_local objects directly, suggesting the first parameter 
should have `__thiscall`
convention.

libstdc++ used the default `__cdecl` convention and caused crashes on 
1686-w64-mingw32 (see
PR83562). But to my surprise, libcxxabi uses `__cdecl` too [1], but I haven't 
heard any of relevant
reports so far.

Original patch is attached in case you can't find it in gcc-patches.


[1]
https://github.com/llvm/llvm-project/blob/97b351a827677ebbedc10bfbce8ef8844c246553/libcxxabi/src/cxa_thread_atexit.cpp#L22





 转发的消息 
主题: Re: libstdc++: Attempt to resolve PR83562
日期: Tue, 27 Oct 2020 22:38:29 +0800
发件人: Liu Hao 
收件人: Jason Merrill , GCC Patches 

在 2020/10/8 22:56, Jason Merrill 写道:
> 
> Hmm, why isn't the mingw implementation used for all programs?  That would 
> avoid the bug.
> 

There was a little further discussion about this [1].

TL;DR: The mingw-w64 function is linked statically and subject to issues about 
order of destruction.

Recently mingw-w64 has got its own `__cxa_thread_atexit()` so libstdc++ no 
longer exposes it. This
patch for libstdc++ fixes
calling conventions for destructors on i686 so they match mingw-w64 ones.


[1] https://github.com/msys2/MINGW-packages/issues/7096

[2] Below is a direct quote from #mingw-w64 on OFTC:
(lh_ideapad is me and wbs is Martin Storsjö.)

```
[14:29:32]  wbs, what was the rationale for the `__thiscall` 
convention for
`__cxa_thread_atexit()` and
`__cxa_atexit()` in our CRT? I suspect it is correct, but it is not specified 
anywhere in Itanium ABI.
[14:30:41]  In case of evidence for that, the GCC prototype (with 
default __cdecl)
should be wrong.
[14:31:10]  See this:  
https://github.com/msys2/MINGW-packages/issues/7096
[14:52:05]  lh_ideapad: itanium ABI doesn't really talk about windows 
things, but, the function
that is passed to
__cxa_thread_atexit is the object's destructor function, and when calling the 
destructor, which is
technically a member
function, it's done with the thiscall calling convention
[14:52:31]  lh_ideapad: example: https://godbolt.org/z/qbfWT1 (only clang 
as there's no
gcc-mingw there, but if you try
the same there you'll see the same thing)
[14:52:35]  Title: Compiler Explorer (at godbolt.org)
[14:52:58]  lh_ideapad: the destruct function shows that when calling 
__ZN7MyClassD1Ev, the
destructor, it passes the
object pointer in ecx, i.e. thiscall
[14:53:42]  lh_ideapad: and when adding the object to the cleanup list, 
the __ZN7MyClassD1Ev
function is passed
directly to ___cxa_thread_atexit, which then will need to call the function 
using the thiscall
convention
[14:59:54]  lh_ideapad: so yes, I would agree with your patch changing 
libsupc++ to use thiscall
[15:13:01]  gcc is doing the same thing with a wrong calling 
convention , leaving a
garbage value on
i686-w64-mingw32.
[15:13:38]  yup, so definite +1 on your libsupc++ patch for that
[15:14:00]  then how about `__cxa_atexit`?
[15:14:26]  I would say it should work the same, but gcc doesn't normally 
use that one, right?
[15:14:29]  it's not used by GCC (the standard `atexit()` is used).
[15:15:26]  clang has a flag -fuse-cxa-atexit, which makes it use 
cxa_atexit instead of atexit
[15:15:40]  I was a bit dubious on it.
[15:18:59]  GCC has `-fuse-cxa-atexit` too .  Let me check.
[15:18:59]  (I tested it), clang does use __cxa_atexit if the 
-fuse-cxa-atexit flag is used,
and then the dtor
(thiscall) is passed directly to __cxa_atexit, so that's +1 datapoint to that 
it should have
thiscall. gcc doesn't use
__cxa_atexit for i686 windows despite -fuse-cxa-atexit, so that's no points in 
either direction
[15:19:28]  both clang and gcc use a wrapper function that fixes the 
calling convention, when
using atexit at least
[15:20:22]  `-fuse-cxa-atexit` seems to have no effect on 
`i686-w64-mingw32-g++`.
[15:20:46]  exactly. so in practice it doesn't matter for gcc, but I think 
libsupc++ should
handle it the same
[15:23:11]  ok I will compose a new patch for both functions later 
today.
[15:23:13]  :)
[15:23:25]  \o/
[15:24:40]  then for the other issue that the user was posting about; I 
remember testing and
noticing that the
mingw-w64-crt implementation of __cxa_thread_atexit doesn't work with emutls, 
but in all of my
tests, it has been a
non-issue as it has ended up using the libsupc++ code instead
[15:50:50]  probably static linking is broken, so one must link 
against shared libstdc++.
[15:52:20]  it doesn't matter whether it is the CRT or libsupc++ 
implementation that is
linked statically.
[15:53:13]  it seems like current msys builds of libstdc++ doesn't include 
__cxa_thread_atexit
in libstdc++ at all. I'm
pretty sure I tested this back when I made the mingw version, but I'll 
investigate and try to
pinpoint what changed (did gcc
at some point start noticing that mingw-w64-crt contains it and stop providing 

Re: libstdc++: Attempt to resolve PR83562

2020-10-27 Thread Liu Hao via Gcc-patches
在 2020/10/8 22:56, Jason Merrill 写道:
> 
> Hmm, why isn't the mingw implementation used for all programs?  That would 
> avoid the bug.
> 

There was a little further discussion about this [1].

TL;DR: The mingw-w64 function is linked statically and subject to issues about 
order of destruction.

Recently mingw-w64 has got its own `__cxa_thread_atexit()` so libstdc++ no 
longer exposes it. This patch for libstdc++ fixes
calling conventions for destructors on i686 so they match mingw-w64 ones.


[1] https://github.com/msys2/MINGW-packages/issues/7096

[2] Below is a direct quote from #mingw-w64 on OFTC:
(lh_ideapad is me and wbs is Martin Storsjö.)

```
[14:29:32]  wbs, what was the rationale for the `__thiscall` 
convention for `__cxa_thread_atexit()` and
`__cxa_atexit()` in our CRT? I suspect it is correct, but it is not specified 
anywhere in Itanium ABI.
[14:30:41]  In case of evidence for that, the GCC prototype (with 
default __cdecl) should be wrong.
[14:31:10]  See this:  
https://github.com/msys2/MINGW-packages/issues/7096
[14:52:05]  lh_ideapad: itanium ABI doesn't really talk about windows 
things, but, the function that is passed to
__cxa_thread_atexit is the object's destructor function, and when calling the 
destructor, which is technically a member
function, it's done with the thiscall calling convention
[14:52:31]  lh_ideapad: example: https://godbolt.org/z/qbfWT1 (only clang 
as there's no gcc-mingw there, but if you try
the same there you'll see the same thing)
[14:52:35]  Title: Compiler Explorer (at godbolt.org)
[14:52:58]  lh_ideapad: the destruct function shows that when calling 
__ZN7MyClassD1Ev, the destructor, it passes the
object pointer in ecx, i.e. thiscall
[14:53:42]  lh_ideapad: and when adding the object to the cleanup list, 
the __ZN7MyClassD1Ev function is passed
directly to ___cxa_thread_atexit, which then will need to call the function 
using the thiscall convention
[14:59:54]  lh_ideapad: so yes, I would agree with your patch changing 
libsupc++ to use thiscall
[15:13:01]  gcc is doing the same thing with a wrong calling 
convention , leaving a garbage value on
i686-w64-mingw32.
[15:13:38]  yup, so definite +1 on your libsupc++ patch for that
[15:14:00]  then how about `__cxa_atexit`?
[15:14:26]  I would say it should work the same, but gcc doesn't normally 
use that one, right?
[15:14:29]  it's not used by GCC (the standard `atexit()` is used).
[15:15:26]  clang has a flag -fuse-cxa-atexit, which makes it use 
cxa_atexit instead of atexit
[15:15:40]  I was a bit dubious on it.
[15:18:59]  GCC has `-fuse-cxa-atexit` too .  Let me check.
[15:18:59]  (I tested it), clang does use __cxa_atexit if the 
-fuse-cxa-atexit flag is used, and then the dtor
(thiscall) is passed directly to __cxa_atexit, so that's +1 datapoint to that 
it should have thiscall. gcc doesn't use
__cxa_atexit for i686 windows despite -fuse-cxa-atexit, so that's no points in 
either direction
[15:19:28]  both clang and gcc use a wrapper function that fixes the 
calling convention, when using atexit at least
[15:20:22]  `-fuse-cxa-atexit` seems to have no effect on 
`i686-w64-mingw32-g++`.
[15:20:46]  exactly. so in practice it doesn't matter for gcc, but I think 
libsupc++ should handle it the same
[15:23:11]  ok I will compose a new patch for both functions later 
today.
[15:23:13]  :)
[15:23:25]  \o/
[15:24:40]  then for the other issue that the user was posting about; I 
remember testing and noticing that the
mingw-w64-crt implementation of __cxa_thread_atexit doesn't work with emutls, 
but in all of my tests, it has been a
non-issue as it has ended up using the libsupc++ code instead
[15:50:50]  probably static linking is broken, so one must link 
against shared libstdc++.
[15:52:20]  it doesn't matter whether it is the CRT or libsupc++ 
implementation that is linked statically.
[15:53:13]  it seems like current msys builds of libstdc++ doesn't include 
__cxa_thread_atexit in libstdc++ at all. I'm
pretty sure I tested this back when I made the mingw version, but I'll 
investigate and try to pinpoint what changed (did gcc
at some point start noticing that mingw-w64-crt contains it and stop providing 
their own?) or whether I just missed
something when I tested it back when I wrote it...
[15:59:47]  I'll follow up on that other issue and mingw bugtracker issue, 
but I'll do a couple hours of comple
testing/studying things first to be able to give an informed comment
[16:15:34] * pamaury (~pama...@ip-41.net-89-3-53.rev.numericable.fr) has joined
[16:27:34]  wbs, there is a check in `libstdc++-v3/configure.ac` 
around line 275.
[16:29:22]  lh_ideapad: yeah, but in my tests it doesn't pick up on it. I 
test by cross-bootstrapping a toolchain, so
maybe this check runs before the mingw-w64-crt actually is built
[16:29:50]  so it doesn't detect if just bootstrapping once, but if 
building a new gcc in an already complete
environment, it behaves differently
[16:33:21] * Pali (~p...@0001caa5.user.oftc.net) 

Re: libstdc++: Attempt to resolve PR83562

2020-10-08 Thread Liu Hao via Gcc-patches
在 2020/10/8 22:56, Jason Merrill 写道:
> On 10/7/20 10:52 PM, Liu Hao via Gcc-patches wrote:
>> [Please CC me as I am not subscribed to this list.]
> 
> Hmm, why isn't the mingw implementation used for all programs?  That would 
> avoid the bug.
> 

I am afraid the libstdc++ implementation has to be kept for compatibility, as 
the mingw-w64 one was only added two years
ago. Neither am I clear about MinGW.org.

> 
> This patch is a good start but won't actually fix the bug: the calling 
> convention only makes a difference when we actually
> call the function, at the line
> 
>     e->destructor (e->object);
> 
> in atexit_thread.cc, and your patch doesn't change the calling convention for 
> elt::destructor.
> 
> I'd think we should add the attribute to __cxa_cdtor_type, and use it more 
> consistently for __cxa_*atexit and __cxa_throw.
> 

This patch contains a hunk

```diff
@@ -52,7 +57,7 @@ namespace {
   // One element in a singly-linked stack of cleanups.
   struct elt
   {
-void (*destructor)(void *);
+void (_GLIBCXX_CDTOR_CALLABI *destructor)(void *);
 void *object;
 elt *next;
 #ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
```

which should suffice. I am not against introduction of another macro for this 
calling convention thing, as the name
`__cxa_thread_atexit()` doesn't suggest its first argument is a non-static 
member function. (Technically I think it should
not be, so GCC's use of it to register the destructor looks like a bug. The 
call should go through a thunk.)




-- 
Best regards,
LH_Mouse



signature.asc
Description: OpenPGP digital signature


Attempt to resolve PR83562

2020-10-07 Thread Liu Hao via Gcc-patches
[Please CC me as I am not subscribed to this list.]
[This patch is only a draft and has not been tested at all.]


Some details have been discussed in [1]. mingw-w64 has got an implementation 
[2] [3] for static libraries, but it takes a
destructor using the `__thiscall` convention. As both functions have C linkage, 
they should agree with each other and should
behave simliarily.


Considerations:

0) This is going to be an ABI breakage for i?86. I am not sure whether people 
would expect the old, broken behavior.
1) GCC doesn't provide `__cxa_atexit()`, but it would suffer from the same 
problem. At the moment GCC calls `atexit()` to
register destructors so it appears to work.
2) There is an explicit reference to `__cxa_atexit` in 'gcc/cp/decl.c' and it 
probably be changed, unless it is not used by
1?86-w64-mingw32 targets.


[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562
[2] 
https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/crt/cxa_thread_atexit.c
[3] 
https://sourceforge.net/p/mingw-w64/mingw-w64/ci/f3e0fbb40cbc9f8821db8bd8a0c4dae8ff671e9f/
[4] https://github.com/msys2/MINGW-packages/issues/7071


-- 
Best regards,
LH_Mouse
From ac325bdcd6e3fa522f8b59d436cd4b3ab663de5c Mon Sep 17 00:00:00 2001
From: Liu Hao 
Date: Thu, 8 Oct 2020 10:26:13 +0800
Subject: [PATCH] libsupc++: Make the destructor parameter to
 `__cxa_thread_atexit()` use the `__thiscall` calling convention for
 i686-w64-mingw32

The mingw-w64 implementations of `__cxa_thread_atexit()` and `__cxa_atexit()` have been
using `__thiscall` since two years ago. Using the default calling convention (which is
`__cdecl`) causes crashes as explained in PR83562.

Calling conventions have no effect on x86_64-w64-mingw32.

Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562
Reference: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/crt/cxa_thread_atexit.c
Reference: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/f3e0fbb40cbc9f8821db8bd8a0c4dae8ff671e9f/
Reference: https://github.com/msys2/MINGW-packages/issues/7071
Signed-off-by: Liu Hao 
---
 libstdc++-v3/libsupc++/atexit_thread.cc | 14 ++
 libstdc++-v3/libsupc++/cxxabi.h |  8 
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
index e97644f8cd4..4f7f982ac6b 100644
--- a/libstdc++-v3/libsupc++/atexit_thread.cc
+++ b/libstdc++-v3/libsupc++/atexit_thread.cc
@@ -30,16 +30,21 @@
 #include 
 #endif
 
+// Simplify it a little for this file.
+#ifndef _GLIBCXX_CDTOR_CALLABI
+#  define _GLIBCXX_CDTOR_CALLABI
+#endif
+
 #if _GLIBCXX_HAVE___CXA_THREAD_ATEXIT
 
 // Libc provides __cxa_thread_atexit definition.
 
 #elif _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL
 
-extern "C" int __cxa_thread_atexit_impl (void (*func) (void *),
+extern "C" int __cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
 	 void *arg, void *d);
 extern "C" int
-__cxxabiv1::__cxa_thread_atexit (void (*dtor)(void *),
+__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
  void *obj, void *dso_handle)
   _GLIBCXX_NOTHROW
 {
@@ -52,7 +57,7 @@ namespace {
   // One element in a singly-linked stack of cleanups.
   struct elt
   {
-void (*destructor)(void *);
+void (_GLIBCXX_CDTOR_CALLABI *destructor)(void *);
 void *object;
 elt *next;
 #ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
@@ -116,7 +121,8 @@ namespace {
 }
 
 extern "C" int
-__cxxabiv1::__cxa_thread_atexit (void (*dtor)(void *), void *obj, void */*dso_handle*/)
+__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
+ void *obj, void */*dso_handle*/)
   _GLIBCXX_NOTHROW
 {
   // Do this initialization once.
diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h
index 000713ecdf8..3d6217a6fac 100644
--- a/libstdc++-v3/libsupc++/cxxabi.h
+++ b/libstdc++-v3/libsupc++/cxxabi.h
@@ -125,14 +125,22 @@ namespace __cxxabiv1
 
   // DSO destruction.
   int
+#ifdef _GLIBCXX_CDTOR_CALLABI
+  __cxa_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void*) _GLIBCXX_NOTHROW;
+#else
   __cxa_atexit(void (*)(void*), void*, void*) _GLIBCXX_NOTHROW;
+#endif
 
   void
   __cxa_finalize(void*);
 
   // TLS destruction.
   int
+#ifdef _GLIBCXX_CDTOR_CALLABI
+  __cxa_thread_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void *) _GLIBCXX_NOTHROW;
+#else
   __cxa_thread_atexit(void (*)(void*), void*, void *) _GLIBCXX_NOTHROW;
+#endif
 
   // Pure virtual functions.
   void
-- 
2.20.1



signature.asc
Description: OpenPGP digital signature


Re: [PATCH] Ensure `-lmsvcrt` precede `-lkernel32`

2020-05-29 Thread Liu Hao via Gcc-patches
在 2020/5/29 22:01, Liu Hao 写道:
> This is necessary as libmsvcrt.a is not a pure import library, but
> also contains some functions that invoke others in KERNEL32.DLL.
> 
>   * config/i386/mingw32.h: Insert -lkernel32 after -lmsvcrt
> ---
>  gcc/config/i386/mingw32.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
> index 1bbabfe8bed..321c30e41cc 100644
> --- a/gcc/config/i386/mingw32.h
> +++ b/gcc/config/i386/mingw32.h
> @@ -165,7 +165,7 @@ along with GCC; see the file COPYING3.  If not see
>  #define REAL_LIBGCC_SPEC \
>"%{mthreads:-lmingwthrd} -lmingw32 \
> " SHARED_LIBGCC_SPEC " \
> -   -lmoldname -lmingwex -lmsvcrt"
> +   -lmoldname -lmingwex -lmsvcrt -lkernel32"
>   #undef STARTFILE_SPEC
>  #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
> 

This patch originates from this discussion on #mingw-w64 on OFTC:

```
[20:09:50]  there is suddenly an unexpected call to
`IsDBCSLeadByteEx()` in winpthreads. Not sure why it gets involved.
[20:13:12] * tchan (~tc...@c-98-220-238-152.hsd1.il.comcast.net) has joined
[20:22:28]  diff'ing the import tables the previous working
binary and now broken binary reveals that the old symbol to `printf` is
gone. seems the mingw-w64 ones is called, which references
`IsDBCSLeadByteEx()` and `WideCharToMultiByte()`.
[20:27:19]  both of those should be provided by -lkernel32 right?
[20:27:36] * Dejan has quit (Quit: Leaving)
[20:34:09]  probably, but I doubt whether it should behave
this way.  when perform cross-compilation the CRT is not available when
building winpthreads.
[20:34:37]  presumably it should always call the MS one.
[20:34:45]  I'm pretty sure you'd first build the crt, then
libraries like winpthreads - the other way around doesn't work
[20:35:16]  :|  let me make a test program.
[20:38:38]  can't reproduce it myself.
[20:41:06]  there may be something wrong with the OP'
[20:41:18]  's configuration.  Normally kernel32 is a default lib.
[20:42:39]  I still think winpthreads should be built with
`CPPFLAGS='-D__USE_MINGW_ANSI_STDIO=0'`. I built a local package and
there is no reference to DBCS or wide char functions.
[20:49:21]   reproduced now:
https://paste.ubuntu.com/p/HwNk8WqgkD/
[20:49:23]  Title: Ubuntu Pastebin (at paste.ubuntu.com)
[20:52:45]  strange:  -lmingw32 -lgcc -lgcc_eh -lmoldname
-lmingwex -lmsvcrt -lpthread -lmcfgthread -ladvapi32 -lshell32 -luser32
-lkernel32 -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt
[20:53:10]  oh.
[20:53:22]  the mingw-w64 `printf` is defined in mingwex I guess?
[20:53:22]  pthread pulls in objects from msvcrt, which then needs
things from kernel32, but there's no more kernel32 after msvcrt
[20:54:04]  in 211af1e7d4d188dbefacea7af8b83d32b3edb48c I moved
mbrtowc and wcrtomb from mingwex to msvcrt
[20:54:37]  (but that wouldn't make a difference wrt this, as
there's no kernel32 after the first mingwex after -lpthread either)
[20:55:10]  I think it would be good with yet another -lkernel32
after -lmsvcrt
[20:55:27]  after all, that's the way they are layered anyway - the
crt runs on top of kernel32
[20:56:32]  and we want to have the freedom to have object file
implementations in libmsvcrt.a
[20:58:21]  some of these -l things are hard-coded in GCC
default specs.
[20:58:48]  I only found `-ladvapi32 -lshell32 -luser32
-lkernel32`. The list ends there.
[20:59:11]  not sure how those additional libraries were added.
[21:00:04]  lld is nice in this aspect, that it doesn't need static
libraries ordered like this; for each undefined, it searches the list of
static libraries from the start
[21:01:07]  LD is dumb. :(
[21:02:53]  I thought MSVCRT was only an import library. It
seems more complicated.
[21:04:18]  it has (almost) always been more than that - there's
been some stub functions that call GetProcAddress() and try to
conditionally load functions if available
[21:04:53]  and especially with ucrt, we want to move quite a bit
of things from libmingwex.a to libmsvcrt-os.a, for things where we can
and should use the ucrt equivalent instead of statically linking in our own
[21:05:32]  GetProcAdress() requires a successive -lkernel32 too.
[21:05:45]  indeed
[21:06:56]  so this suddenly becomes a GCC issue in its
default specs:  `-lkernel32` is required after `-lmsvcrt`.
[21:07:33]  yes, pretty much. clang has got the same structure as well
[21:07:44]  (which matters for cases when using clang on top of ld.bfd)
[21:08:48]  looks like it's REAL_LIBGCC_SPEC in
gcc/config/i386/mingw32.h that needs to be updated
```



-- 
Best regards,
LH_Mouse



signature.asc
Description: OpenPGP digital signature


[PATCH] Ensure `-lmsvcrt` precede `-lkernel32`

2020-05-29 Thread Liu Hao via Gcc-patches
This is necessary as libmsvcrt.a is not a pure import library, but
also contains some functions that invoke others in KERNEL32.DLL.

* config/i386/mingw32.h: Insert -lkernel32 after -lmsvcrt
---
 gcc/config/i386/mingw32.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index 1bbabfe8bed..321c30e41cc 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -165,7 +165,7 @@ along with GCC; see the file COPYING3.  If not see
 #define REAL_LIBGCC_SPEC \
   "%{mthreads:-lmingwthrd} -lmingw32 \
" SHARED_LIBGCC_SPEC " \
-   -lmoldname -lmingwex -lmsvcrt"
+   -lmoldname -lmingwex -lmsvcrt -lkernel32"
  #undef STARTFILE_SPEC
 #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
-- 
2.26.2




signature.asc
Description: OpenPGP digital signature