Prior to 1652e9241b5d8a5a779c6582b1c3c4f4a7cc66e5, the inline functions always were static. Due to reexporting such symbols in C++20 modules (for the C++23 std module), the reexported symbols must not be static, so the inline functions were changed from static inline to __mingw_ovr, which practically is static inline in C mode, but regular inline in C++ mode.
By using regular inline in C++ mode, each use of the functions can (but doesn't need to) emit an external symbol for the inline function, and the callers may either call that function or inline the body of the function. This can have two potential issues; if different translation units are configured differently (with the _USE_32BIT_TIME_T define), but both use the same external symbol for it, the linker will only keep one of them (as they're both inline, and supposed to be the same). In practice, this is rare for _USE_32BIT_TIME_T though. Secondly, such an external symbol may conflict with the actual import library. Such a case was reported at https://github.com/mstorsjo/llvm-mingw/issues/427. (Practically, the issue there was that some built object files defined an external "_time" symbol, i.e. regular "time" with i386 cdecl underscore prefix, from the non-static inline functions. The object also files reference _time32 with dllimport, which via the weak aliases produced by llvm-dlltool end up pulling in the __imp__time symbol, which also brings in a conflicting "_time" symbol.) In short - inline functions can be problematic. Where possible, it's less problematic to use asm(), via __MINGW_ASM_CALL(), to redirect calls directly towards the right function. This has a slight drawback, that this ends up calling the thunks (as the declarations lack dllimport), while we previously could inline the call directly to a dllimported function (avoiding the thunk, fetching the target address via the __imp_ prefixed symbol). We could, easily, add the dllimport attributes on these declarations, but that triggers a GCC bug for how those symbol names are mangled on i386, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114984. (The bug seems to be noted and mentioned as early as 2007, in https://sourceware.org/pipermail/cygwin/2007-February/154845.html, but it doesn't seem to have been fixed since.) Signed-off-by: Martin Storsjö <mar...@martin.st> --- mingw-w64-headers/crt/time.h | 62 ++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/mingw-w64-headers/crt/time.h b/mingw-w64-headers/crt/time.h index f8401903c..d94a9f619 100644 --- a/mingw-w64-headers/crt/time.h +++ b/mingw-w64-headers/crt/time.h @@ -213,26 +213,20 @@ extern "C" { #if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) #define _INC_WTIME_INL - wchar_t *__cdecl _wctime(const time_t *) __MINGW_ATTRIB_DEPRECATED_SEC_WARN; -#ifndef __CRT__NO_INLINE #ifndef _USE_32BIT_TIME_T - __CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime64(_Time); } + wchar_t *__cdecl _wctime(const time_t *_Time) __MINGW_ATTRIB_DEPRECATED_SEC_WARN __MINGW_ASM_CALL(_wctime64); #else - __CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime32(_Time); } + wchar_t *__cdecl _wctime(const time_t *_Time) __MINGW_ATTRIB_DEPRECATED_SEC_WARN __MINGW_ASM_CALL(_wctime32); #endif -#endif /* __CRT__NO_INLINE */ #endif #if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) #define _INC_WTIME_S_INL - errno_t __cdecl _wctime_s(wchar_t *, size_t, const time_t *); -#ifndef __CRT__NO_INLINE #ifndef _USE_32BIT_TIME_T - __CRT_INLINE errno_t __cdecl _wctime_s (wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s (_Buffer,_SizeInWords,_Time); } + errno_t __cdecl _wctime_s (wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) __MINGW_ASM_CALL(_wctime64_s); #else - __CRT_INLINE errno_t __cdecl _wctime_s (wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime32_s (_Buffer,_SizeInWords,_Time); } + errno_t __cdecl _wctime_s (wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) __MINGW_ASM_CALL(_wctime32_s); #endif -#endif /* __CRT__NO_INLINE */ #endif #define _WTIME_DEFINED @@ -241,33 +235,33 @@ extern "C" { #ifndef RC_INVOKED #ifdef _USE_32BIT_TIME_T -__mingw_ovr time_t __CRTDECL time(time_t *_Time) { return _time32(_Time); } +time_t __CRTDECL time(time_t *_Time) __MINGW_ASM_CALL(_time32); #ifdef _UCRT -__mingw_ovr int __CRTDECL timespec_get(struct timespec* _Ts, int _Base) { return _timespec32_get((struct _timespec32*)_Ts, _Base); } -#endif -__mingw_ovr double __CRTDECL difftime(time_t _Time1,time_t _Time2) { return _difftime32(_Time1,_Time2); } -__mingw_ovr struct tm *__CRTDECL localtime(const time_t *_Time) { return _localtime32(_Time); } -__mingw_ovr errno_t __CRTDECL localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime32_s(_Tm,_Time); } -__mingw_ovr struct tm *__CRTDECL gmtime(const time_t *_Time) { return _gmtime32(_Time); } -__mingw_ovr errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t *_Time) { return _gmtime32_s(_Tm, _Time); } -__mingw_ovr char *__CRTDECL ctime(const time_t *_Time) { return _ctime32(_Time); } -__mingw_ovr errno_t __CRTDECL ctime_s(char *_Buf,size_t _SizeInBytes,const time_t *_Time) { return _ctime32_s(_Buf,_SizeInBytes,_Time); } -__mingw_ovr time_t __CRTDECL mktime(struct tm *_Tm) { return _mktime32(_Tm); } -__mingw_ovr time_t __CRTDECL _mkgmtime(struct tm *_Tm) { return _mkgmtime32(_Tm); } +int __CRTDECL timespec_get(struct timespec* _Ts, int _Base) __MINGW_ASM_CALL(_timespec32_get); +#endif +double __CRTDECL difftime(time_t _Time1,time_t _Time2) __MINGW_ASM_CALL(_difftime32); +struct tm *__CRTDECL localtime(const time_t *_Time) __MINGW_ASM_CALL(_localtime32); +errno_t __CRTDECL localtime_s(struct tm *_Tm,const time_t *_Time) __MINGW_ASM_CALL(_localtime32_s); +struct tm *__CRTDECL gmtime(const time_t *_Time) __MINGW_ASM_CALL(_gmtime32); +errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t *_Time) __MINGW_ASM_CALL(_gmtime32_s); +char *__CRTDECL ctime(const time_t *_Time) __MINGW_ASM_CALL(_ctime32); +errno_t __CRTDECL ctime_s(char *_Buf,size_t _SizeInBytes,const time_t *_Time) __MINGW_ASM_CALL(_ctime32_s); +time_t __CRTDECL mktime(struct tm *_Tm) __MINGW_ASM_CALL(_mktime32); +time_t __CRTDECL _mkgmtime(struct tm *_Tm) __MINGW_ASM_CALL(_mkgmtime32); #else -__mingw_ovr time_t __CRTDECL time(time_t *_Time) { return _time64(_Time); } +time_t __CRTDECL time(time_t *_Time) __MINGW_ASM_CALL(_time64); #ifdef _UCRT -__mingw_ovr int __CRTDECL timespec_get(struct timespec* _Ts, int _Base) { return _timespec64_get((struct _timespec64*)_Ts, _Base); } -#endif -__mingw_ovr double __CRTDECL difftime(time_t _Time1,time_t _Time2) { return _difftime64(_Time1,_Time2); } -__mingw_ovr struct tm *__CRTDECL localtime(const time_t *_Time) { return _localtime64(_Time); } -__mingw_ovr errno_t __CRTDECL localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); } -__mingw_ovr struct tm *__CRTDECL gmtime(const time_t *_Time) { return _gmtime64(_Time); } -__mingw_ovr errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t *_Time) { return _gmtime64_s(_Tm, _Time); } -__mingw_ovr char *__CRTDECL ctime(const time_t *_Time) { return _ctime64(_Time); } -__mingw_ovr errno_t __CRTDECL ctime_s(char *_Buf,size_t _SizeInBytes,const time_t *_Time) { return _ctime64_s(_Buf,_SizeInBytes,_Time); } -__mingw_ovr time_t __CRTDECL mktime(struct tm *_Tm) { return _mktime64(_Tm); } -__mingw_ovr time_t __CRTDECL _mkgmtime(struct tm *_Tm) { return _mkgmtime64(_Tm); } +int __CRTDECL timespec_get(struct timespec* _Ts, int _Base) __MINGW_ASM_CALL(_timespec64_get); +#endif +double __CRTDECL difftime(time_t _Time1,time_t _Time2) __MINGW_ASM_CALL(_difftime64); +struct tm *__CRTDECL localtime(const time_t *_Time) __MINGW_ASM_CALL(_localtime64); +errno_t __CRTDECL localtime_s(struct tm *_Tm,const time_t *_Time) __MINGW_ASM_CALL(_localtime64_s); +struct tm *__CRTDECL gmtime(const time_t *_Time) __MINGW_ASM_CALL(_gmtime64); +errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t *_Time) __MINGW_ASM_CALL(_gmtime64_s); +char *__CRTDECL ctime(const time_t *_Time) __MINGW_ASM_CALL(_ctime64); +errno_t __CRTDECL ctime_s(char *_Buf,size_t _SizeInBytes,const time_t *_Time) __MINGW_ASM_CALL(_ctime64_s); +time_t __CRTDECL mktime(struct tm *_Tm) __MINGW_ASM_CALL(_mktime64); +time_t __CRTDECL _mkgmtime(struct tm *_Tm) __MINGW_ASM_CALL(_mkgmtime64); #endif #endif /* !RC_INVOKED */ -- 2.34.1 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public