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);



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

Reply via email to