-
Notifications
You must be signed in to change notification settings - Fork 12.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Builtins] Overload __builtin_operator_new/delete to allow forwarding…
… to usual allocation/deallocation functions. Summary: Libc++'s default allocator uses `__builtin_operator_new` and `__builtin_operator_delete` in order to allow the calls to new/delete to be ellided. However, libc++ now needs to support over-aligned types in the default allocator. In order to support this without disabling the existing optimization Clang needs to support calling the aligned new overloads from the builtins. See llvm.org/PR22634 for more information about the libc++ bug. This patch changes `__builtin_operator_new`/`__builtin_operator_delete` to call any usual `operator new`/`operator delete` function. It does this by performing overload resolution with the arguments passed to the builtin to determine which allocation function to call. If the selected function is not a usual allocation function a diagnostic is issued. One open issue is if the `align_val_t` overloads should be considered "usual" when `LangOpts::AlignedAllocation` is disabled. In order to allow libc++ to detect this new behavior the value for `__has_builtin(__builtin_operator_new)` has been updated to `201802`. Reviewers: rsmith, majnemer, aaron.ballman, erik.pilkington, bogner, ahatanak Reviewed By: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D43047 llvm-svn: 328134
- Loading branch information
Showing
11 changed files
with
386 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s \ | ||
// RUN: -faligned-allocation -fsized-deallocation -emit-llvm -o - \ | ||
// RUN: | FileCheck %s | ||
|
||
typedef __SIZE_TYPE__ size_t; | ||
|
||
// Declare an 'operator new' template to tickle a bug in __builtin_operator_new. | ||
template<typename T> void *operator new(size_t, int (*)(T)); | ||
|
||
// Ensure that this declaration doesn't cause operator new to lose its | ||
// 'noalias' attribute. | ||
void *operator new(size_t); | ||
|
||
namespace std { | ||
struct nothrow_t {}; | ||
enum class align_val_t : size_t { __zero = 0, | ||
__max = (size_t)-1 }; | ||
} | ||
std::nothrow_t nothrow; | ||
|
||
// Declare the reserved placement operators. | ||
void *operator new(size_t, void*) throw(); | ||
void operator delete(void*, void*) throw(); | ||
void *operator new[](size_t, void*) throw(); | ||
void operator delete[](void*, void*) throw(); | ||
|
||
// Declare the replaceable global allocation operators. | ||
void *operator new(size_t, const std::nothrow_t &) throw(); | ||
void *operator new[](size_t, const std::nothrow_t &) throw(); | ||
void operator delete(void *, const std::nothrow_t &) throw(); | ||
void operator delete[](void *, const std::nothrow_t &) throw(); | ||
|
||
// Declare some other placement operators. | ||
void *operator new(size_t, void*, bool) throw(); | ||
void *operator new[](size_t, void*, bool) throw(); | ||
|
||
|
||
// CHECK-LABEL: define void @test_basic( | ||
extern "C" void test_basic() { | ||
// CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] | ||
// CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]] | ||
// CHECK: ret void | ||
__builtin_operator_delete(__builtin_operator_new(4)); | ||
} | ||
// CHECK: declare noalias i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]] | ||
// CHECK: declare void @_ZdlPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]] | ||
|
||
// CHECK-LABEL: define void @test_aligned_alloc( | ||
extern "C" void test_aligned_alloc() { | ||
// CHECK: call i8* @_ZnwmSt11align_val_t(i64 4, i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] | ||
// CHECK: call void @_ZdlPvSt11align_val_t({{.*}}, i64 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]] | ||
__builtin_operator_delete(__builtin_operator_new(4, std::align_val_t(4)), std::align_val_t(4)); | ||
} | ||
// CHECK: declare noalias i8* @_ZnwmSt11align_val_t(i64, i64) [[ATTR_NOBUILTIN:#[^ ]*]] | ||
// CHECK: declare void @_ZdlPvSt11align_val_t(i8*, i64) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]] | ||
|
||
|
||
// CHECK-LABEL: define void @test_sized_delete( | ||
extern "C" void test_sized_delete() { | ||
// CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] | ||
// CHECK: call void @_ZdlPvm({{.*}}, i64 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]] | ||
__builtin_operator_delete(__builtin_operator_new(4), 4); | ||
} | ||
// CHECK: declare void @_ZdlPvm(i8*, i64) [[ATTR_NOBUILTIN_UNWIND:#[^ ]*]] | ||
|
||
|
||
// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin {{.*[}]}} | ||
// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}} | ||
|
||
// CHECK-DAG: attributes [[ATTR_BUILTIN_NEW]] = {{[{].*}} builtin {{.*[}]}} | ||
// CHECK-DAG: attributes [[ATTR_BUILTIN_DELETE]] = {{[{].*}} builtin {{.*[}]}} |
Oops, something went wrong.