[libc-commits] [libc] [libc] Fix two issues in sprintf_test after #213860 (PR #214435)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Thu Aug 6 02:02:48 PDT 2026


https://github.com/labath created https://github.com/llvm/llvm-project/pull/214435

PR #213860 enabled the test on GPU targets (which only runs hermetic tests), exposing two issues.

The first one is passing "pointer" values as `int`s. On AMDGPU, this produced garbage in the high bits of the printed value, presumably the result of reading a short `int` as a (longer) `void *`. On other this probably worked because the value is passed in a register, which (implicitly) zeroes out high bits. I fix this by casting the argument to a `uintptr_t`.

The second error is a crash in the wide char test. I restore status quo by disabling that part of the test, but I've filed #214433 to figure out a long term solution.

>From 50d45d9c8b35b8ba45043d9c11557339475cf623 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 6 Aug 2026 08:49:51 +0000
Subject: [PATCH] [libc] Fix two issues in sprintf_test after #213860

PR #213860 enabled the test on GPU targets (which only runs hermetic
tests), exposing two issues.

The first one is passing "pointer" values as `int`s. On AMDGPU, this
produced garbage in the high bits of the printed value, presumably the
result of reading a short `int` as a (longer) `void *`. On other this
probably worked because the value is passed in a register, which
(implicitly) zeroes out high bits. I fix this by casting the argument to
a `uintptr_t`.

The second error is a crash in the wide char test. I restore status quo
by disabling that part of the test, but I've filed #214433 to figure out
a long term solution.
---
 libc/test/src/stdio/sprintf_test.cpp | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/libc/test/src/stdio/sprintf_test.cpp b/libc/test/src/stdio/sprintf_test.cpp
index a366920339110..2cbf0b94a1711 100644
--- a/libc/test/src/stdio/sprintf_test.cpp
+++ b/libc/test/src/stdio/sprintf_test.cpp
@@ -546,11 +546,13 @@ TEST(LlvmLibcSPrintfTest, PointerConv) {
   written = LIBC_NAMESPACE::sprintf(buff, "%p", nullptr);
   ASSERT_STREQ_LEN(written, buff, "(nullptr)");
 
-  written = LIBC_NAMESPACE::sprintf(buff, "%p", 0x1a2b3c4d);
+  written =
+      LIBC_NAMESPACE::sprintf(buff, "%p", static_cast<uintptr_t>(0x1a2b3c4d));
   ASSERT_STREQ_LEN(written, buff, "0x1a2b3c4d");
 
   if constexpr (sizeof(void *) > 4) {
-    written = LIBC_NAMESPACE::sprintf(buff, "%p", 0x1a2b3c4d5e6f7081);
+    written = LIBC_NAMESPACE::sprintf(
+        buff, "%p", static_cast<uintptr_t>(0x1a2b3c4d5e6f7081));
     ASSERT_STREQ_LEN(written, buff, "0x1a2b3c4d5e6f7081");
   }
 
@@ -562,7 +564,8 @@ TEST(LlvmLibcSPrintfTest, PointerConv) {
   written = LIBC_NAMESPACE::sprintf(buff, "%20p", nullptr);
   ASSERT_STREQ_LEN(written, buff, "           (nullptr)");
 
-  written = LIBC_NAMESPACE::sprintf(buff, "%20p", 0x1a2b3c4d);
+  written =
+      LIBC_NAMESPACE::sprintf(buff, "%20p", static_cast<uintptr_t>(0x1a2b3c4d));
   ASSERT_STREQ_LEN(written, buff, "          0x1a2b3c4d");
 
   // Flag tests:
@@ -570,12 +573,14 @@ TEST(LlvmLibcSPrintfTest, PointerConv) {
   written = LIBC_NAMESPACE::sprintf(buff, "%-20p", nullptr);
   ASSERT_STREQ_LEN(written, buff, "(nullptr)           ");
 
-  written = LIBC_NAMESPACE::sprintf(buff, "%-20p", 0x1a2b3c4d);
+  written = LIBC_NAMESPACE::sprintf(buff, "%-20p",
+                                    static_cast<uintptr_t>(0x1a2b3c4d));
   ASSERT_STREQ_LEN(written, buff, "0x1a2b3c4d          ");
 
   // Using the 0 flag is technically undefined, but here we're following the
   // convention of matching the behavior of %#x.
-  written = LIBC_NAMESPACE::sprintf(buff, "%020p", 0x1a2b3c4d);
+  written = LIBC_NAMESPACE::sprintf(buff, "%020p",
+                                    static_cast<uintptr_t>(0x1a2b3c4d));
   ASSERT_STREQ_LEN(written, buff, "0x00000000001a2b3c4d");
 
   // Precision tests:
@@ -587,7 +592,8 @@ TEST(LlvmLibcSPrintfTest, PointerConv) {
 
   // Precision specifies the number of digits to be written for %x conversions,
   // and the "0x" doesn't count as part of the digits.
-  written = LIBC_NAMESPACE::sprintf(buff, "%.20p", 0x1a2b3c4d);
+  written = LIBC_NAMESPACE::sprintf(buff, "%.20p",
+                                    static_cast<uintptr_t>(0x1a2b3c4d));
   ASSERT_STREQ_LEN(written, buff, "0x0000000000001a2b3c4d");
 }
 
@@ -3801,7 +3807,8 @@ TEST(LlvmLibcSPrintfTest, IndexModeParsing) {
 }
 #endif // LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
 
-#ifndef LIBC_COPT_PRINTF_DISABLE_WIDE
+#if !defined(LIBC_COPT_PRINTF_DISABLE_WIDE) &&                                 \
+    !defined(LIBC_TARGET_ARCH_IS_GPU) // llvm.org/pr214433
 TEST(LlvmLibcSprintfTest, WideCharConversion) {
   char buff[16];
   int written;
@@ -3993,4 +4000,4 @@ TEST(LlvmLibcSprintfTest, WideCharStringConversion) {
   EXPECT_EQ(written, 6);
   ASSERT_STREQ_LEN(written, buff, "   (nu");
 }
-#endif // LIBC_COPT_PRINTF_DISABLE_WIDE
+#endif // !LIBC_COPT_PRINTF_DISABLE_WIDE && !LIBC_TARGET_ARCH_IS_GPU



More information about the libc-commits mailing list