[libcxx-commits] [libcxx] bf1bcb6 - [libc++] Use intptr_t instead of ptrdiff_t for messages_base::catalog

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 8 06:16:08 PDT 2023


Author: Alexander Richardson
Date: 2023-09-08T09:15:57-04:00
New Revision: bf1bcb68fc4142c792576b53866df60ead8ac501

URL: https://github.com/llvm/llvm-project/commit/bf1bcb68fc4142c792576b53866df60ead8ac501
DIFF: https://github.com/llvm/llvm-project/commit/bf1bcb68fc4142c792576b53866df60ead8ac501.diff

LOG: [libc++] Use intptr_t instead of ptrdiff_t for messages_base::catalog

On GLibc, FreeBSD and macOS systems nl_catd is a pointer type, and
round-tripping this in a variable of ptrdiff_t is not portable.
In fact such a round-trip yields a non-dereferenceable pointer on
CHERI-enabled architectures such as Arm Morello. There pointers (and
therefore intptr_t) are twice the size of ptrdiff_t, which means casting
to ptrdiff_t strips the high (metadata) bits (as well as a hidden pointer
validity bit).

Since catalog is now guaranteed to be the same size or larger than nl_catd,
we can store all return values safely and the shifting workaround from
commit 0c68ed006d4f38c3cdcab6a565aa3e208015895f should not be needed
anymore (this is also not portable to CHERI systems on since shifting a
valid pointer right will create a massively out-of-bounds pointer that
may not be representable).

This can be fixed by using intptr_t which should be the same type as
ptrdiff_t on all currently supported architectures.

See also: https://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2028

Differential Revision: https://reviews.llvm.org/D134420

Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>

Added: 
    

Modified: 
    libcxx/include/locale
    libcxx/test/std/localization/locale.categories/category.messages/locale.messages/messages_base.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/locale b/libcxx/include/locale
index 8008ec2a0776a35..7e861f880555fa7 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -3455,7 +3455,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>;
 class _LIBCPP_EXPORTED_FROM_ABI messages_base
 {
 public:
-    typedef ptr
diff _t catalog;
+    typedef intptr_t catalog;
 
     _LIBCPP_INLINE_VISIBILITY messages_base() {}
 };
@@ -3512,10 +3512,7 @@ typename messages<_CharT>::catalog
 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
 {
 #ifdef _LIBCPP_HAS_CATOPEN
-    catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
-    if (__cat != -1)
-        __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
-    return __cat;
+    return (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
 #else // !_LIBCPP_HAS_CATOPEN
     (void)__nm;
     return -1;
@@ -3532,9 +3529,8 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
     __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(std::back_inserter(__ndflt),
                                                        __dflt.c_str(),
                                                        __dflt.c_str() + __dflt.size());
-    if (__c != -1)
-        __c <<= 1;
     nl_catd __cat = (nl_catd)__c;
+    static_assert(sizeof(catalog) >= sizeof(nl_catd), "Unexpected nl_catd type");
     char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
     string_type __w;
     __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(std::back_inserter(__w),
@@ -3553,10 +3549,7 @@ void
 messages<_CharT>::do_close(catalog __c) const
 {
 #ifdef _LIBCPP_HAS_CATOPEN
-    if (__c != -1)
-        __c <<= 1;
-    nl_catd __cat = (nl_catd)__c;
-    catclose(__cat);
+    catclose((nl_catd)__c);
 #else // !_LIBCPP_HAS_CATOPEN
     (void)__c;
 #endif // _LIBCPP_HAS_CATOPEN

diff  --git a/libcxx/test/std/localization/locale.categories/category.messages/locale.messages/messages_base.pass.cpp b/libcxx/test/std/localization/locale.categories/category.messages/locale.messages/messages_base.pass.cpp
index 9fd30c3689ed9d9..15bed92c44fdc0a 100644
--- a/libcxx/test/std/localization/locale.categories/category.messages/locale.messages/messages_base.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.messages/locale.messages/messages_base.pass.cpp
@@ -14,14 +14,22 @@
 //     typedef unspecified catalog;
 // };
 
+#include <cstdint>
 #include <locale>
 #include <type_traits>
 
-#include "test_macros.h"
+#include "assert_macros.h"
 
-int main(int, char**)
-{
-    std::messages_base mb;
+#ifdef _LIBCPP_VERSION
+ASSERT_SAME_TYPE(std::messages_base::catalog, std::intptr_t);
+#endif
+
+// Check that we implement LWG2028
+static_assert(std::is_signed<std::messages_base::catalog>::value, "");
+static_assert(std::is_integral<std::messages_base::catalog>::value, "");
+
+int main(int, char**) {
+  std::messages_base mb;
 
   return 0;
 }


        


More information about the libcxx-commits mailing list