Skip to content

Commit 38e3bd0

Browse files
authored
Merge branch 'llvm:main' into main
2 parents 57fd7fe + c6f67b8 commit 38e3bd0

File tree

34 files changed

+1343
-139
lines changed

34 files changed

+1343
-139
lines changed

.github/workflows/pr-code-format.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
- name: Install clang-format
6161
uses: aminya/setup-cpp@v1
6262
with:
63-
clangformat: 18.1.7
63+
clangformat: 19.1.6
6464

6565
- name: Setup Python env
6666
uses: actions/setup-python@v5

compiler-rt/cmake/base-config-ix.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ else()
8989
set(COMPILER_RT_TEST_COMPILER_ID GNU)
9090
endif()
9191

92+
# AppleClang expects 'Clang' as compiler-rt test compiler ID.
93+
if ("${COMPILER_RT_TEST_COMPILER_ID}" STREQUAL "AppleClang")
94+
set(COMPILER_RT_TEST_COMPILER_ID Clang)
95+
endif()
96+
9297
if(NOT DEFINED COMPILER_RT_OS_DIR)
9398
if(ANDROID)
9499
# The CMAKE_SYSTEM_NAME for Android is Android, but the OS is Linux and the

libc/config/baremetal/config.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,5 @@
3030
"LIBC_CONF_MATH_OPTIMIZATIONS": {
3131
"value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES)"
3232
}
33-
},
34-
"codegen": {
35-
"LIBC_CONF_KEEP_FRAME_POINTER": {
36-
"value": false
37-
}
3833
}
3934
}

libc/include/__llvm-libc-common.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,14 @@
5050
#define __END_C_DECLS
5151

5252
#undef __restrict
53-
#define __restrict restrict // C99 and above support the restrict keyword.
53+
#if __STDC_VERSION__ >= 199901L
54+
// C99 and above support the restrict keyword.
55+
#define __restrict restrict
56+
#elif !defined(__GNUC__)
57+
// GNU-compatible compilers accept the __ spelling in all modes.
58+
// Otherwise, omit the qualifier for pure C89 compatibility.
59+
#define __restrict
60+
#endif
5461

5562
#undef _Noreturn
5663
#if __STDC_VERSION__ >= 201112L

libcxx/docs/Hardening.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,10 @@ ABI configuration.
311311
ABI options
312312
-----------
313313

314-
Vendors can use the following ABI options to enable additional hardening checks:
314+
Vendors can use some ABI options at CMake configuration time (when building libc++
315+
itself) to enable additional hardening checks. This is done by passing these
316+
macros as ``-DLIBCXX_ABI_DEFINES="_LIBCPP_ABI_FOO;_LIBCPP_ABI_BAR;etc"`` at
317+
CMake configuration time. The available options are:
315318

316319
- ``_LIBCPP_ABI_BOUNDED_ITERATORS`` -- changes the iterator type of select
317320
containers (see below) to a bounded iterator that keeps track of whether it's
@@ -341,7 +344,7 @@ Vendors can use the following ABI options to enable additional hardening checks:
341344

342345
ABI impact: changes the iterator type of ``vector`` (except ``vector<bool>``).
343346

