On 4/5/19 9:15 AM, Martin Storsjö wrote:
On Thu, 4 Apr 2019, Jacek Caban wrote:

On 4/4/19 3:07 PM, Martin Storsjö wrote:
On Thu, 4 Apr 2019, Jacek Caban wrote:

Signed-off-by: Jacek Caban <ja...@codeweavers.com>
---
mingw-w64-crt/Makefile.am              |  2 +-
mingw-w64-crt/lib-common/msvcrt.def.in |  4 +-
mingw-w64-crt/lib32/msvcr100.def.in    |  4 +-
mingw-w64-crt/lib32/msvcr80.def.in     |  2 +
mingw-w64-crt/lib32/msvcr90.def.in     |  4 +-
mingw-w64-crt/lib64/msvcr100.def.in    |  4 +-
mingw-w64-crt/lib64/msvcr80.def.in     |  2 +
mingw-w64-crt/lib64/msvcr90.def.in     |  4 +-
mingw-w64-crt/misc/difftime.c          | 21 ----------
mingw-w64-crt/misc/difftime32.c        |  9 -----
mingw-w64-crt/misc/difftime64.c        |  9 -----
mingw-w64-headers/crt/time.h           | 55 +++++++++++---------------
12 files changed, 37 insertions(+), 83 deletions(-)
delete mode 100644 mingw-w64-crt/misc/difftime.c
delete mode 100644 mingw-w64-crt/misc/difftime32.c
delete mode 100644 mingw-w64-crt/misc/difftime64.c

Ok with me, if you extend the commit message to mention all the changes. The changes IMO now include the following three change categories:

- Use importlibs for more time functions
- Unify inline attribute strategies for time functions in headers
- Use _CRTIMP on more time functions


Multiple line in commit message usually is a good sign that the patch should be split ;) And I agree, I could do better job at that. I split the patch and pushed.

This turned out to break compilation in certain cases for me.

The culprit is that __forceinline is a bit deceptive (and so is __CRT_INLINE). For good reasons I was using __mingw_static_ovr here before, for the UCRT case.

These three macros expand to slightly different things depending on compiler and context, but for the C, modern clang/gcc case, they are as follows:

#define __CRT_INLINE extern inline __attribute__((__gnu_inline__))
#define __forceinline extern __inline__ __attribute__((__always_inline__,__gnu_inline__)) #define __mingw_static_ovr static __attribute__ ((__unused__)) __inline__ __cdecl

Both __CRT_INLINE and __forceinline declare the inline functions as extern, in combination with the gnu_inline attribute. The gnu_inline attribute, in combination with extern, means that when you take the address of the function, it shouldn't generate and reference the inline version of the function, but reference the extern copy of the function available in another translation unit.

This obviously is desireable for getting the same function pointer to a function in all translation units that refer to it, but doesn't work for functions that don't exist elsewhere in that form.

I'm not sure about how many of the existing cases of __forceinline and __CRT_INLINE that really intentionally want this behaviour, so I've proceeded cautiously and used __mingw_static_ovr in a few places for UCRT where I otherwise ran into issues.

But in any case, we either need to add import library aliases for these cases (which doesn't work for things that vary depending on _USE_32BIT_TIME_T), remove extern from __forceinline and __CRT_INLINE, or use a different inline attribute (e.g. __mingw_static_ovr) for these particular inlines.


It would be great to have __forceinline fixed. I've seen a problems in code using static __forceinline multiple times. I also recall that attempts to change that had their problems, so it's more tricky than it seems (if possible).


How about doing things in msvc ucrt compatible way? Like the patch I attached as an example (not yet tested)?


Jacek

diff --git a/mingw-w64-headers/crt/corecrt.h b/mingw-w64-headers/crt/corecrt.h
index d171a013..44d32d62 100644
--- a/mingw-w64-headers/crt/corecrt.h
+++ b/mingw-w64-headers/crt/corecrt.h
@@ -143,6 +143,14 @@ typedef __time64_t time_t;
 #define _CRT_SECURE_CPP_NOTHROW throw()
 #endif
 
+#ifndef __CRTDECL
+#if !defined(__cplusplus) && defined(__GNUC__)
+#define __CRTDECL __cdecl __attribute__ ((__unused__))
+#else
+#define __CRTDECL __cdecl
+#endif
+#endif
+
 #if defined(__cplusplus) && _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES
 
 #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(__ret,__func,__dsttype,__dst) \
diff --git a/mingw-w64-headers/crt/time.h b/mingw-w64-headers/crt/time.h
index 02abd7b6..be2398d4 100644
--- a/mingw-w64-headers/crt/time.h
+++ b/mingw-w64-headers/crt/time.h
@@ -216,27 +216,27 @@ extern "C" {
 #ifndef RC_INVOKED
 
 #ifdef _USE_32BIT_TIME_T
-__forceinline time_t __cdecl time(time_t *_Time) { return _time32(_Time); }
-__forceinline double __cdecl difftime(time_t _Time1,time_t _Time2)  { return _difftime32(_Time1,_Time2); }
-__forceinline struct tm *__cdecl localtime(const time_t *_Time) { return _localtime32(_Time); }
-__forceinline errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime32_s(_Tm,_Time); }
-__forceinline struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime32(_Time); }
-__forceinline errno_t __cdecl gmtime_s(struct tm *_Tm, const time_t *_Time)   { return _gmtime32_s(_Tm, _Time); }
-__forceinline char *__cdecl ctime(const time_t *_Time) { return _ctime32(_Time); }
-__forceinline errno_t __cdecl ctime_s(char *_Buf,size_t _SizeInBytes,const time_t *_Time) { return _ctime32_s(_Buf,_SizeInBytes,_Time); }
-__forceinline time_t __cdecl mktime(struct tm *_Tm) { return _mktime32(_Tm); }
-__forceinline time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime32(_Tm); }
+static __inline time_t __CRTDECL time(time_t *_Time) { return _time32(_Time); }
+static __inline double __CRTDECL difftime(time_t _Time1,time_t _Time2)  { return _difftime32(_Time1,_Time2); }
+static __inline struct tm *__CRTDECL localtime(const time_t *_Time) { return _localtime32(_Time); }
+static __inline errno_t __CRTDECL localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime32_s(_Tm,_Time); }
+static __inline struct tm *__CRTDECL gmtime(const time_t *_Time) { return _gmtime32(_Time); }
+static __inline errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t *_Time)   { return _gmtime32_s(_Tm, _Time); }
+static __inline char *__CRTDECL ctime(const time_t *_Time) { return _ctime32(_Time); }
+static __inline errno_t __CRTDECL ctime_s(char *_Buf,size_t _SizeInBytes,const time_t *_Time) { return _ctime32_s(_Buf,_SizeInBytes,_Time); }
+static __inline time_t __CRTDECL mktime(struct tm *_Tm) { return _mktime32(_Tm); }
+static __inline time_t __CRTDECL _mkgmtime(struct tm *_Tm) { return _mkgmtime32(_Tm); }
 #else
