Skip to content

Commit 3c6f9e0

Browse files
committed
libcxx: Introduce __force_nonstandard_layout base class for pointer field protection.
The __force_nonstandard_layout class causes types derived from it to be non-standard layout. This is beneficial with pointer field protection because, thanks to the standard rules related to standard layout structs, it is likely infeasible to automatically apply PFP to pointer fields of standard layout types. By marking commonly used standard types as non-standard layout, we not only enable PFP on the pointers contained in these types but also types containing a field or base class of one of the standard types, thus allowing many types to automatically receive pointer field protection for their fields. Therefore, make several commonly used standard types derive from __force_nonstandard_layout when PFP is enabled. Pull Request: llvm#151652
1 parent b3d3076 commit 3c6f9e0

File tree

9 files changed

+60
-7
lines changed

9 files changed

+60
-7
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ set(files
375375
__flat_set/flat_set.h
376376
__flat_set/ra_iterator.h
377377
__flat_set/utils.h
378+
__force_nonstandard_layout
378379
__format/buffer.h
379380
__format/concepts.h
380381
__format/container_adaptor.h
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP___FORCE_NONSTANDARD_LAYOUT
11+
#define _LIBCPP___FORCE_NONSTANDARD_LAYOUT
12+
13+
#include <__config>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
_LIBCPP_BEGIN_NAMESPACE_STD
20+
21+
// Force a class to be non-standard layout by giving it two bases with the same
22+
// type. This is useful when structure protection is enabled because structure
23+
// protection cannot be applied to standard layout classes. We may use this in
24+
// cases where the standard does not specify whether a standard library class is
25+
// standard layout. See C++2a [class]p7:
26+
// A class S is a standard-layout class if it:
27+
// -- has at most one base class subobject of any given type
28+
_LIBCPP_DIAGNOSTIC_PUSH
29+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winaccessible-base")
30+
class __force_nonstandard_layout_base1 {};
31+
class __force_nonstandard_layout_base2 : __force_nonstandard_layout_base1 {};
32+
class __force_nonstandard_layout : __force_nonstandard_layout_base1, __force_nonstandard_layout_base2 {};
33+
_LIBCPP_DIAGNOSTIC_POP
34+
35+
#if __has_feature(pointer_field_protection)
36+
# define _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT : __force_nonstandard_layout
37+
#else
38+
# define _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT
39+
#endif
40+
41+
_LIBCPP_END_NAMESPACE_STD
42+
43+
#endif // _LIBCPP___FORCE_NONSTANDARD_LAYOUT

libcxx/include/__functional/function.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <__config>
1515
#include <__cstddef/nullptr_t.h>
1616
#include <__exception/exception.h>
17+
#include <__force_nonstandard_layout>
1718
#include <__functional/binary_function.h>
1819
#include <__functional/invoke.h>
1920
#include <__functional/unary_function.h>
@@ -427,7 +428,7 @@ template <class _Fp>
427428
class __policy_func;
428429

429430
template <class _Rp, class... _ArgTypes>
430-
class __policy_func<_Rp(_ArgTypes...)> {
431+
class __policy_func<_Rp(_ArgTypes...)> _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
431432
// Inline storage for small objects.
432433
__policy_storage __buf_;
433434

libcxx/include/__memory/shared_ptr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <__cstddef/nullptr_t.h>
1717
#include <__cstddef/ptrdiff_t.h>
1818
#include <__exception/exception.h>
19+
#include <__force_nonstandard_layout>
1920
#include <__functional/binary_function.h>
2021
#include <__functional/operations.h>
2122
#include <__functional/reference_wrapper.h>
@@ -304,7 +305,7 @@ using __shared_ptr_nullptr_deleter_ctor_reqs _LIBCPP_NODEBUG =
304305
#endif
305306

306307
template <class _Tp>
307-
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
308+
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
308309
struct __nullptr_sfinae_tag {};
309310

310311
public:
@@ -1204,7 +1205,7 @@ inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXC
12041205
#endif // _LIBCPP_HAS_RTTI
12051206

12061207
template <class _Tp>
1207-
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr {
1208+
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
12081209
public:
12091210
#if _LIBCPP_STD_VER >= 17
12101211
typedef remove_extent_t<_Tp> element_type;

libcxx/include/__memory/unique_ptr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <__config>
1818
#include <__cstddef/nullptr_t.h>
1919
#include <__cstddef/size_t.h>
20+
#include <__force_nonstandard_layout>
2021
#include <__functional/hash.h>
2122
#include <__functional/operations.h>
2223
#include <__memory/allocator_traits.h> // __pointer
@@ -127,7 +128,7 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> {
127128
#endif
128129

129130
template <class _Tp, class _Dp = default_delete<_Tp> >
130-
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
131+
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
131132
public:
132133
typedef _Tp element_type;
133134
typedef _Dp deleter_type;
@@ -396,7 +397,7 @@ struct __unique_ptr_array_bounds_stored {
396397
};
397398

398399
template <class _Tp, class _Dp>
399-
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> {
400+
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
400401
public:
401402
typedef _Tp element_type;
402403
typedef _Dp deleter_type;

libcxx/include/__tree

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <__algorithm/min.h>
1414
#include <__assert>
1515
#include <__config>
16+
#include <__force_nonstandard_layout>
1617
#include <__fwd/map.h>
1718
#include <__fwd/pair.h>
1819
#include <__fwd/set.h>
@@ -782,7 +783,7 @@ _LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Compare const&, _Tp const&, _Tp cons
782783
int __diagnose_non_const_comparator();
783784

784785
template <class _Tp, class _Compare, class _Allocator>
785-
class __tree {
786+
class __tree _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
786787
public:
787788
using value_type = __get_node_value_type_t<_Tp>;
788789
typedef _Compare value_compare;

libcxx/include/__vector/vector.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <__assert>
2222
#include <__config>
2323
#include <__debug_utils/sanitizers.h>
24+
#include <__force_nonstandard_layout>
2425
#include <__format/enable_insertable.h>
2526
#include <__fwd/vector.h>
2627
#include <__iterator/advance.h>
@@ -85,7 +86,7 @@ _LIBCPP_PUSH_MACROS
8586
_LIBCPP_BEGIN_NAMESPACE_STD
8687

8788
template <class _Tp, class _Allocator /* = allocator<_Tp> */>
88-
class vector {
89+
class vector _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
8990
public:
9091
//
9192
// Types

libcxx/include/module.modulemap.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,6 +2377,9 @@ module std [system] {
23772377
module undef_macros {
23782378
textual header "__undef_macros"
23792379
}
2380+
module force_nonstandard_layout {
2381+
header "__force_nonstandard_layout"
2382+
}
23802383

23812384
// This module needs to appear after __tree to work around issues with modules in Objective-C++ mode.
23822385
module coroutine {

llvm/utils/gn/secondary/libcxx/include/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,7 @@ if (current_toolchain == default_toolchain) {
10321032
"__flat_set/flat_set.h",
10331033
"__flat_set/ra_iterator.h",
10341034
"__flat_set/utils.h",
1035+
"__force_nonstandard_layout",
10351036
"__format/buffer.h",
10361037
"__format/concepts.h",
10371038
"__format/container_adaptor.h",

0 commit comments

Comments
 (0)