Declare __argc, __argv, __wargv, _pgmptr, _wpgmptr via corresponding
__p_func() function as now it is provided by every CRT import library
(either directly or manually by mingw-w64 code) which also provides that
symbol.
Declare _environ and _wenviron based on architecture. On i386 and x64 in
msvcr*, and in UCRT on all architectures, it is always defined via
__p__environ() and __p__wenviron() functions which are provided by every
CRT import library (wide variant since VC20+). On arm32 and arm64 in
msvcrt, they are via _get_environ() and _get_wenviron() functions.
_osplatform, _osver, _winver, _winmajor, _winminor are declared as global
variables directly. They are available since the first crtdll.dll library
up to the msvcr80.dll (both i386 and x64). All these variables were removed
in Visual Studio 2008, together with corresponding __p_func fuctions. So
there is no reason to define them via functions.
Signed-off-by: Martin Storsjö <martin@martin.st>
Global variable _sys_nerr is present in every CRT library except UCRT.
Function __sys_nerr() is present since msvcr80.dll and returns pointer to
the global variable _sys_nerr. This function is not present in any
msvcrt.dll library version, but is present in UCRT library.
Same applies for global array _sys_errlist[] and function __sys_errlist()
which returns pointer to the first member of __sys_errlist[] array.
For all pre-msvcr80 CRT import libraries provides mingw-w64 functions
__sys_errlist() and __sys_nerr(). And change stdlib.h header file to
define _sys_nerr and _sys_errlist via __sys_errlist() and __sys_nerr()
functions. With this change, definitions will be compatible for all CRT
versions (crtdll, msvcrt, msvcr80+, UCRT).
Signed-off-by: Martin Storsjö <martin@martin.st>
_mbcasemap[] global array is available since Microsoft Visual C++ 5.0 SP1
version of msvcrt.dll for all architectures, and then also in new msvcr*
DLL libraries, and also in UCRT.
__p__mbcasemap() function is available in msvcrt.dll only for i386
architecture since Microsoft Visual C++ 5.0 SP1. For new msvcr* DLL
libraries, it is available also for non-i386 architecture.
So provide fallback implementation of __p__mbcasemap() function in non-i386
msvcrt.dll import libraries. And define _mbcasemap in header file via
__p__mbcasemap() function.
Signed-off-by: Martin Storsjö <martin@martin.st>
Global variable _mbctype[] is not available in UCRT and msvcrt10.dll. UCRT
instead provides __p__mbctype() function which returns pointer to the first
_mbctype array member. msvcrt10.dll does not have any replacement.
Function __p__mbctype() is present also in all msvcrt VC versions starting
from VC20 for all architectures. In OS system version of msvcrt.dll, this
function is present only for i386 architecture.
Therefore function __p__mbctype() is not present in: crtdll.dll,
msvcrt10.dll and x64, arm32 and arm64 versions of msvcrt.dll.
So for import libraries crtdll and x64, arm32 and arm64 versions of msvcrt
provides fallback implementation of __p__mbctype() function via _mbctype[].
Then change mbctype.h include file to define _mbctype via function call
__p__mbctype(). This change allows to use _mbctype with all CRT libraries,
including UCRT, except msvcrt10 (which does not have neither _mbctype[],
nor __p__mbctype()).
Signed-off-by: Martin Storsjö <martin@martin.st>
_wctype is a global variable exported from CRT library and therefore has to
be always accessed by the import symbol via __MINGW_IMP_SYMBOL(_wctype).
There is no CRT function which could return pointer to this variable.
_wctype variable is present since msvcr70.dll and also since Windows Server
2003 version of msvcrt.dll. It is present also in UCRT. For older versions
there is no fallback or emulation.
Signed-off-by: Martin Storsjö <martin@martin.st>
Global variable _pwctype is not available in UCRT. Instead UCRT has only
__pwctype_func() function which returns value of _pwctype variable.
Function __pwctype_func() is available also in msvcrt since VC70. For
previous i386 msvcrt versions there is a __p__pwctype() function which
returns pointer to the _pwctype variable.
Like for _pctype changes, add fallback versions of __pwctype_func() and
__p__pwctype() functions suitable for older CRT versions. And change
definition of _pwctype in header file from the global variable to macro
which calls __pwctype_func() function.
This change allows to use _pwctype with all CRT libraries, including UCRT.
Fix also type of _pwctype. In msvc its type is wctype_t and not unsigned
short. Note that wctype_t is just typedef for unsigned short, so this
should be just a cosmetic change to align with msvc.
Signed-off-by: Martin Storsjö <martin@martin.st>
__pctype_func is available in msvcrt since VC70. __p__pctype is available
in i386 msvcrt version since VC20. _pctype is available in all versions
except in UCRT.
Define fallback __pctype_func() function implementation via __p__pctype()
function. And define __p__pctype() via _pctype variable.
With this change every CRT import library provides __pctype_func()
function. So remove #ifdefs for _pctype declarations in header files and
unifies _pctype definitions between different CRT libraries.
Signed-off-by: Martin Storsjö <martin@martin.st>
Provide fallback ___mb_cur_max_func() implementation via __p___mb_cur_max()
function. __p___mb_cur_max() is available since VC20. For earlier version
import libraries provide fallback __p___mb_cur_max() implementation via
global variable __mb_cur_max.
With this change every CRT import library provides ___mb_cur_max_func()
function. So remove #ifdefs for __mb_cur_max declarations in header files.
Signed-off-by: Martin Storsjö <martin@martin.st>
Both functions __iob_func() and __p__iob() returns same constant value -
pointer to the first member of _iob[] array. Symbol for _iob[] array is
present in every msvcrt DLL library.
Function __p__iob() is provided by every i386 version of msvcrt DLL library
since VC20. But it is not available in any non-i386 version. Function
__iob_func() is provided by every version of msvcrt DLL library since VC70
for every architecture. __iob_func() is provided also by every X64 and ARM
versions of OS system version msvcrt.dll.
Note that UCRT does not provide neither __iob_func(), nor __p__iob()
function.
So for all msvcrt versions before VC70 define __iob_func symbol as an alias
to __p__iob symbol. And for versions before VC20 provide custom mingw-w64
implementation of __iob_func() function which returns pointer to the first
member of _iob[] array.
This change allows to remove #ifdef around _iob declaration in stdio.h and
wchar.h header files as now the __iob_func() function is provided by every
version of msvcrt import library.
Signed-off-by: Martin Storsjö <martin@martin.st>
Existent enumerators have been updated a little to prevent a trailing comma.
Signed-off-by: Biswapriyo Nath <nathbappai@gmail.com>
Signed-off-by: LIU Hao <lh_mouse@126.com>
This commit reveals names in three categories:
1) Names that start with an underscore and a letter in uppercase are reserved
for implementations. These can be revealed even with strict standard
conformance.
2) Names that start with an underscore and a letter in lowercase are reserved
for implementations in file scopes (i.e. they are not eligible for macros).
These can be revealed even with strict standard conformance.
3) Some names reference POSIX functions. These are revealed when a POSIX, GNU
or BSD feature test macro is defined.
Signed-off-by: LIU Hao <lh_mouse@126.com>
This fixes build errors with GCC, after
e5ac8c5509cd729b97065733cf4b0df0ec732797; GCC doesn't accept
__asm__(), expanded from __MINGW_ASM_CALL(), after
__attribute__((deprecated())), while Clang accepts both orders.
By default, __MINGW_ATTRIB_DEPRECATED_SEC_WARN doesn't expand
to anything, but if built with defines that makes this expand to
a deprecation attribute, the build would fail with GCC.
Signed-off-by: Martin Storsjö <martin@martin.st>
All CRT import libraries provides UCRT-compatible *stat* symbols since
commit b463875615.
So define all stat* macros consistently with definitions of aliases in def
files based on UCRT. There is no need to have ifdef for non-UCRT version
anymore.
Signed-off-by: Martin Storsjö <martin@martin.st>
Clang doesn't support the ms_printf/scanf and gnu_printf/scanf
format attributes, only plain "printf" and "scanf".
We already expand e.g. __MINGW_PRINTF_FORMAT (which differs depending
on __USE_MINGW_ANSI_STDIO) into plain "printf" for Clang, since
015e637b4b. However, a number
of functions explicitly declared either gnu or ms style formats,
which caused these functions to not get any format string diagnostics.
This fixes https://github.com/llvm/llvm-project/issues/68995,
which reported that no warnings are produced for mismatched
printf/scanf format strings, when compiling with Clang, with
a toolchain targeting msvcrt (i.e. in practice using
__USE_MINGW_ANSI_STDIO enabled).
Signed-off-by: Martin Storsjö <martin@martin.st>
Prefer declaring these attributes with such macros, rather than
spelling out the full attribute.
These macros were added in 73e50d0577
in 2013, but haven't been used in mingw-w64 headers since (although
they may have been used in user code).
These macros, which expand to the full attribute, differ slightly
from the other preexisting macros (which are used quite widely)
like __MINGW_PRINTF_FORMAT, which expand only to the type string
"gnu_printf", "ms_printf" or "printf".
However as we do have these existing macros in this form, for
declaring a specific form of these format attributes, take them into
use where applicable.
Signed-off-by: Martin Storsjö <martin@martin.st>
Prior to 1652e9241b, the time.h
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ö <martin@martin.st>
We should prefer using a macro which doesn't declare functions
as static inline in C++ mode.
This macro was added in bc6a874889,
without an explanation of why it was added.
Signed-off-by: Martin Storsjö <martin@martin.st>
When building the C++23 std modules, at least with libc++, the
C++ module needs to reexport a number of standard C functions.
The regular libc++ headers (the ones used even if not using
C++ modules) do this, essentially:
namespace std {
using ::ctime;
}
Thus reexporting the regular C function ctime within the std
namespace.
When building libc++ as a module, this function gets emitted as
part of the C++ std module, like this:
export namespace std {
using std::ctime;
}
This tries to export the function as part of the C++ module. In the
case of our inline functions, this errors out if the inline functions
are static inline:
<prefix>/share/libc++/v1/std/ctime.inc:20:14: error: using declaration referring to 'ctime' with internal linkage cannot be exported
20 | using std::ctime;
| ^
<prefix>/x86_64-w64-mingw32/include/time.h:267:29: note: target of using declaration
267 | static __inline char *__CRTDECL ctime(const time_t *_Time) { return _ctime64(_Time); }
| ^
Therefore, prefer using the __mingw_ovr macro for these inline
declarations. This macro expands to regular plain (non-static)
inline in C++ mode, while it still expands to static inline in C mode.
Signed-off-by: Martin Storsjö <martin@martin.st>
This redefining of the macro was added in
824ceb1d12, without an explanation
of why that was done.
If we really do need to use a different inline declaration for
these functions, we should use a different macro, so we don't
alter the meaning of the __mingw_ovr define after including
swprintf.inl or wchar.h.
This practically has the effect, that these inlines are declared
as regular "inline" instead of "static __inline__" when built
in C++ mode with a GCC compatible compiler. This matches how
the __mingw_ovr macro is defined and used for many other inline
functions.
Signed-off-by: Martin Storsjö <martin@martin.st>
We already have non-inline versions of these functions; use the
non-inline version consistently, to avoid potential cases of
inconsistency.
Signed-off-by: Martin Storsjö <martin@martin.st>