diff --git a/libc/docs/dev/printf_behavior.rst b/libc/docs/dev/printf_behavior.rst index 00d6c83f4b0d36..9548bfda57aa7d 100644 --- a/libc/docs/dev/printf_behavior.rst +++ b/libc/docs/dev/printf_behavior.rst @@ -1,3 +1,5 @@ +.. _printf_behavior: + ==================================== Printf Behavior Under All Conditions ==================================== diff --git a/libc/docs/dev/undefined_behavior.rst b/libc/docs/dev/undefined_behavior.rst index 3a06b7007febd4..50e8bdde89ddd6 100644 --- a/libc/docs/dev/undefined_behavior.rst +++ b/libc/docs/dev/undefined_behavior.rst @@ -74,3 +74,10 @@ The POSIX.1 standard does not delineate the behavior consequent to invoking hsea Path without Leading Slashs in shm_open ---------------------------------------- POSIX.1 leaves that when the name of a shared memory object does not begin with a slash, the behavior is implementation defined. In such cases, the shm_open in LLVM libc is implemented to behave as if the name began with a slash. + +Handling of NULL arguments to the 's' format specifier +------------------------------------------------------ +The C standard does not specify behavior for ``printf("%s", NULL)``. We will +print the string literal ``(null)`` unless using the +``LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS`` option described in :ref:`printf +behavior`. diff --git a/libc/src/stdio/printf_core/string_converter.h b/libc/src/stdio/printf_core/string_converter.h index 04dc5a06da2226..9e05591079faa4 100644 --- a/libc/src/stdio/printf_core/string_converter.h +++ b/libc/src/stdio/printf_core/string_converter.h @@ -25,7 +25,7 @@ LIBC_INLINE int convert_string(Writer *writer, const FormatSection &to_conv) { #ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS if (str_ptr == nullptr) { - str_ptr = "null"; + str_ptr = "(null)"; } #endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS diff --git a/libc/test/src/stdio/sprintf_test.cpp b/libc/test/src/stdio/sprintf_test.cpp index ab8bdb23b1187c..8dde95d02a96dc 100644 --- a/libc/test/src/stdio/sprintf_test.cpp +++ b/libc/test/src/stdio/sprintf_test.cpp @@ -121,8 +121,8 @@ TEST(LlvmLibcSPrintfTest, StringConv) { #ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS written = LIBC_NAMESPACE::sprintf(buff, "%s", nullptr); - EXPECT_EQ(written, 4); - ASSERT_STREQ(buff, "null"); + EXPECT_EQ(written, 6); + ASSERT_STREQ(buff, "(null)"); #endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS }