Skip to content

Commit 7aaff8f

Browse files
committed
[ADT] Move allocate_buffer to MemAlloc.h and out of line
There's an ABI breakage here if LLVM is compiled in C++14 without aligned allocation and a user tries to use the result with aligned allocation. If DenseMap or unique_function is used across that ABI boundary it will break (PR45413). Moving it out of line is a bit of a band-aid and LLVM doesn't really give ABI guarantees at this level, but given the number of complaints I've received over this it still seems worth fixing.
1 parent 0517255 commit 7aaff8f

File tree

6 files changed

+58
-45
lines changed

6 files changed

+58
-45
lines changed

llvm/include/llvm/ADT/DenseMap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/Support/AlignOf.h"
1919
#include "llvm/Support/Compiler.h"
2020
#include "llvm/Support/MathExtras.h"
21+
#include "llvm/Support/MemAlloc.h"
2122
#include "llvm/Support/ReverseIteration.h"
2223
#include "llvm/Support/type_traits.h"
2324
#include <algorithm>

llvm/include/llvm/ADT/FunctionExtras.h

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

3535
#include "llvm/ADT/PointerIntPair.h"
3636
#include "llvm/ADT/PointerUnion.h"
37+
#include "llvm/Support/MemAlloc.h"
3738
#include "llvm/Support/type_traits.h"
3839
#include <memory>
3940

llvm/include/llvm/Support/Compiler.h

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -551,48 +551,4 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
551551
#define LLVM_ENABLE_EXCEPTIONS 1
552552
#endif
553553

554-
#ifdef __cplusplus
555-
namespace llvm {
556-
557-
/// Allocate a buffer of memory with the given size and alignment.
558-
///
559-
/// When the compiler supports aligned operator new, this will use it to to
560-
/// handle even over-aligned allocations.
561-
///
562-
/// However, this doesn't make any attempt to leverage the fancier techniques
563-
/// like posix_memalign due to portability. It is mostly intended to allow
564-
/// compatibility with platforms that, after aligned allocation was added, use
565-
/// reduced default alignment.
566-
inline void *allocate_buffer(size_t Size, size_t Alignment) {
567-
return ::operator new(Size
568-
#ifdef __cpp_aligned_new
569-
,
570-
std::align_val_t(Alignment)
571-
#endif
572-
);
573-
}
574-
575-
/// Deallocate a buffer of memory with the given size and alignment.
576-
///
577-
/// If supported, this will used the sized delete operator. Also if supported,
578-
/// this will pass the alignment to the delete operator.
579-
///
580-
/// The pointer must have been allocated with the corresponding new operator,
581-
/// most likely using the above helper.
582-
inline void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
583-
::operator delete(Ptr
584-
#ifdef __cpp_sized_deallocation
585-
,
586-
Size
587-
#endif
588-
#ifdef __cpp_aligned_new
589-
,
590-
std::align_val_t(Alignment)
591-
#endif
592-
);
593-
}
594-
595-
} // End namespace llvm
596-
597-
#endif // __cplusplus
598554
#endif

llvm/include/llvm/Support/MemAlloc.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,26 @@ LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_realloc(void *Ptr, size_t Sz) {
6262
return Result;
6363
}
6464

65-
}
65+
/// Allocate a buffer of memory with the given size and alignment.
66+
///
67+
/// When the compiler supports aligned operator new, this will use it to to
68+
/// handle even over-aligned allocations.
69+
///
70+
/// However, this doesn't make any attempt to leverage the fancier techniques
71+
/// like posix_memalign due to portability. It is mostly intended to allow
72+
/// compatibility with platforms that, after aligned allocation was added, use
73+
/// reduced default alignment.
74+
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void *
75+
allocate_buffer(size_t Size, size_t Alignment);
76+
77+
/// Deallocate a buffer of memory with the given size and alignment.
78+
///
79+
/// If supported, this will used the sized delete operator. Also if supported,
80+
/// this will pass the alignment to the delete operator.
81+
///
82+
/// The pointer must have been allocated with the corresponding new operator,
83+
/// most likely using the above helper.
84+
void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment);
85+
86+
} // namespace llvm
6687
#endif

llvm/lib/Support/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ add_llvm_component_library(LLVMSupport
115115
LowLevelType.cpp
116116
ManagedStatic.cpp
117117
MathExtras.cpp
118+
MemAlloc.cpp
118119
MemoryBuffer.cpp
119120
MD5.cpp
120121
NativeFormatting.cpp

llvm/lib/Support/MemAlloc.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===- MemAlloc.cpp - Memory allocation functions -------------------------===//
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+
#include "llvm/Support/MemAlloc.h"
10+
11+
// These are out of line to have __cpp_aligned_new not affect ABI.
12+
13+
void *llvm::allocate_buffer(size_t Size, size_t Alignment) {
14+
return ::operator new(Size
15+
#ifdef __cpp_aligned_new
16+
,
17+
std::align_val_t(Alignment)
18+
#endif
19+
);
20+
}
21+
22+
void llvm::deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
23+
::operator delete(Ptr
24+
#ifdef __cpp_sized_deallocation
25+
,
26+
Size
27+
#endif
28+
#ifdef __cpp_aligned_new
29+
,
30+
std::align_val_t(Alignment)
31+
#endif
32+
);
33+
}

0 commit comments

Comments
 (0)