[libcxx] Don't use an undefined '+' in unsigned/octal/hexal print formats
If building code like this:
unsigned long val = 1000;
snprintf(buf, sizeof(buf), "%+lu", val);
with clang, clang warns
warning: flag '+' results in undefined behavior with 'u' conversion specifier [-Wformat]
Therefore, don't construct such undefined format strings. (There's
no compiler warnings here, as the compiler can't inspect dynamically
assembled format strings.)
This fixes number formatting in mingw-w64 if built with
`__USE_MINGW_ANSI_STDIO` defined (there, the '+' flag causes a
leading plus to be printed when formatting unsigned numbers too,
while the '+' flag doesn't cause any extra leading plus in other
stdio implementations).
Differential Revision: https://reviews.llvm.org/D103444
NOKEYCHECK=True
GitOrigin-RevId: b0cc7b53a53f180c0b70b8b2f02999be78a32395
diff --git a/src/locale.cpp b/src/locale.cpp
index 903c78a..d5ab8fb 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -4597,7 +4597,10 @@
__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
ios_base::fmtflags __flags)
{
- if (__flags & ios_base::showpos)
+ if ((__flags & ios_base::showpos) &&
+ (__flags & ios_base::basefield) != ios_base::oct &&
+ (__flags & ios_base::basefield) != ios_base::hex &&
+ __signd)
*__fmtp++ = '+';
if (__flags & ios_base::showbase)
*__fmtp++ = '#';