344-
- ``_LIBCPP_ABI_BOUNDED_UNIQUE_PTR``` -- tracks the bounds of the array stored inside
347+
- ``_LIBCPP_ABI_BOUNDED_UNIQUE_PTR`` -- tracks the bounds of the array stored inside
345348
a ``std::unique_ptr<T[]>``, allowing it to trap when accessed out-of-bounds. This
346349
requires the ``std::unique_ptr`` to be created using an API like ``std::make_unique``
347350
or ``std::make_unique_for_overwrite``, otherwise the bounds information is not available

libcxx/include/__vector/vector_bool.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator> {
279279
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __n) const {
280280
return __make_ref(__n);
281281
}
282-
_LIBCPP_HIDE_FROM_ABI reference at(size_type __n);
283-
_LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const;
282+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n);
283+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
284284

285285
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() { return __make_ref(0); }
286286
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const { return __make_ref(0); }
@@ -853,14 +853,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::shrink_to_fit() _NO
853853
}
854854

855855
template <class _Allocator>
856-
typename vector<bool, _Allocator>::reference vector<bool, _Allocator>::at(size_type __n) {
856+
_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::reference vector<bool, _Allocator>::at(size_type __n) {
857857
if (__n >= size())
858858
this->__throw_out_of_range();
859859
return (*this)[__n];
860860
}
861861

862862
template <class _Allocator>
863-
typename vector<bool, _Allocator>::const_reference vector<bool, _Allocator>::at(size_type __n) const {
863+
_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::const_reference
864+
vector<bool, _Allocator>::at(size_type __n) const {
864865
if (__n >= size())
865866
this->__throw_out_of_range();
866867
return (*this)[__n];

libcxx/src/filesystem/operations.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,16 @@
3939
#include <fcntl.h> /* values for fchmodat */
4040
#include <time.h>
4141

42-
// since Linux 4.5 and FreeBSD 13, but the Linux libc wrapper is only provided by glibc and musl
43-
#if (defined(__linux__) && (defined(__GLIBC__) || _LIBCPP_HAS_MUSL_LIBC)) || defined(__FreeBSD__)
42+
// since Linux 4.5 and FreeBSD 13, but the Linux libc wrapper is only provided by glibc >= 2.27 and musl
43+
#if defined(__linux__)
44+
# if defined(_LIBCPP_GLIBC_PREREQ)
45+
# if _LIBCPP_GLIBC_PREREQ(2, 27)
46+
# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
47+
# endif
48+
# elif _LIBCPP_HAS_MUSL_LIBC
49+
# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
50+
# endif
51+
#elif defined(__FreeBSD__)
4452
# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
4553
#endif
4654
#if __has_include(<sys/sendfile.h>)

libcxx/src/include/overridable_function.h

Lines changed: 45 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -29,106 +29,81 @@
2929
// This is a low-level utility which does not work on all platforms, since it needs
3030
// to make assumptions about the object file format in use. Furthermore, it requires
3131
// the "base definition" of the function (the one we want to check whether it has been
32-
// overridden) to be annotated with the _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro.
32+
// overridden) to be defined using the _LIBCPP_OVERRIDABLE_FUNCTION macro.
3333
//
3434
// This currently works with Mach-O files (used on Darwin) and with ELF files (used on Linux
3535
// and others). On platforms where we know how to implement this detection, the macro
3636
// _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION is defined to 1, and it is defined to 0 on
37-
// other platforms. The _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro is defined to
38-
// nothing on unsupported platforms so that it can be used to decorate functions regardless
39-
// of whether detection is actually supported.
37+
// other platforms. The _LIBCPP_OVERRIDABLE_FUNCTION macro expands to regular function
38+
// definition on unsupported platforms so that it can be used to decorate functions
39+
// regardless of whether detection is actually supported.
4040
//
4141
// How does this work?
4242
// -------------------
4343
//
4444
// Let's say we want to check whether a weak function `f` has been overridden by the user.
45-
// The general mechanism works by placing `f`'s definition (in the libc++ built library)
46-
// inside a special section, which we do using the `__section__` attribute via the
47-
// _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro.
45+
// The general mechanism works by defining a symbol `f_impl__` and a weak alias `f` via the
46+
// _LIBCPP_OVERRIDABLE_FUNCTION macro.
4847
//
4948
// Then, when comes the time to check whether the function has been overridden, we take
50-
// the address of the function and we check whether it falls inside the special function
51-
// we created. This can be done by finding pointers to the start and the end of the section
52-
// (which is done differently for ELF and Mach-O), and then checking whether `f` falls
53-
// within those bounds. If it falls within those bounds, then `f` is still inside the
54-
// special section and so it is the version we defined in the libc++ built library, i.e.
55-
// it was not overridden. Otherwise, it was overridden by the user because it falls
56-
// outside of the section.
49+
// the address of the function `f` and we check whether it is different from `f_impl__`.
50+
// If so it means the function was overriden by the user.
5751
//
5852
// Important note
5953
// --------------
6054
//
61-
// This mechanism should never be used outside of the libc++ built library. In particular,
62-
// attempting to use this within the libc++ headers will not work at all because we don't
63-
// want to be defining special sections inside user's executables which use our headers.
55+
// This mechanism should never be used outside of the libc++ built library. Functions defined
56+
// with this macro must be defined at global scope.
6457
//
6558

6659
#if defined(_LIBCPP_OBJECT_FORMAT_MACHO)
6760

68-
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
69-
# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE \
70-
__attribute__((__section__("__TEXT,__lcxx_override,regular,pure_instructions")))
71-
7261
_LIBCPP_BEGIN_NAMESPACE_STD
73-
template <class _Ret, class... _Args>
74-
_LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) noexcept {
75-
// Declare two dummy bytes and give them these special `__asm` values. These values are
76-
// defined by the linker, which means that referring to `&__lcxx_override_start` will
77-
// effectively refer to the address where the section starts (and same for the end).
78-
extern char __lcxx_override_start __asm("section$start$__TEXT$__lcxx_override");
79-
extern char __lcxx_override_end __asm("section$end$__TEXT$__lcxx_override");
80-
81-
// Now get a uintptr_t out of these locations, and out of the function pointer.
82-
uintptr_t __start = reinterpret_cast<uintptr_t>(&__lcxx_override_start);
83-
uintptr_t __end = reinterpret_cast<uintptr_t>(&__lcxx_override_end);
84-
uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr);
85-
86-
# if __has_feature(ptrauth_calls)
87-
// We must pass a void* to ptrauth_strip since it only accepts a pointer type. Also, in particular,
88-
// we must NOT pass a function pointer, otherwise we will strip the function pointer, and then attempt
89-
// to authenticate and re-sign it when casting it to a uintptr_t again, which will fail because we just
90-
// stripped the function pointer. See rdar://122927845.
91-
__ptr = reinterpret_cast<uintptr_t>(ptrauth_strip(reinterpret_cast<void*>(__ptr), ptrauth_key_function_pointer));
92-
# endif
93-
94-
// Finally, the function was overridden if it falls outside of the section's bounds.
95-
return __ptr < __start || __ptr > __end;
96-
}
97-
_LIBCPP_END_NAMESPACE_STD
9862

99-
// The NVPTX linker cannot create '__start/__stop' sections.
100-
#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) && !defined(__NVPTX__)
63+
template <auto _Func>
64+
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_function_overridden();
10165

102-
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
103-
# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE __attribute__((__section__("__lcxx_override")))
66+
_LIBCPP_END_NAMESPACE_STD
10467

105-
// This is very similar to what we do for Mach-O above. The ELF linker will implicitly define
106-
// variables with those names corresponding to the start and the end of the section.
107-
//
108-
// See https://stackoverflow.com/questions/16552710/how-do-you-get-the-start-and-end-addresses-of-a-custom-elf-section
109-
extern char __start___lcxx_override;
110-
extern char __stop___lcxx_override;
68+
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
69+
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
70+
static __attribute__((used)) type symbol##_impl__ arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \
71+
__asm__(".globl _" _LIBCPP_TOSTRING(symbol)); \
72+
__asm__(".weak_definition _" _LIBCPP_TOSTRING(symbol)); \
73+
extern __typeof(symbol##_impl__) name __attribute__((weak_import)); \
74+
_LIBCPP_BEGIN_NAMESPACE_STD \
75+
template <> \
76+
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
77+
return static_cast<type(*) arglist>(name) != symbol##_impl__; \
78+
} \
79+
_LIBCPP_END_NAMESPACE_STD \
80+
static type symbol##_impl__ arglist
81+
82+
#elif defined(_LIBCPP_OBJECT_FORMAT_ELF)
11183

11284
_LIBCPP_BEGIN_NAMESPACE_STD
113-
template <class _Ret, class... _Args>
114-
_LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) noexcept {
115-
uintptr_t __start = reinterpret_cast<uintptr_t>(&__start___lcxx_override);
116-
uintptr_t __end = reinterpret_cast<uintptr_t>(&__stop___lcxx_override);
117-
uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr);
118-
119-
# if __has_feature(ptrauth_calls)
120-
// We must pass a void* to ptrauth_strip since it only accepts a pointer type. See full explanation above.
121-
__ptr = reinterpret_cast<uintptr_t>(ptrauth_strip(reinterpret_cast<void*>(__ptr), ptrauth_key_function_pointer));
122-
# endif
123-
124-
return __ptr < __start || __ptr > __end;
125-
}
85+
86+
template <auto _Func>
87+
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_function_overridden();
88+
12689
_LIBCPP_END_NAMESPACE_STD
12790

91+
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
92+
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \
93+
static type symbol##_impl__ arglist __asm__(_LIBCPP_TOSTRING(symbol##_impl__)); \
94+
[[gnu::weak, gnu::alias(_LIBCPP_TOSTRING(symbol##_impl__))]] type name arglist; \
95+
_LIBCPP_BEGIN_NAMESPACE_STD \
96+
template <> \
97+
inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \
98+
return static_cast<type(*) arglist>(name) != symbol##_impl__; \
99+
} \
100+
_LIBCPP_END_NAMESPACE_STD \
101+
static type symbol##_impl__ arglist
102+
128103
#else
129104

130105
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0
131-
# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE /* nothing */
106+
# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) _LIBCPP_WEAK type name arglist
132107

133108
#endif
134109

libcxx/src/new.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static void* operator_new_impl(std::size_t size) {
4343
return p;
4444
}
4545

46-
_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
46+
_LIBCPP_OVERRIDABLE_FUNCTION(_Znwm, void*, operator new, (std::size_t size)) _THROW_BAD_ALLOC {
4747
void* p = operator_new_impl(size);
4848
if (p == nullptr)
4949
__throw_bad_alloc_shim();
@@ -54,7 +54,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
5454
# if !_LIBCPP_HAS_EXCEPTIONS
5555
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
5656
_LIBCPP_ASSERT_SHIM(
57-
!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)),
57+
!std::__is_function_overridden<static_cast<void* (*)(std::size_t)>(&operator new)>(),
5858
"libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, "
5959
"but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because "
6060
"`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case "
@@ -74,15 +74,15 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
7474
# endif
7575
}
7676

