Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ set(files
__flat_set/flat_set.h
__flat_set/ra_iterator.h
__flat_set/utils.h
__force_nonstandard_layout
__format/buffer.h
__format/concepts.h
__format/container_adaptor.h
Expand Down
43 changes: 43 additions & 0 deletions libcxx/include/__force_nonstandard_layout
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___FORCE_NONSTANDARD_LAYOUT
#define _LIBCPP___FORCE_NONSTANDARD_LAYOUT

#include <__config>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

// Force a class to be non-standard layout by giving it two bases with the same
// type. This is useful when structure protection is enabled because structure
// protection cannot be applied to standard layout classes. We may use this in
// cases where the standard does not specify whether a standard library class is
// standard layout. See C++2a [class]p7:
// A class S is a standard-layout class if it:
// -- has at most one base class subobject of any given type
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winaccessible-base")
class __force_nonstandard_layout_base1 {};
class __force_nonstandard_layout_base2 : __force_nonstandard_layout_base1 {};
class __force_nonstandard_layout : __force_nonstandard_layout_base1, __force_nonstandard_layout_base2 {};
_LIBCPP_DIAGNOSTIC_POP

#if __has_feature(pointer_field_protection)
# define _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT : __force_nonstandard_layout
#else
# define _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT
#endif

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___FORCE_NONSTANDARD_LAYOUT
3 changes: 2 additions & 1 deletion libcxx/include/__functional/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <__config>
#include <__cstddef/nullptr_t.h>
#include <__exception/exception.h>
#include <__force_nonstandard_layout>
#include <__functional/binary_function.h>
#include <__functional/invoke.h>
#include <__functional/unary_function.h>
Expand Down Expand Up @@ -427,7 +428,7 @@ template <class _Fp>
class __policy_func;

template <class _Rp, class... _ArgTypes>
class __policy_func<_Rp(_ArgTypes...)> {
class __policy_func<_Rp(_ArgTypes...)> _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
// Inline storage for small objects.
__policy_storage __buf_;

Expand Down
5 changes: 3 additions & 2 deletions libcxx/include/__memory/shared_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <__cstddef/nullptr_t.h>
#include <__cstddef/ptrdiff_t.h>
#include <__exception/exception.h>
#include <__force_nonstandard_layout>
#include <__functional/binary_function.h>
#include <__functional/operations.h>
#include <__functional/reference_wrapper.h>
Expand Down Expand Up @@ -304,7 +305,7 @@ using __shared_ptr_nullptr_deleter_ctor_reqs _LIBCPP_NODEBUG =
#endif

template <class _Tp>
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to add a test file (in the libcxx/test/libcxx subdirectory), verifying static_assert(!std::is_standard_layout<T>::value, ""); for affected types when __has_feature(pointer_field_protection).

struct __nullptr_sfinae_tag {};

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

template <class _Tp>
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr {
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
public:
#if _LIBCPP_STD_VER >= 17
typedef remove_extent_t<_Tp> element_type;
Expand Down
5 changes: 3 additions & 2 deletions libcxx/include/__memory/unique_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <__config>
#include <__cstddef/nullptr_t.h>
#include <__cstddef/size_t.h>
#include <__force_nonstandard_layout>
#include <__functional/hash.h>
#include <__functional/operations.h>
#include <__memory/allocator_traits.h> // __pointer
Expand Down Expand Up @@ -127,7 +128,7 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> {
#endif

template <class _Tp, class _Dp = default_delete<_Tp> >
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
public:
typedef _Tp element_type;
typedef _Dp deleter_type;
Expand Down Expand Up @@ -396,7 +397,7 @@ struct __unique_ptr_array_bounds_stored {
};

template <class _Tp, class _Dp>
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> {
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
public:
typedef _Tp element_type;
typedef _Dp deleter_type;
Expand Down
3 changes: 2 additions & 1 deletion libcxx/include/__tree
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <__algorithm/min.h>
#include <__assert>
#include <__config>
#include <__force_nonstandard_layout>
#include <__fwd/map.h>
#include <__fwd/pair.h>
#include <__fwd/set.h>
Expand Down Expand Up @@ -782,7 +783,7 @@ _LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Compare const&, _Tp const&, _Tp cons
int __diagnose_non_const_comparator();

template <class _Tp, class _Compare, class _Allocator>
class __tree {
class __tree _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
public:
using value_type = __get_node_value_type_t<_Tp>;
typedef _Compare value_compare;
Expand Down
3 changes: 2 additions & 1 deletion libcxx/include/__vector/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <__assert>
#include <__config>
#include <__debug_utils/sanitizers.h>
#include <__force_nonstandard_layout>
#include <__format/enable_insertable.h>
#include <__fwd/vector.h>
#include <__iterator/advance.h>
Expand Down Expand Up @@ -85,7 +86,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp, class _Allocator /* = allocator<_Tp> */>
class vector {
class vector _LIBCPP_MAYBE_FORCE_NONSTANDARD_LAYOUT {
public:
//
// Types
Expand Down
3 changes: 3 additions & 0 deletions libcxx/include/module.modulemap.in
Original file line number Diff line number Diff line change
Expand Up @@ -2377,6 +2377,9 @@ module std [system] {
module undef_macros {
textual header "__undef_macros"
}
module force_nonstandard_layout {
header "__force_nonstandard_layout"
}

// This module needs to appear after __tree to work around issues with modules in Objective-C++ mode.
module coroutine {
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/gn/secondary/libcxx/include/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,7 @@ if (current_toolchain == default_toolchain) {
"__flat_set/flat_set.h",
"__flat_set/ra_iterator.h",
"__flat_set/utils.h",
"__force_nonstandard_layout",
"__format/buffer.h",
"__format/concepts.h",
"__format/container_adaptor.h",
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.