Skip to content

Commit 9474e09

Browse files
authored
[libc++] Granularize the <new> header (#119270)
This disentangles the code which previously had a mix of many #ifdefs, a non-versioned namespace and a versioned namespace. It also makes it clearer which parts of <new> are implemented on Windows by including <new.h>.
1 parent d1f51c6 commit 9474e09

35 files changed

+555
-301
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,16 @@ set(files
581581
__mutex/once_flag.h
582582
__mutex/tag_types.h
583583
__mutex/unique_lock.h
584+
__new/align_val_t.h
585+
__new/allocate.h
586+
__new/destroying_delete_t.h
587+
__new/exceptions.h
588+
__new/global_new_delete.h
589+
__new/interference_size.h
590+
__new/launder.h
591+
__new/new_handler.h
592+
__new/nothrow_t.h
593+
__new/placement_new_delete.h
584594
__node_handle
585595
__numeric/accumulate.h
586596
__numeric/adjacent_difference.h

libcxx/include/__hash_table

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <__memory/pointer_traits.h>
2727
#include <__memory/swap_allocator.h>
2828
#include <__memory/unique_ptr.h>
29+
#include <__new/launder.h>
2930
#include <__type_traits/can_extract_key.h>
3031
#include <__type_traits/conditional.h>
3132
#include <__type_traits/enable_if.h>
@@ -46,7 +47,6 @@
4647
#include <__utility/swap.h>
4748
#include <cstring>
4849
#include <limits>
49-
#include <new> // __launder
5050

5151
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5252
# pragma GCC system_header

libcxx/include/__memory/allocator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <__config>
1414
#include <__cstddef/ptrdiff_t.h>
15+
#include <__cstddef/size_t.h>
1516
#include <__memory/addressof.h>
1617
#include <__memory/allocate_at_least.h>
1718
#include <__memory/allocator_traits.h>

libcxx/include/__memory/builtin_new_allocator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define _LIBCPP___MEMORY_BUILTIN_NEW_ALLOCATOR_H
1111

1212
#include <__config>
13+
#include <__cstddef/size_t.h>
1314
#include <__memory/unique_ptr.h>
1415
#include <new>
1516

libcxx/include/__memory/construct_at.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
#include <__config>
1515
#include <__iterator/access.h>
1616
#include <__memory/addressof.h>
17+
#include <__new/placement_new_delete.h>
1718
#include <__type_traits/enable_if.h>
1819
#include <__type_traits/is_array.h>
1920
#include <__utility/declval.h>
2021
#include <__utility/forward.h>
2122
#include <__utility/move.h>
22-
#include <new>
2323

2424
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2525
# pragma GCC system_header

libcxx/include/__memory/shared_ptr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <__type_traits/is_bounded_array.h>
4444
#include <__type_traits/is_constructible.h>
4545
#include <__type_traits/is_convertible.h>
46+
#include <__type_traits/is_function.h>
4647
#include <__type_traits/is_reference.h>
4748
#include <__type_traits/is_same.h>
4849
#include <__type_traits/is_unbounded_array.h>

libcxx/include/__memory/uninitialized_algorithms.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <__algorithm/unwrap_iter.h>
1616
#include <__algorithm/unwrap_range.h>
1717
#include <__config>
18+
#include <__cstddef/size_t.h>
1819
#include <__iterator/iterator_traits.h>
1920
#include <__iterator/reverse_iterator.h>
2021
#include <__memory/addressof.h>

libcxx/include/__new/align_val_t.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___NEW_ALIGN_VAL_T_H
10+
#define _LIBCPP___NEW_ALIGN_VAL_T_H
11+
12+
#include <__config>
13+
#include <__cstddef/size_t.h>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
// purposefully not using versioning namespace
20+
namespace std {
21+
#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION && !defined(_LIBCPP_ABI_VCRUNTIME)
22+
# ifndef _LIBCPP_CXX03_LANG
23+
enum class align_val_t : size_t {};
24+
# else
25+
enum align_val_t { __zero = 0, __max = (size_t)-1 };
26+
# endif
27+
#endif
28+
} // namespace std
29+
30+
#endif // _LIBCPP___NEW_ALIGN_VAL_T_H

libcxx/include/__new/allocate.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___NEW_ALLOCATE_H
10+
#define _LIBCPP___NEW_ALLOCATE_H
11+
12+
#include <__config>
13+
#include <__cstddef/max_align_t.h>
14+
#include <__cstddef/size_t.h>
15+
#include <__new/align_val_t.h>
16+
#include <__new/global_new_delete.h> // for _LIBCPP_HAS_SIZED_DEALLOCATION
17+
18+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19+
# pragma GCC system_header
20+
#endif
21+
22+
_LIBCPP_BEGIN_NAMESPACE_STD
23+
24+
_LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI bool __is_overaligned_for_new(size_t __align) _NOEXCEPT {
25+
#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
26+
return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__;
27+
#else
28+
return __align > _LIBCPP_ALIGNOF(max_align_t);
29+
#endif
30+
}
31+
32+
template <class... _Args>
33+
_LIBCPP_HIDE_FROM_ABI void* __libcpp_operator_new(_Args... __args) {
34+
#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
35+
return __builtin_operator_new(__args...);
36+
#else
37+
return ::operator new(__args...);
38+
#endif
39+
}
40+
41+
template <class... _Args>
42+
_LIBCPP_HIDE_FROM_ABI void __libcpp_operator_delete(_Args... __args) _NOEXCEPT {
43+
#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
44+
__builtin_operator_delete(__args...);
45+
#else
46+
::operator delete(__args...);
47+
#endif
48+
}
49+
50+
inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_allocate(size_t __size, size_t __align) {
51+
#if _LIBCPP_HAS_ALIGNED_ALLOCATION
52+
if (__is_overaligned_for_new(__align)) {
53+
const align_val_t __align_val = static_cast<align_val_t>(__align);
54+
return __libcpp_operator_new(__size, __align_val);
55+
}
56+
#endif
57+
58+
(void)__align;
59+
return __libcpp_operator_new(__size);
60+
}
61+
62+
template <class... _Args>
63+
_LIBCPP_HIDE_FROM_ABI void __do_deallocate_handle_size(void* __ptr, size_t __size, _Args... __args) _NOEXCEPT {
64+
#if !_LIBCPP_HAS_SIZED_DEALLOCATION
65+
(void)__size;
66+
return std::__libcpp_operator_delete(__ptr, __args...);
67+
#else
68+
return std::__libcpp_operator_delete(__ptr, __size, __args...);
69+
#endif
70+
}
71+
72+
inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) _NOEXCEPT {
73+
#if !_LIBCPP_HAS_ALIGNED_ALLOCATION
74+
(void)__align;
75+
return __do_deallocate_handle_size(__ptr, __size);
76+
#else
77+
if (__is_overaligned_for_new(__align)) {
78+
const align_val_t __align_val = static_cast<align_val_t>(__align);
79+
return __do_deallocate_handle_size(__ptr, __size, __align_val);
80+
} else {
81+
return __do_deallocate_handle_size(__ptr, __size);
82+
}
83+
#endif
84+
}
85+
86+
inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate_unsized(void* __ptr, size_t __align) _NOEXCEPT {
87+
#if !_LIBCPP_HAS_ALIGNED_ALLOCATION
88+
(void)__align;
89+
return __libcpp_operator_delete(__ptr);
90+
#else
91+
if (__is_overaligned_for_new(__align)) {
92+
const align_val_t __align_val = static_cast<align_val_t>(__align);
93+
return __libcpp_operator_delete(__ptr, __align_val);
94+
} else {
95+
return __libcpp_operator_delete(__ptr);
96+
}
97+
#endif
98+
}
99+
_LIBCPP_END_NAMESPACE_STD
100+
101+
#endif // _LIBCPP___NEW_ALLOCATE_H
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___NEW_DESTROYING_DELETE_T_H
10+
#define _LIBCPP___NEW_DESTROYING_DELETE_T_H
11+
12+
#include <__config>
13+
14+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15+
# pragma GCC system_header
16+
#endif
17+
18+
#if _LIBCPP_STD_VER >= 20
19+
// purposefully not using versioning namespace
20+
namespace std {
21+
// Enable the declaration even if the compiler doesn't support the language
22+
// feature.
23+
struct destroying_delete_t {
24+
explicit destroying_delete_t() = default;
25+
};
26+
inline constexpr destroying_delete_t destroying_delete{};
27+
} // namespace std
28+
#endif
29+
30+
#endif // _LIBCPP___NEW_DESTROYING_DELETE_T_H

libcxx/include/__new/exceptions.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___NEW_EXCEPTIONS_H
10+
#define _LIBCPP___NEW_EXCEPTIONS_H
11+
12+
#include <__config>
13+
#include <__exception/exception.h>
14+
#include <__verbose_abort>
15+
16+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17+
# pragma GCC system_header
18+
#endif
19+
20+
// purposefully not using versioning namespace
21+
namespace std {
22+
#if !defined(_LIBCPP_ABI_VCRUNTIME)
23+
24+
class _LIBCPP_EXPORTED_FROM_ABI bad_alloc : public exception {
25+
public:
26+
bad_alloc() _NOEXCEPT;
27+
_LIBCPP_HIDE_FROM_ABI bad_alloc(const bad_alloc&) _NOEXCEPT = default;
28+
_LIBCPP_HIDE_FROM_ABI bad_alloc& operator=(const bad_alloc&) _NOEXCEPT = default;
29+
~bad_alloc() _NOEXCEPT override;
30+
const char* what() const _NOEXCEPT override;
31+
};
32+
33+
class _LIBCPP_EXPORTED_FROM_ABI bad_array_new_length : public bad_alloc {
34+
public:
35+
bad_array_new_length() _NOEXCEPT;
36+
_LIBCPP_HIDE_FROM_ABI bad_array_new_length(const bad_array_new_length&) _NOEXCEPT = default;
37+
_LIBCPP_HIDE_FROM_ABI bad_array_new_length& operator=(const bad_array_new_length&) _NOEXCEPT = default;
38+
~bad_array_new_length() _NOEXCEPT override;
39+
const char* what() const _NOEXCEPT override;
40+
};
41+
42+
#elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME
43+
44+
// When _HAS_EXCEPTIONS == 0, these complete definitions are needed,
45+
// since they would normally be provided in vcruntime_exception.h
46+
class bad_alloc : public exception {
47+
public:
48+
bad_alloc() noexcept : exception("bad allocation") {}
49+
50+
private:
51+
friend class bad_array_new_length;
52+
53+
bad_alloc(char const* const __message) noexcept : exception(__message) {}
54+
};
55+
56+
class bad_array_new_length : public bad_alloc {
57+
public:
58+
bad_array_new_length() noexcept : bad_alloc("bad array new length") {}
59+
};
60+
61+
#endif // defined(_LIBCPP_ABI_VCRUNTIME) && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0
62+
63+
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void __throw_bad_alloc(); // not in C++ spec
64+
65+
[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_array_new_length() {
66+
#if _LIBCPP_HAS_EXCEPTIONS
67+
throw bad_array_new_length();
68+
#else
69+
_LIBCPP_VERBOSE_ABORT("bad_array_new_length was thrown in -fno-exceptions mode");
70+
#endif
71+
}
72+
} // namespace std
73+
74+
#endif // _LIBCPP___NEW_EXCEPTIONS_H

0 commit comments

Comments
 (0)