77-
_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC {
77+
_LIBCPP_OVERRIDABLE_FUNCTION(_Znam, void*, operator new[], (size_t size)) _THROW_BAD_ALLOC {
7878
return ::operator new(size);
7979
}
8080

8181
_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
8282
# if !_LIBCPP_HAS_EXCEPTIONS
8383
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
8484
_LIBCPP_ASSERT_SHIM(
85-
!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])),
85+
!std::__is_function_overridden<static_cast<void* (*)(std::size_t)>(&operator new[])>(),
8686
"libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, "
8787
"but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because "
8888
"`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case "
@@ -136,8 +136,8 @@ static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignm
136136
return p;
137137
}
138138

139-
_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*
140-
operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
139+
_LIBCPP_OVERRIDABLE_FUNCTION(_ZnwmSt11align_val_t, void*, operator new, (std::size_t size, std::align_val_t alignment))
140+
_THROW_BAD_ALLOC {
141141
void* p = operator_new_aligned_impl(size, alignment);
142142
if (p == nullptr)
143143
__throw_bad_alloc_shim();
@@ -148,7 +148,7 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const s
148148
# if !_LIBCPP_HAS_EXCEPTIONS
149149
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
150150
_LIBCPP_ASSERT_SHIM(
151-
!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)),
151+
!std::__is_function_overridden<static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)>(),
152152
"libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, "
153153
"but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "
154154
"`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will "
@@ -168,16 +168,14 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const s
168168
# endif
169169
}
170170

171-
_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*
172-
operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
173-
return ::operator new(size, alignment);
174-
}
171+
_LIBCPP_OVERRIDABLE_FUNCTION(_ZnamSt11align_val_t, void*, operator new[], (size_t size, std::align_val_t alignment))
172+
_THROW_BAD_ALLOC { return ::operator new(size, alignment); }
175173

176174
_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
177175
# if !_LIBCPP_HAS_EXCEPTIONS
178176
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
179177
_LIBCPP_ASSERT_SHIM(
180-
!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])),
178+
!std::__is_function_overridden<static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])>(),
181179
"libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, "
182180
"but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "
183181
"`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will "

0 commit comments

Comments
 (0)