-__forceinline time_t __cdecl time(time_t *_Time) { return _time64(_Time); }
-__forceinline double __cdecl difftime(time_t _Time1,time_t _Time2) { return _difftime64(_Time1,_Time2); }
-__forceinline struct tm *__cdecl localtime(const time_t *_Time) { return _localtime64(_Time); }
-__forceinline errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); }
-__forceinline struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime64(_Time); }
-__forceinline errno_t __cdecl gmtime_s(struct tm *_Tm, const time_t *_Time) { return _gmtime64_s(_Tm, _Time); }
-__forceinline char *__cdecl ctime(const time_t *_Time) { return _ctime64(_Time); }
-__forceinline errno_t __cdecl ctime_s(char *_Buf,size_t _SizeInBytes,const time_t *_Time) { return _ctime64_s(_Buf,_SizeInBytes,_Time); }
-__forceinline time_t __cdecl mktime(struct tm *_Tm) { return _mktime64(_Tm); }
-__forceinline time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime64(_Tm); }
+static __inline time_t __CRTDECL time(time_t *_Time) { return _time64(_Time); }
+static __inline double __CRTDECL difftime(time_t _Time1,time_t _Time2) { return _difftime64(_Time1,_Time2); }
+static __inline struct tm *__CRTDECL localtime(const time_t *_Time) { return _localtime64(_Time); }
+static __inline errno_t __CRTDECL localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); }
+static __inline struct tm *__CRTDECL gmtime(const time_t *_Time) { return _gmtime64(_Time); }
+static __inline errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t *_Time) { return _gmtime64_s(_Tm, _Time); }
+static __inline char *__CRTDECL ctime(const time_t *_Time) { return _ctime64(_Time); }
+static __inline errno_t __CRTDECL ctime_s(char *_Buf,size_t _SizeInBytes,const time_t *_Time) { return _ctime64_s(_Buf,_SizeInBytes,_Time); }
+static __inline time_t __CRTDECL mktime(struct tm *_Tm) { return _mktime64(_Tm); }
+static __inline time_t __CRTDECL _mkgmtime(struct tm *_Tm) { return _mkgmtime64(_Tm); }
 #endif
 
 #endif /* !RC_INVOKED */
@@ -282,16 +282,16 @@ struct timezone {
 #endif
 
 #ifdef _POSIX_THREAD_SAFE_FUNCTIONS
-__forceinline struct tm *__cdecl localtime_r(const time_t *_Time, struct tm *_Tm) {
+static __inline struct tm *__CRTDECL localtime_r(const time_t *_Time, struct tm *_Tm) {
   return localtime_s(_Tm, _Time) ? NULL : _Tm;
 }
-__forceinline struct tm *__cdecl gmtime_r(const time_t *_Time, struct tm *_Tm) {
+static __inline struct tm *__CRTDECL gmtime_r(const time_t *_Time, struct tm *_Tm) {
   return gmtime_s(_Tm, _Time) ? NULL : _Tm;
 }
-__forceinline char *__cdecl ctime_r(const time_t *_Time, char *_Str) {
+static __inline char *__CRTDECL ctime_r(const time_t *_Time, char *_Str) {
   return ctime_s(_Str, 0x7fffffff, _Time) ? NULL : _Str;
 }
-__forceinline char *__cdecl asctime_r(const struct tm *_Tm, char * _Str) {
+static __inline char *__CRTDECL asctime_r(const struct tm *_Tm, char * _Str) {
   return asctime_s(_Str, 0x7fffffff, _Tm) ? NULL : _Str;
 }
 #endif
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to