[libc-commits] [libc] [libc] Add inf/nan tests for strfrom*() functions (PR #86663)

Vinayak Dev via libc-commits libc-commits at lists.llvm.org
Wed Mar 27 11:46:15 PDT 2024


https://github.com/vinayakdsci updated https://github.com/llvm/llvm-project/pull/86663

>From 9d79236c340ce7c075ec7cd3bd497d0624363c13 Mon Sep 17 00:00:00 2001
From: Vinayak Dev <vinayakdev.sci at gmail.com>
Date: Tue, 26 Mar 2024 18:54:48 +0530
Subject: [PATCH] [libc] Add inf/nan tests for strfrom*() functions

---
 libc/test/src/stdlib/CMakeLists.txt |  1 +
 libc/test/src/stdlib/StrfromTest.h  | 79 ++++++++++++++++++++++++++---
 2 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 3ccc1cde91934c..28c5b566cc4772 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -174,6 +174,7 @@ add_header_library(
   StrfromTest.h
   DEPENDS
   libc.src.__support.CPP.type_traits
+  libc.src.__support.FPUtil.fp_bits
 )
 
 add_libc_test(
diff --git a/libc/test/src/stdlib/StrfromTest.h b/libc/test/src/stdlib/StrfromTest.h
index f695bbb335bdbe..0db507ef0716e9 100644
--- a/libc/test/src/stdlib/StrfromTest.h
+++ b/libc/test/src/stdlib/StrfromTest.h
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/Test.h"
 
 #define ASSERT_STREQ_LEN(actual_written, actual_str, expected_str)             \
@@ -71,8 +72,18 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
     written =
         func(buff, 37,
              "%A simple string with one conversion, should overwrite.", 1.0);
-    ASSERT_STREQ_LEN(written, buff, is_long_double ? "0X8P-3" : "0X1P+0");
-
+    if (is_long_double) {
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+      ASSERT_STREQ_LEN(written, buff, "0X8P-3");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+      ASSERT_STREQ_LEN(written, buff, "0X1P+0");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+      ASSERT_STREQ_LEN(written, buff, "0X1P+0");
+#endif
+    } else {
+      // not long double
+      ASSERT_STREQ_LEN(written, buff, "0X1P+0");
+    }
     written = func(buff, 74,
                    "A simple string with one conversion in %A "
                    "between, writes string as it is",
@@ -105,6 +116,13 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
     ASSERT_STREQ(buff, "1.05"); // Make sure that buff has not changed
   }
 
+  void infNanValues(FunctionT func) {
+    if (is_double_prec)
+      doublePrecInfNan(func);
+    else if (!is_single_prec)
+      longDoublePrecInfNan(func);
+  }
+
   void floatDecimalSinglePrec(FunctionT func) {
     char buff[70];
     int written;
@@ -336,8 +354,10 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
   }
 
   void floatDecimalExpLongDoublePrec(FunctionT func) {
-    char buff[100];
-    int written;
+    // Mark as maybe_unused to silence unused variable
+    // warning when long double is not 80-bit
+    [[maybe_unused]] char buff[100];
+    [[maybe_unused]] int written;
 
 #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
     written = func(buff, 90, "%.9e", 1000000000500000000.1L);
@@ -399,8 +419,10 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
   }
 
   void floatDecimalAutoLongDoublePrec(FunctionT func) {
-    char buff[100];
-    int written;
+    // Mark as maybe_unused to silence unused variable
+    // warning when long double is not 80-bit
+    [[maybe_unused]] char buff[100];
+    [[maybe_unused]] int written;
 
 #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
     written = func(buff, 99, "%g", 0xf.fffffffffffffffp+16380L);
@@ -413,6 +435,48 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
     ASSERT_STREQ_LEN(written, buff, "1e-99");
 #endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
   }
+
+  void doublePrecInfNan(FunctionT func) {
+    char buff[15];
+    int written;
+
+    double inf = LIBC_NAMESPACE::fputil::FPBits<double>::inf().get_val();
+    double nan = LIBC_NAMESPACE::fputil::FPBits<double>::quiet_nan().get_val();
+
+    written = func(buff, 10, "%f", inf);
+    ASSERT_STREQ_LEN(written, buff, "inf");
+
+    written = func(buff, 10, "%A", -inf);
+    ASSERT_STREQ_LEN(written, buff, "-INF");
+
+    written = func(buff, 10, "%f", nan);
+    ASSERT_STREQ_LEN(written, buff, "nan");
+
+    written = func(buff, 10, "%A", -nan);
+    ASSERT_STREQ_LEN(written, buff, "-NAN");
+  }
+
+  void longDoublePrecInfNan(FunctionT func) {
+    char buff[15];
+    int written;
+
+    long double ld_inf =
+        LIBC_NAMESPACE::fputil::FPBits<long double>::inf().get_val();
+    long double ld_nan =
+        LIBC_NAMESPACE::fputil::FPBits<long double>::quiet_nan().get_val();
+
+    written = func(buff, 10, "%f", ld_inf);
+    ASSERT_STREQ_LEN(written, buff, "inf");
+
+    written = func(buff, 10, "%A", -ld_inf);
+    ASSERT_STREQ_LEN(written, buff, "-INF");
+
+    written = func(buff, 10, "%f", ld_nan);
+    ASSERT_STREQ_LEN(written, buff, "nan");
+
+    written = func(buff, 10, "%A", -ld_nan);
+    ASSERT_STREQ_LEN(written, buff, "-NAN");
+  }
 };
 
 #define STRFROM_TEST(InputType, name, func)                                    \
@@ -432,4 +496,5 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
   }                                                                            \
   TEST_F(LlvmLibc##name##Test, InsufficientBufferSize) {                       \
     insufficentBufsize(func);                                                  \
-  }
+  }                                                                            \
+  TEST_F(LlvmLibc##name##Test, InfAndNanValues) { infNanValues(func); }



More information about the libc-commits mailing list