[libc-commits] [libc] 81dfeb7 - [libc][locale] Fix nullptr argument handling in setlocale. (#229569)
via libc-commits
libc-commits at lists.llvm.org
Tue Oct 6 14:53:25 PDT 2026
Author: Alexey Samsonov
Date: 2026-10-06T21:53:16Z
New Revision: 81dfeb7806617258f1a3b0fd859af3a7db49f6f0
URL: https://github.com/llvm/llvm-project/commit/81dfeb7806617258f1a3b0fd859af3a7db49f6f0
DIFF: https://github.com/llvm/llvm-project/commit/81dfeb7806617258f1a3b0fd859af3a7db49f6f0.diff
LOG: [libc][locale] Fix nullptr argument handling in setlocale. (#229569)
`setlocale` function should accept `nullptr` as a possible value for the
second argument - in this case the
locale is not modified but queried. Make sure to return `C` locale in
this case (the only one supported by LLVM-libc).
Expand the unit test to verify `setlocale` behavior.
Added:
Modified:
libc/src/locale/newlocale.h
libc/src/locale/setlocale.cpp
libc/test/src/locale/CMakeLists.txt
libc/test/src/locale/locale_test.cpp
Removed:
################################################################################
diff --git a/libc/src/locale/newlocale.h b/libc/src/locale/newlocale.h
index 07972fa384433c..211bbb19b9f8c7 100644
--- a/libc/src/locale/newlocale.h
+++ b/libc/src/locale/newlocale.h
@@ -1,13 +1,18 @@
-//===-- Implementation header for setlocale ---------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for newlocale.
+///
+//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_LOCALE_SETLOCALE_H
-#define LLVM_LIBC_SRC_LOCALE_SETLOCALE_H
+#ifndef LLVM_LIBC_SRC_LOCALE_NEWLOCALE_H
+#define LLVM_LIBC_SRC_LOCALE_NEWLOCALE_H
#include "hdr/types/locale_t.h"
#include "src/__support/macros/config.h"
@@ -18,4 +23,4 @@ locale_t newlocale(int category_mask, const char *locale_name, locale_t base);
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_LOCALE_SETLOCALE_H
+#endif // LLVM_LIBC_SRC_LOCALE_NEWLOCALE_H
diff --git a/libc/src/locale/setlocale.cpp b/libc/src/locale/setlocale.cpp
index 2dec497ce051a4..bdc311eead2a7e 100644
--- a/libc/src/locale/setlocale.cpp
+++ b/libc/src/locale/setlocale.cpp
@@ -1,10 +1,15 @@
-//===-- Implementation of setlocale ---------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of setlocale.
+///
+//===----------------------------------------------------------------------===//
#include "src/locale/setlocale.h"
#include "hdr/locale_macros.h"
@@ -15,10 +20,15 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(char *, setlocale, (int category, const char *locale_name)) {
- cpp::string_view name(locale_name);
- if (category > LC_ALL || (!name.empty() && name != "C"))
+ if (category > LC_ALL)
return nullptr;
+ if (locale_name != nullptr) {
+ cpp::string_view name(locale_name);
+ if (!name.empty() && name != "C")
+ return nullptr;
+ }
+
static char locale_str[] = "C";
return locale_str;
}
diff --git a/libc/test/src/locale/CMakeLists.txt b/libc/test/src/locale/CMakeLists.txt
index 5032ce9c324e23..2a50e2ed87d1b9 100644
--- a/libc/test/src/locale/CMakeLists.txt
+++ b/libc/test/src/locale/CMakeLists.txt
@@ -9,6 +9,7 @@ add_libc_test(
DEPENDS
libc.hdr.locale_macros
libc.src.locale.newlocale
+ libc.src.locale.setlocale
libc.src.locale.uselocale
libc.src.locale.freelocale
)
diff --git a/libc/test/src/locale/locale_test.cpp b/libc/test/src/locale/locale_test.cpp
index d19e2605fca375..a55ad85006260c 100644
--- a/libc/test/src/locale/locale_test.cpp
+++ b/libc/test/src/locale/locale_test.cpp
@@ -1,14 +1,20 @@
-//===-- Unittests for locale ----------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unittests for locale.
+///
+//===----------------------------------------------------------------------===//
#include "hdr/locale_macros.h"
#include "src/locale/freelocale.h"
#include "src/locale/newlocale.h"
+#include "src/locale/setlocale.h"
#include "src/locale/uselocale.h"
#include "test/UnitTest/Test.h"
@@ -45,3 +51,20 @@ TEST(LlvmLibcLocale, NewLocaleValidation) {
loc = LIBC_NAMESPACE::newlocale(LC_ALL_MASK, "does-not-exist", nullptr);
EXPECT_EQ(loc, static_cast<locale_t>(nullptr));
}
+
+TEST(LlvmLibcLocale, SetLocale) {
+ // Setting a "C" or default locale.
+ EXPECT_STREQ(LIBC_NAMESPACE::setlocale(LC_ALL, "C"), "C");
+ EXPECT_STREQ(LIBC_NAMESPACE::setlocale(LC_CTYPE, ""), "C");
+ // Querying the current locale.
+ EXPECT_STREQ(LIBC_NAMESPACE::setlocale(LC_ALL, nullptr), "C");
+ EXPECT_STREQ(LIBC_NAMESPACE::setlocale(LC_NUMERIC, nullptr), "C");
+
+ // Unsupporter categories or non-C locales.
+ EXPECT_EQ(LIBC_NAMESPACE::setlocale(LC_ALL + 1, "C"),
+ static_cast<char *>(nullptr));
+ EXPECT_EQ(LIBC_NAMESPACE::setlocale(LC_ALL + 1, nullptr),
+ static_cast<char *>(nullptr));
+ EXPECT_EQ(LIBC_NAMESPACE::setlocale(LC_ALL, "does-not-exist"),
+ static_cast<char *>(nullptr));
+}
More information about the libc-commits
mailing list