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

Vinayak Dev via libc-commits libc-commits at lists.llvm.org
Tue Mar 26 07:01:12 PDT 2024


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

Adds tests for `inf` and `nan` values to the tests for `strfrom*()` functions.

Also marks some variables as `[[maybe_unused]]` to silence unused variable warnings.

>From be79ebc5aaa5b55f2a3487902e72ef1910334606 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  | 91 +++++++++++++++++++++++++----
 2 files changed, 82 insertions(+), 10 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..0b9a48e69165c1 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)             \
@@ -68,11 +69,27 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
     written = func(buff, 37, "A simple string with no conversions.", 1.0);
     ASSERT_STREQ_LEN(written, buff, "A simple string with no conversions.");
 
-    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) {
+      // 64-bit long double values require checking as they will give
+      // a different result
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+      written =
+          func(buff, 37,
+               "%A simple string with one conversion, should overwrite.", 1.0);
+      ASSERT_STREQ_LEN(written, buff, "0X1P+0");
+#else
+      written =
+          func(buff, 37,
+               "%A simple string with one conversion, should overwrite.", 1.0);
+      ASSERT_STREQ_LEN(written, buff, "0X8P-3");
+#endif
+    } else {
+      // not long double
+      written =
+          func(buff, 37,
+               "%A simple string with one conversion, should overwrite.", 1.0);
+      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 +122,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 +360,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 +425,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 +441,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 +502,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