On Fri, 28 Mar 2025, Pali Rohár wrote:

On Thursday 27 March 2025 22:17:54 Martin Storsjö wrote:
On Thu, 27 Mar 2025, Martin Storsjö wrote:

On Thu, 20 Mar 2025, Pali Rohár wrote:

Currently all 32-bit non-UCRT builds are forced to use time_t type as
32-bit and also all time_t functions in 32-bit form.

With this change, any msvcrt.dll based 32-bit application can use 64-bit
time_t functions by defining -D_TIME_BITS=64 flag during compilation.

Flag -D_TIME_BITS=64 is recognized also by GNU C library header files for
the same purpose.

When both _USE_32BIT_TIME_T and _TIME_BITS are defined by application then
_USE_32BIT_TIME_T override effect of _TIME_BITS.
---
mingw-w64-headers/crt/_mingw.h.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

I had a read through the rest of this patch series, and I didn't find
anything else by reading that would be a problem.

I did try running this through my "CI" setup on github, and that did
uncover a problem though:
https://github.com/mstorsjo/mingw-w64/actions/runs/14106946049

The libcxx testsuite now fails with this patchset applied. Tests fail
with an error like this:

# .---command stderr------------
# | In file included from 
D:\a\mingw-w64\mingw-w64\llvm-project\libcxx\test\libcxx\input.output\iostream.format\output.streams\ostream.formatted\ostream.formatted.print\vprint_unicode.pass.cpp:37:
# | 
D:/a/mingw-w64/mingw-w64/llvm-project/libcxx/test/support/filesystem_test_helper.h:147:28:
error: cannot initialize a member subobject of type '_dev_t' (aka
'unsigned int') with an rvalue of type 'const value_type *' (aka 'const
char *')
# |   147 |         return ::stat(path.c_str(), &tmp) == 0;
# |       |                       ~~~~~^~~~~~~
# | 
D:/a/mingw-w64/mingw-w64/llvm-project/libcxx/test/support/filesystem_test_helper.h:147:43:
error: invalid operands to binary expression ('::stat' and 'int')
# |   147 |         return ::stat(path.c_str(), &tmp) == 0;
# |       |                ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~
# | C:/llvm-mingw/include/guiddef.h:180:15: note: candidate function not
viable: no known conversion from '::stat' to 'const GUID' (aka 'const
_GUID') for 1st argument
# |   180 | __inline bool operator== (REFGUID guidOne, REFGUID
guidOther) { return !!IsEqualGUID (guidOne, guidOther); }
# |       |               ^           ~~~~~~~~~~~~~~~
# | 2 errors generated.
# `-----------------------------

I can also reproduce similar errors by trying to compile this small
standalone test snippet:

#include <sys/stat.h>
#include <string>
bool exists(std::string const& path) {
   struct ::stat tmp;
   return ::stat(path.c_str(), &tmp) == 0;
}

Building this snippet, with a toolchain with this patchset applied,
errors out like this:

exists.cpp:5:12: error: no matching constructor for initialization of
'::stat'
   5 |     return ::stat(path.c_str(), &tmp) == 0;
     |            ^      ~~~~~~~~~~~~~~~~~~
/home/martin/clang-trunk/x86_64-w64-mingw32/include/sys/stat.h:129:8:
note: candidate constructor (the implicit copy constructor) not viable:
requires 1 argument, but 2 were provided
 129 | struct stat {
     |        ^~~~
/home/martin/clang-trunk/x86_64-w64-mingw32/include/sys/stat.h:129:8:
note: candidate constructor (the implicit move constructor) not viable:
requires 1 argument, but 2 were provided
 129 | struct stat {
     |        ^~~~
/home/martin/clang-trunk/x86_64-w64-mingw32/include/sys/stat.h:129:8:
note: candidate constructor (the implicit default constructor) not
viable: requires 0 arguments, but 2 were provided
exists.cpp:5:39: error: invalid operands to binary expression ('::stat'
and 'int')
   5 |     return ::stat(path.c_str(), &tmp) == 0;
     |            ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~
2 errors generated.

Lasse pointed out that this seems to be due to __CRT__NO_INLINE - when
building without optimizations, that is defined, and we get these errors. If
building with optimizations enabled, it builds fine.

Needless to say, our headers need to work both with and without
optimizations...

// Martin

I was looking at this problem and investigating how to handle it. Could
you try if the following change fixes your build issue with clang and libc++?

diff --git a/mingw-w64-headers/crt/sys/stat.h b/mingw-w64-headers/crt/sys/stat.h
index c520f858661e..53f00abc1902 100644
--- a/mingw-w64-headers/crt/sys/stat.h
+++ b/mingw-w64-headers/crt/sys/stat.h
@@ -140,7 +140,16 @@ struct stat {
  time_t st_ctime;
};

-#ifndef __CRT__NO_INLINE
+#ifdef _CRTBLD
+/*
+ * When building mingw-w64 CRT files it is required that the fstat, stat and
+ * wstat functions are not declared with __MINGW_ASM_CALL redirection.
+ * Otherwise the mingw-w64 would provide broken fstat, stat and wstat symbols.
+ */
+int __cdecl fstat(int _Desc, struct stat *_Stat);
+int __cdecl stat(const char *_Filename, struct stat *_Stat);
+int __cdecl wstat(const wchar_t *_Filename, struct stat *_Stat);
+#else
#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
#ifdef _USE_32BIT_TIME_T
int __cdecl fstat(int _Desc, struct stat *_Stat) __MINGW_ASM_CALL(_fstat32i64);

Thanks, this does seem to work.

Which patch should this be squashed into?

// Martin

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to