@@ -554,7 +554,8 @@ TEST_F(FormatConvertTest, Uint128) {
554554}
555555
556556template <typename Floating>
557- void TestWithMultipleFormatsHelper (const std::vector<Floating> &floats) {
557+ void TestWithMultipleFormatsHelper (const std::vector<Floating> &floats,
558+ const std::set<Floating> &skip_verify) {
558559 const NativePrintfTraits &native_traits = VerifyNativeImplementation ();
559560 // Reserve the space to ensure we don't allocate memory in the output itself.
560561 std::string str_format_result;
@@ -602,7 +603,16 @@ void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) {
602603 AppendPack (&str_format_result, format, absl::MakeSpan (args));
603604 }
604605
605- if (string_printf_result != str_format_result) {
606+ #ifdef _MSC_VER
607+ // MSVC has a different rounding policy than us so we can't test our
608+ // implementation against the native one there.
609+ continue ;
610+ #elif defined(__APPLE__)
611+ // Apple formats NaN differently (+nan) vs. (nan)
612+ if (std::isnan (d)) continue ;
613+ #endif
614+ if (string_printf_result != str_format_result &&
615+ skip_verify.find (d) == skip_verify.end ()) {
606616 // We use ASSERT_EQ here because failures are usually correlated and a
607617 // bug would print way too many failed expectations causing the test
608618 // to time out.
@@ -616,12 +626,6 @@ void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) {
616626}
617627
618628TEST_F (FormatConvertTest, Float) {
619- #ifdef _MSC_VER
620- // MSVC has a different rounding policy than us so we can't test our
621- // implementation against the native one there.
622- return ;
623- #endif // _MSC_VER
624-
625629 std::vector<float > floats = {0 .0f ,
626630 -0 .0f ,
627631 .9999999f ,
@@ -635,7 +639,8 @@ TEST_F(FormatConvertTest, Float) {
635639 std::numeric_limits<float >::epsilon (),
636640 std::numeric_limits<float >::epsilon () + 1 .0f ,
637641 std::numeric_limits<float >::infinity (),
638- -std::numeric_limits<float >::infinity ()};
642+ -std::numeric_limits<float >::infinity (),
643+ std::nanf (" " )};
639644
640645 // Some regression tests.
641646 floats.push_back (0 .999999989f );
@@ -664,21 +669,14 @@ TEST_F(FormatConvertTest, Float) {
664669 std::sort (floats.begin (), floats.end ());
665670 floats.erase (std::unique (floats.begin (), floats.end ()), floats.end ());
666671
667- #ifndef __APPLE__
668- // Apple formats NaN differently (+nan) vs. (nan)
669- floats.push_back (std::nan (" " ));
670- #endif
671-
672- TestWithMultipleFormatsHelper (floats);
672+ TestWithMultipleFormatsHelper (floats, {});
673673}
674674
675675TEST_F (FormatConvertTest, Double) {
676- #ifdef _MSC_VER
677- // MSVC has a different rounding policy than us so we can't test our
678- // implementation against the native one there.
679- return ;
680- #endif // _MSC_VER
681-
676+ // For values that we know won't match the standard library implementation we
677+ // skip verification, but still run the algorithm to catch asserts/sanitizer
678+ // bugs.
679+ std::set<double > skip_verify;
682680 std::vector<double > doubles = {0.0 ,
683681 -0.0 ,
684682 .99999999999999 ,
@@ -692,7 +690,8 @@ TEST_F(FormatConvertTest, Double) {
692690 std::numeric_limits<double >::epsilon (),
693691 std::numeric_limits<double >::epsilon () + 1 ,
694692 std::numeric_limits<double >::infinity (),
695- -std::numeric_limits<double >::infinity ()};
693+ -std::numeric_limits<double >::infinity (),
694+ std::nan (" " )};
696695
697696 // Some regression tests.
698697 doubles.push_back (0.99999999999999989 );
@@ -722,33 +721,29 @@ TEST_F(FormatConvertTest, Double) {
722721 " 5084551339423045832369032229481658085593321233482747978262041447231"
723722 " 68738177180919299881250404026184124858368.000000" ;
724723
725- if (!gcc_bug_22142) {
726- for (int exp = -300 ; exp <= 300 ; ++exp) {
727- const double all_ones_mantissa = 0x1fffffffffffff ;
728- doubles.push_back (std::ldexp (all_ones_mantissa, exp));
724+ for (int exp = -300 ; exp <= 300 ; ++exp) {
725+ const double all_ones_mantissa = 0x1fffffffffffff ;
726+ doubles.push_back (std::ldexp (all_ones_mantissa, exp));
727+ if (gcc_bug_22142) {
728+ skip_verify.insert (doubles.back ());
729729 }
730730 }
731731
732732 if (gcc_bug_22142) {
733- for ( auto &d : doubles) {
734- using L = std::numeric_limits< double > ;
735- double d2 = std::abs (d);
736- if (d2 == L::max () || d2 == L::min () || d2 == L:: denorm_min ()) {
737- d = 0 ;
738- }
739- }
733+ using L = std::numeric_limits< double >;
734+ skip_verify. insert ( L::max ()) ;
735+ skip_verify. insert ( L::min ()); // NOLINT
736+ skip_verify. insert ( L::denorm_min ());
737+ skip_verify. insert (- L::max ()) ;
738+ skip_verify. insert (- L::min ()); // NOLINT
739+ skip_verify. insert (- L::denorm_min ());
740740 }
741741
742742 // Remove duplicates to speed up the logic below.
743743 std::sort (doubles.begin (), doubles.end ());
744744 doubles.erase (std::unique (doubles.begin (), doubles.end ()), doubles.end ());
745745
746- #ifndef __APPLE__
747- // Apple formats NaN differently (+nan) vs. (nan)
748- doubles.push_back (std::nan (" " ));
749- #endif
750-
751- TestWithMultipleFormatsHelper (doubles);
746+ TestWithMultipleFormatsHelper (doubles, skip_verify);
752747}
753748
754749TEST_F (FormatConvertTest, DoubleRound) {
@@ -1069,11 +1064,6 @@ TEST_F(FormatConvertTest, ExtremeWidthPrecision) {
10691064}
10701065
10711066TEST_F (FormatConvertTest, LongDouble) {
1072- #ifdef _MSC_VER
1073- // MSVC has a different rounding policy than us so we can't test our
1074- // implementation against the native one there.
1075- return ;
1076- #endif // _MSC_VER
10771067 const NativePrintfTraits &native_traits = VerifyNativeImplementation ();
10781068 const char *const kFormats [] = {" %" , " %.3" , " %8.5" , " %9" , " %.5000" ,
10791069 " %.60" , " %+" , " % " , " %-10" };
@@ -1134,10 +1124,18 @@ TEST_F(FormatConvertTest, LongDouble) {
11341124 for (auto d : doubles) {
11351125 FormatArgImpl arg (d);
11361126 UntypedFormatSpecImpl format (fmt_str);
1127+ std::string result = FormatPack (format, {&arg, 1 });
1128+
1129+ #ifdef _MSC_VER
1130+ // MSVC has a different rounding policy than us so we can't test our
1131+ // implementation against the native one there.
1132+ continue ;
1133+ #endif // _MSC_VER
1134+
11371135 // We use ASSERT_EQ here because failures are usually correlated and a
11381136 // bug would print way too many failed expectations causing the test to
11391137 // time out.
1140- ASSERT_EQ (StrPrint (fmt_str.c_str (), d), FormatPack (format, {&arg, 1 }) )
1138+ ASSERT_EQ (StrPrint (fmt_str.c_str (), d), result )
11411139 << fmt_str << " " << StrPrint (" %.18Lg" , d) << " "
11421140 << StrPrint (" %La" , d) << " " << StrPrint (" %.1080Lf" , d);
11431141 }
0 commit comments