diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 1d8fa48b..fc0913ff 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -676,13 +676,18 @@ inline void PrintTo(char32_t* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } -#if GTEST_HAS_WCHAR +// MSVC can be configured to define wchar_t as a typedef of unsigned +// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native +// type. When wchar_t is a typedef, defining an overload for const +// wchar_t* would cause unsigned short* be printed as a wide string, +// possibly causing invalid memory accesses. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Overloads for wide C strings GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); inline void PrintTo(wchar_t* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } -#endif // GTEST_HAS_WCHAR +#endif // Overload for C arrays. Multi-dimensional arrays are printed // properly. diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 6afceeb2..31654b09 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -80,11 +80,6 @@ // is/isn't available. // GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't // enabled. -// GTEST_HAS_WCHAR - Define it to 1/0 to indicate that wide -// characters are/aren't supported. (Google Test -// can be used where std::char_traits and -// libc wchar_t functions (putwc, getwc, etc.) are -// unavailable.) // GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that // std::wstring does/doesn't work (Google Test can // be used where std::wstring is unavailable). @@ -504,89 +499,22 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS -// 1. Calculate default GTEST_HAS_WCHAR and GTEST_HAS_STD_WSTRING values based -// on compiler / STL capabilities. -#if defined(_MSC_VER) -// MSVC always supports ::std::wstring. -#define GTEST_HAS_STD_WSTRING_DEFAULT 1 -// MSVC either defines wchar_t as a typedef of unsigned short, or as a native -// type (in which case, it defines _NATIVE_WCHAR_T_DEFINED). When wchar_t is a -// typedef, defining an overload for const wchar_t* would cause unsigned short* -// be printed as a wide string, possibly causing invalid memory accesses, so we -// omit wchar_t overloads in that case. -#if defined(_NATIVE_WCHAR_T_DEFINED) -#define GTEST_HAS_WCHAR_DEFAULT 1 -#else -#define GTEST_HAS_WCHAR_DEFAULT 0 -#endif - -#elif defined(_LIBCPP_VERSION) -#if _LIBCPP_HAS_WIDE_CHARACTERS -#define GTEST_HAS_WCHAR_DEFAULT 1 -#define GTEST_HAS_STD_WSTRING_DEFAULT 1 -#else -#define GTEST_HAS_WCHAR_DEFAULT 0 -#define GTEST_HAS_STD_WSTRING_DEFAULT 0 -#endif - -#elif defined(__GLIBCXX__) -#if _GLIBCXX_USE_WCHAR_T -#define GTEST_HAS_WCHAR_DEFAULT 1 -#define GTEST_HAS_STD_WSTRING_DEFAULT 1 -#else -#define GTEST_HAS_WCHAR_DEFAULT 0 -#define GTEST_HAS_STD_WSTRING_DEFAULT 0 -#endif - -#else -// Unknown standard library implementation; fall back to a list of OSes known to -// not support wide characters. -// +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. // Cygwin 1.7 and below doesn't support ::std::wstring. // Solaris' libc++ doesn't support it either. Android has // no support for it at least as recent as Froyo (2.2). -// -// Always let the user override the defaults in this case; they might have more -// information about what's supported than we do. #if (!(defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_CYGWIN) || \ defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_HAIKU) || \ defined(GTEST_OS_ESP32) || defined(GTEST_OS_ESP8266) || \ defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \ defined(GTEST_OS_NXP_QN9090) || defined(GTEST_OS_NRF52))) -#define GTEST_HAS_WCHAR_DEFAULT 1 -#define GTEST_HAS_STD_WSTRING_DEFAULT 1 +#define GTEST_HAS_STD_WSTRING 1 #else -#define GTEST_HAS_WCHAR_DEFAULT 0 -#define GTEST_HAS_STD_WSTRING_DEFAULT 0 -#endif -#endif - -// 2. Validate explicit user overrides (if user passed -DGTEST_HAS_*=1) -#if defined(GTEST_HAS_WCHAR) && GTEST_HAS_WCHAR -#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) -#error Cannot explicitly enable GTEST_HAS_WCHAR when wchar_t is a typedef. -#elif defined(_LIBCPP_VERSION) && !_LIBCPP_HAS_WIDE_CHARACTERS -#error Cannot explicitly enable GTEST_HAS_WCHAR without libc++ wide character support. -#elif defined(__GLIBCXX__) && !_GLIBCXX_USE_WCHAR_T -#error Cannot explicitly enable GTEST_HAS_WCHAR without libstdc++ wide character support. -#endif -#endif - -#if defined(GTEST_HAS_STD_WSTRING) && GTEST_HAS_STD_WSTRING -#if defined(_LIBCPP_VERSION) && !_LIBCPP_HAS_WIDE_CHARACTERS -#error Cannot explicitly enable GTEST_HAS_STD_WSTRING without libc++ wide character support. -#elif defined(__GLIBCXX__) && !_GLIBCXX_USE_WCHAR_T -#error Cannot explicitly enable GTEST_HAS_STD_WSTRING without libstdc++ wide character support. -#endif -#endif - -// 3. Set final values if not explicitly overridden by user -#if !defined(GTEST_HAS_WCHAR) -#define GTEST_HAS_WCHAR GTEST_HAS_WCHAR_DEFAULT -#endif -#if !defined(GTEST_HAS_STD_WSTRING) -#define GTEST_HAS_STD_WSTRING GTEST_HAS_STD_WSTRING_DEFAULT +#define GTEST_HAS_STD_WSTRING 0 #endif +#endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_FILE_SYSTEM // Most platforms support a file system. diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc index 0fb2de59..6d1de6d9 100644 --- a/googletest/src/gtest-printers.cc +++ b/googletest/src/gtest-printers.cc @@ -445,10 +445,16 @@ void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); } void PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); } -#if GTEST_HAS_WCHAR +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Prints the given wide C string to the ostream. void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); } -#endif // GTEST_HAS_WCHAR +#endif // wchar_t is native namespace { diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index 8e0a6e75..aa1ddaeb 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -648,7 +648,13 @@ TEST(PrintU32StringTest, EscapesProperly) { Print(p)); } -#if GTEST_HAS_WCHAR +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // const wchar_t*. TEST(PrintWideCStringTest, Const) { @@ -679,7 +685,7 @@ TEST(PrintWideCStringTest, EscapesProperly) { "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", Print(static_cast(s))); } -#endif // GTEST_HAS_WCHAR +#endif // native wchar_t // Tests printing pointers to other char types.