Hi,

thanks for working on this and unifying this inlining issues.  Looks good to me.

Thanks
Kai

Am Mi., 8. Mai 2024 um 14:23 Uhr schrieb Martin Storsjö <mar...@martin.st>:
>
> 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


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

Reply via email to