[libcxx-commits] [libcxx] 60f7bdf - [libc++][AIX] Make basic_string layout compatible with earlier version

Xing Xue via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 24 14:26:34 PDT 2022


Author: Xing Xue
Date: 2022-06-24T17:25:15-04:00
New Revision: 60f7bdfd0317cb38eda54637cdab9baed8ae2f57

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

LOG: [libc++][AIX] Make basic_string layout compatible with earlier version

Summary:
Patch D123580 changed to use bit fields for strings in long and short mode. As a result, this changes the layout of these strings on AIX because bit fields on AIX are 4 bytes, which breaks the ABI compatibility with earlier strings before the change on AIX. This patch uses the attribute 'packed' and anonymous structure to make string layout compatible. This patch will also make test cases alignof.compile.pass.cpp and sizeof.compile.pass.cpp introduced in D127672 pass on AIX.

Reviewed by: philnik, Mordante, hubert.reinterpretcast, libc++

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

Added: 
    

Modified: 
    libcxx/include/__config
    libcxx/include/string

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__config b/libcxx/include/__config
index 11f934c0edf33..90ae511b4269b 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1176,6 +1176,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_PACKED_BYTE_FOR_AIX_END /* empty */
 #  endif
 
+#  if __has_attribute(__packed__)
+#    define _LIBCPP_PACKED __attribute__((__packed__))
+#  else
+#    define _LIBCPP_PACKED
+#  endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP___CONFIG

diff  --git a/libcxx/include/string b/libcxx/include/string
index ab8d2ac446d1c..0ce8c4fecebdd 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -721,10 +721,16 @@ private:
     static const size_type __endian_factor = 2;
 #endif
 
+    // Attribute 'packed' is used to keep the layout compatible with the
+    // previous definition that did not use bit fields. This is because on
+    // some platforms bit fields have a default size rather than the actual
+    // size used, e.g., it is 4 bytes on AIX. See D128285 for details.
     struct __long
     {
-        size_type __is_long_ : 1;
-        size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
+        struct _LIBCPP_PACKED {
+            size_type __is_long_ : 1;
+            size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
+        };
         size_type __size_;
         pointer   __data_;
     };
@@ -734,8 +740,10 @@ private:
 
     struct __short
     {
-        unsigned char __is_long_ : 1;
-        unsigned char __size_ : 7;
+        struct _LIBCPP_PACKED {
+            unsigned char __is_long_ : 1;
+            unsigned char __size_ : 7;
+        };
         char __padding_[sizeof(value_type) - 1];
         value_type __data_[__min_cap];
     };


        


More information about the libcxx-commits mailing list