[libcxx-commits] [libcxx] [libc++][string] Remove potential non-trailing 0-length array (PR #105865)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 29 01:41:52 PDT 2024
https://github.com/serge-sans-paille updated https://github.com/llvm/llvm-project/pull/105865
>From 6e1b86c38ddd218b268332e8c2ca6b452404654b Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Fri, 23 Aug 2024 19:52:56 +0200
Subject: [PATCH 1/3] [libc++][string] Remove potential non-trailing 0-length
array
It is a violation of the standard to use 0 length arrays, especially
when not at the end of a structure (not a FAM GNU extension). Compiler
generally accept it, but it's probably better to have a conforming
implementation.
---
libcxx/include/string | 52 ++++++++++++++++++++++++++++++-------------
1 file changed, 36 insertions(+), 16 deletions(-)
diff --git a/libcxx/include/string b/libcxx/include/string
index 6e93a6230cc2c0..10301c4a7afed0 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -748,6 +748,41 @@ struct __can_be_converted_to_string_view
struct __uninitialized_size_tag {};
struct __init_with_sentinel_tag {};
+#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+template <class _CharT, size_t __min_cap, size_t _Padding = sizeof(_CharT) - 1>
+struct __short_impl {
+ _CharT __data_[__min_cap];
+ unsigned char __padding_[_Padding];
+ unsigned char __size_ : 7;
+ unsigned char __is_long_ : 1;
+};
+
+template <class _CharT, size_t __min_cap>
+struct __short_impl<_CharT, __min_cap, 0> {
+ value_type __data_[__min_cap];
+ unsigned char __size_ : 7;
+ unsigned char __is_long_ : 1;
+};
+#else
+template <class _CharT, size_t __min_cap, size_t _Padding = sizeof(_CharT) - 1>
+struct __short_impl {
+ struct _LIBCPP_PACKED {
+ unsigned char __is_long_ : 1;
+ unsigned char __size_ : 7;
+ };
+ char __padding_[_Padding];
+ _CharT __data_[__min_cap];
+};
+template <class _CharT, size_t __min_cap>
+struct __short_impl<_CharT, __min_cap, 0> {
+ struct _LIBCPP_PACKED {
+ unsigned char __is_long_ : 1;
+ unsigned char __size_ : 7;
+ };
+ _CharT __data_[__min_cap];
+};
+#endif
+
template <class _CharT, class _Traits, class _Allocator>
class basic_string {
private:
@@ -850,13 +885,6 @@ private:
enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 };
- struct __short {
- value_type __data_[__min_cap];
- unsigned char __padding_[sizeof(value_type) - 1];
- unsigned char __size_ : 7;
- unsigned char __is_long_ : 1;
- };
-
// The __endian_factor is required because the field we use to store the size
// has one fewer bit than it would if it were not a bitfield.
//
@@ -899,17 +927,9 @@ private:
enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 };
- struct __short {
- struct _LIBCPP_PACKED {
- unsigned char __is_long_ : 1;
- unsigned char __size_ : 7;
- };
- char __padding_[sizeof(value_type) - 1];
- value_type __data_[__min_cap];
- };
-
#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+ using __short = __short_impl<value_type, __min_cap>;
static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
union __rep {
>From f3302f08c3e7e3e3aa5a6be5b932bf5f080ddc95 Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Sat, 24 Aug 2024 14:11:35 +0200
Subject: [PATCH 2/3] fixup! [libc++][string] Remove potential non-trailing
0-length array
---
libcxx/include/string | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/include/string b/libcxx/include/string
index 10301c4a7afed0..8cbda52fa4ebbf 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -759,7 +759,7 @@ struct __short_impl {
template <class _CharT, size_t __min_cap>
struct __short_impl<_CharT, __min_cap, 0> {
- value_type __data_[__min_cap];
+ _CharT __data_[__min_cap];
unsigned char __size_ : 7;
unsigned char __is_long_ : 1;
};
>From bd910ae6999437ab1c89923640ad374c3252c90b Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Thu, 29 Aug 2024 10:30:34 +0200
Subject: [PATCH 3/3] fixup! [libc++][string] Remove potential non-trailing
0-length array
---
libcxx/include/string | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/libcxx/include/string b/libcxx/include/string
index 8cbda52fa4ebbf..805831a16720b1 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -750,7 +750,7 @@ struct __init_with_sentinel_tag {};
#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
template <class _CharT, size_t __min_cap, size_t _Padding = sizeof(_CharT) - 1>
-struct __short_impl {
+struct __short_layout_alternate {
_CharT __data_[__min_cap];
unsigned char __padding_[_Padding];
unsigned char __size_ : 7;
@@ -758,14 +758,14 @@ struct __short_impl {
};
template <class _CharT, size_t __min_cap>
-struct __short_impl<_CharT, __min_cap, 0> {
+struct __short_layout_alternate<_CharT, __min_cap, 0> {
_CharT __data_[__min_cap];
unsigned char __size_ : 7;
unsigned char __is_long_ : 1;
};
#else
template <class _CharT, size_t __min_cap, size_t _Padding = sizeof(_CharT) - 1>
-struct __short_impl {
+struct __short_layout_classic {
struct _LIBCPP_PACKED {
unsigned char __is_long_ : 1;
unsigned char __size_ : 7;
@@ -774,7 +774,7 @@ struct __short_impl {
_CharT __data_[__min_cap];
};
template <class _CharT, size_t __min_cap>
-struct __short_impl<_CharT, __min_cap, 0> {
+struct __short_layout_classic<_CharT, __min_cap, 0> {
struct _LIBCPP_PACKED {
unsigned char __is_long_ : 1;
unsigned char __size_ : 7;
@@ -929,7 +929,11 @@ private:
#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
- using __short = __short_impl<value_type, __min_cap>;
+#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+ using __short = __short_layout_alternate <value_type, __min_cap>;
+#else
+ using __short = __short_layout_classic <value_type, __min_cap>;
+#endif
static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
union __rep {
More information about the libcxx-commits
mailing list