On Sat, 10 Jan 2026 at 10:45, Wang Jinghao <[email protected]> wrote: > > On the mingw32 target, std::system_category().message(int) uses > FormatMessage api to format error messages. When the error message contains > insert sequences, it is unsafe not to use the FORMAT_MESSAGE_OGNORE_INSERTS > flag, as seen at: > https://devblogs.microsoft.com/oldnewthing/20071128-00/?p=24353 > > The output of FormatMessage ends with "\r\n" and includes a Full stop > character > used by the current thread's UI language. Now, we will remove "\r\n" and > any trailing '.' from the output in any language environment. > > In the testsuite for std::system_category().message(int), we first switch the > thread UI language to en-US tomeet expectations in any language environment.
Thanks, the patch looks good now. > libstdc++-v3/ChangeLog: > > * src/c++11/system_error.cc (system_error_category) [_WIN32]: > Fix typo in __MINGW32__ macro name. > Adjust behavior on the mingw32 target. The two lines above relate to the error_category/system_category.cc test, not the src/c++11/system_category.cc source file, right? > Use FormatMessageA function instead of FormatMessage macro. > * testsuite/19_diagnostics/error_category/system_category.cc: > Adjust behavior on the mingw32 target. I've just noticed that there's no Signed-off-by trailer in the patch. Do you have a copyright assignment filed with the FSF? As documented at https://gcc.gnu.org/contribute.html#legal we need either a copyright assignment, or DCO sign-off. If you don't have a copyrigh assignment, could you please add the Signed-off-by trailer if you are willing and able to agree to the terms of https://gcc.gnu.org/dco.html ? Thanks > --- > libstdc++-v3/src/c++11/system_error.cc | 21 ++++++++++--------- > .../error_category/system_category.cc | 18 +++++++++++++--- > 2 files changed, 26 insertions(+), 13 deletions(-) > > diff --git a/libstdc++-v3/src/c++11/system_error.cc > b/libstdc++-v3/src/c++11/system_error.cc > index 548c88fcfde..7e3a3a0c904 100644 > --- a/libstdc++-v3/src/c++11/system_error.cc > +++ b/libstdc++-v3/src/c++11/system_error.cc > @@ -161,22 +161,23 @@ namespace > #if defined(_WIN32) && !defined(__CYGWIN__) > char* buf = nullptr; > auto len > - = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM > - | FORMAT_MESSAGE_ALLOCATE_BUFFER, > - nullptr, > - i, > - LANG_USER_DEFAULT, > - reinterpret_cast<LPTSTR>(&buf), > - 0, > - nullptr); > + = FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM > + | FORMAT_MESSAGE_ALLOCATE_BUFFER > + | FORMAT_MESSAGE_IGNORE_INSERTS, > + nullptr, > + i, > + LANG_USER_DEFAULT, > + reinterpret_cast<LPTSTR>(&buf), > + 0, > + nullptr); > if (len > 0) > { > struct deleter { > void operator()(void* p) const { ::LocalFree(p); } > }; > std::unique_ptr<char[], deleter> guard(buf); > - if (len > 3 && !__builtin_memcmp(buf + len - 3, ".\r\n", 3)) > [[likely]] > - len -= 3; > + if (len > 2 && !__builtin_memcmp (buf + len - 2, "\r\n", 2)) > [[likely]] > + len -= 2 + (buf[len - 3] == '.'); > return string(buf, len); > } > return string("Unknown error code"); > diff --git > a/libstdc++-v3/testsuite/19_diagnostics/error_category/system_category.cc > b/libstdc++-v3/testsuite/19_diagnostics/error_category/system_category.cc > index 250d34f9bb5..03577234c43 100644 > --- a/libstdc++-v3/testsuite/19_diagnostics/error_category/system_category.cc > +++ b/libstdc++-v3/testsuite/19_diagnostics/error_category/system_category.cc > @@ -21,6 +21,11 @@ > #include <locale> > #include <testsuite_hooks.h> > > +#if defined __MINGW32__ || defined __MINGW64__ > +#define WIN32_LEAN_AND_MEAN > +#include <windows.h> > +#endif > + > void > test01() > { > @@ -34,7 +39,7 @@ test02() > const std::error_category& cat = std::system_category(); > std::error_condition cond; > > -#if defined __MING32__ || defined __MINGW64__ > +#if defined __MINGW32__ || defined __MINGW64__ > cond = cat.default_error_condition(8); // ERROR_NOT_ENOUGH_MEMORY > VERIFY( cond.value() == ENOMEM ); > VERIFY( cond.category() == std::generic_category() ); > @@ -112,9 +117,16 @@ test03() > // set "C" locale to get expected message > auto loc = std::locale::global(std::locale::classic()); > > -#if defined __MING32__ || defined __MINGW64__ > +#if defined __MINGW32__ || defined __MINGW64__ > + // On Windows, set thread preferred UI languages to "en-US" > + // to get expected message > + ULONG num_langs = 1; > + SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, L"en-US\0", &num_langs); > + > std::string msg = std::system_category().message(5); // ERROR_ACCESS_DENIED > - VERIFY(msg == "Access denied"); > + VERIFY(msg == "Access is denied"); > + > + SetThreadPreferredUILanguages(MUI_RESET_FILTERS, nullptr, nullptr); > #else > std::string msg = std::system_category().message(EBADF); > VERIFY( msg.find("file") != std::string::npos ); > -- > 2.52.0 >
