diff --git a/libcxx/docs/CodingGuidelines.rst b/libcxx/docs/CodingGuidelines.rst index ff312d16cf7bb..9253456b7358b 100644 --- a/libcxx/docs/CodingGuidelines.rst +++ b/libcxx/docs/CodingGuidelines.rst @@ -195,3 +195,17 @@ prevent compilers from generating said debug information. Aliases inside type tr should be annotated for the same reason. This is enforced by the clang-tidy check ``libcpp-nodebug-on-aliases``. + +Pointer field protection +======================== + +To improve the effectiveness of Clang's `pointer field protection +`_ feature, commonly +used vocabulary types, or internal base classes or fields thereof, +with pointer fields are marked with the ``_LIBCPP_PFP`` attribute, to +give Clang permission to use PFP to protect their pointer fields. Newly +added vocabulary types and their internal base classes or fields should +be marked with this attribute if they contain pointer fields. + +For the time being, PFP is an experimental feature, so our criteria for +marking types with ``_LIBCPP_PFP`` may change. diff --git a/libcxx/include/__config b/libcxx/include/__config index 7e996bbf92ba0..4dd513e092768 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1269,6 +1269,12 @@ typedef __char32_t char32_t; # define _LIBCPP_NO_PFP # endif +# if defined(__POINTER_FIELD_PROTECTION__) +# define _LIBCPP_PFP [[_Clang::__pointer_field_protection__]] +# else +# define _LIBCPP_PFP +# endif + #endif // __cplusplus #endif // _LIBCPP___CONFIG diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h index c768fd90d01b4..29b4d3329b0e3 100644 --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -420,7 +420,7 @@ template class __policy_func; template -class __policy_func<_Rp(_ArgTypes...)> { +class _LIBCPP_PFP __policy_func<_Rp(_ArgTypes...)> { // Inline storage for small objects. __policy_storage __buf_; diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h index 0388d752ccc8b..ab352a7d278d8 100644 --- a/libcxx/include/__memory/compressed_pair.h +++ b/libcxx/include/__memory/compressed_pair.h @@ -106,7 +106,7 @@ class __compressed_pair_padding<_ToPad, true> {}; _LIBCPP_NO_UNIQUE_ADDRESS ::std::__compressed_pair_padding _LIBCPP_CONCAT3(__padding3_, __LINE__, _) # else # define _LIBCPP_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2) \ - struct { \ + struct _LIBCPP_PFP { \ _LIBCPP_NO_UNIQUE_ADDRESS T1 Initializer1; \ _LIBCPP_NO_UNIQUE_ADDRESS ::std::__compressed_pair_padding _LIBCPP_CONCAT3(__padding1_, __LINE__, _); \ _LIBCPP_NO_UNIQUE_ADDRESS T2 Initializer2; \ @@ -114,7 +114,7 @@ class __compressed_pair_padding<_ToPad, true> {}; } # define _LIBCPP_COMPRESSED_TRIPLE(T1, Initializer1, T2, Initializer2, T3, Initializer3) \ - struct { \ + struct _LIBCPP_PFP { \ _LIBCPP_NO_UNIQUE_ADDRESS T1 Initializer1; \ _LIBCPP_NO_UNIQUE_ADDRESS ::std::__compressed_pair_padding _LIBCPP_CONCAT3(__padding1_, __LINE__, _); \ _LIBCPP_NO_UNIQUE_ADDRESS T2 Initializer2; \ diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h index 0cbd995105671..2933306874a9c 100644 --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -304,7 +304,7 @@ using __shared_ptr_nullptr_deleter_ctor_reqs _LIBCPP_NODEBUG = #endif template -class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr { +class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_PFP shared_ptr { struct __nullptr_sfinae_tag {}; public: @@ -1204,7 +1204,7 @@ inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXC #endif // _LIBCPP_HAS_RTTI template -class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr { +class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_PFP weak_ptr { public: #if _LIBCPP_STD_VER >= 17 typedef remove_extent_t<_Tp> element_type; diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h index eff24546cdc01..23dde0bb20d91 100644 --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -127,7 +127,7 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> { #endif template > -class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr { +class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_PFP unique_ptr { public: typedef _Tp element_type; typedef _Dp deleter_type; @@ -396,7 +396,7 @@ struct __unique_ptr_array_bounds_stored { }; template -class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> { +class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_PFP unique_ptr<_Tp[], _Dp> { public: typedef _Tp element_type; typedef _Dp deleter_type; diff --git a/libcxx/include/__tree b/libcxx/include/__tree index ef960d481cb7b..b185b2d6b8d8e 100644 --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -790,7 +790,7 @@ _LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Compare const&, _Tp const&, _Tp cons int __diagnose_non_const_comparator(); template -class __tree { +class _LIBCPP_PFP __tree { public: using value_type = __get_node_value_type_t<_Tp>; using value_compare = _Compare; diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 316d3a9d10eff..38627a09f693f 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -84,7 +84,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template */> -class vector { +class _LIBCPP_PFP vector { template using __split_buffer _LIBCPP_NODEBUG = std::__split_buffer<_Up, _Alloc, __split_buffer_pointer_layout>; diff --git a/libcxx/include/string b/libcxx/include/string index 363f27a51648c..fbed735829f7d 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -825,7 +825,7 @@ private: # ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT - struct __long { + struct _LIBCPP_PFP __long { __long() = default; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __long(__alloc_result __alloc, size_type __size) @@ -879,7 +879,7 @@ private: // 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 { + struct _LIBCPP_PFP __long { __long() = default; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __long(__alloc_result __alloc, size_type __size)