From b0cc7b53a53f180c0b70b8b2f02999be78a32395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 1 Jun 2021 09:04:58 +0000 Subject: [PATCH] [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 --- libcxx/src/locale.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp index 903c78a1bde9..d5ab8fb3b836 100644 --- a/libcxx/src/locale.cpp +++ b/libcxx/src/locale.cpp @@ -4597,7 +4597,10 @@ void __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++ = '#';