diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_array.hh | 4 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_generic_array.hh | 2 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_linear_allocator.hh | 2 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_map.hh | 4 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_memory_utils.hh | 24 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_set.hh | 4 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_stack.hh | 4 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_utildefines.h | 12 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_vector.hh | 4 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_vector_set.hh | 4 |
11 files changed, 42 insertions, 23 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 85827e01af5..3e97e393f17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1756,6 +1756,7 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC") "/wd4828" # The file contains a character that is illegal "/wd4996" # identifier was declared deprecated "/wd4661" # no suitable definition provided for explicit template instantiation request + "/wd4848" # 'no_unique_address' is a vendor extension in C++17 # errors: "/we4013" # 'function' undefined; assuming extern returning int "/we4133" # incompatible pointer types diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh index 91dfc81ae27..813277d9968 100644 --- a/source/blender/blenlib/BLI_array.hh +++ b/source/blender/blenlib/BLI_array.hh @@ -64,10 +64,10 @@ class Array { int64_t size_; /** Used for allocations when the inline buffer is too small. */ - Allocator allocator_; + BLI_NO_UNIQUE_ADDRESS Allocator allocator_; /** A placeholder buffer that will remain uninitialized until it is used. */ - TypedBuffer<T, InlineBufferCapacity> inline_buffer_; + BLI_NO_UNIQUE_ADDRESS TypedBuffer<T, InlineBufferCapacity> inline_buffer_; public: /** diff --git a/source/blender/blenlib/BLI_generic_array.hh b/source/blender/blenlib/BLI_generic_array.hh index e1b6b29874a..4b917434264 100644 --- a/source/blender/blenlib/BLI_generic_array.hh +++ b/source/blender/blenlib/BLI_generic_array.hh @@ -33,7 +33,7 @@ class GArray { void *data_ = nullptr; int64_t size_ = 0; - Allocator allocator_; + BLI_NO_UNIQUE_ADDRESS Allocator allocator_; public: /** diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh index 6532c59a846..deb6ea3b5fd 100644 --- a/source/blender/blenlib/BLI_linear_allocator.hh +++ b/source/blender/blenlib/BLI_linear_allocator.hh @@ -18,7 +18,7 @@ namespace blender { template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopyable, NonMovable { private: - Allocator allocator_; + BLI_NO_UNIQUE_ADDRESS Allocator allocator_; Vector<void *> owned_buffers_; Vector<Span<char>> unused_borrowed_buffers_; diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh index d76aa46502d..55233676ed8 100644 --- a/source/blender/blenlib/BLI_map.hh +++ b/source/blender/blenlib/BLI_map.hh @@ -130,10 +130,10 @@ class Map { uint64_t slot_mask_; /** This is called to hash incoming keys. */ - Hash hash_; + BLI_NO_UNIQUE_ADDRESS Hash hash_; /** This is called to check equality of two keys. */ - IsEqual is_equal_; + BLI_NO_UNIQUE_ADDRESS IsEqual is_equal_; /** The max load factor is 1/2 = 50% by default. */ #define LOAD_FACTOR 1, 2 diff --git a/source/blender/blenlib/BLI_memory_utils.hh b/source/blender/blenlib/BLI_memory_utils.hh index d7c41ae88a8..940542c9f1d 100644 --- a/source/blender/blenlib/BLI_memory_utils.hh +++ b/source/blender/blenlib/BLI_memory_utils.hh @@ -317,30 +317,36 @@ template<typename T> using destruct_ptr = std::unique_ptr<T, DestructValueAtAddr * An `AlignedBuffer` is a byte array with at least the given size and alignment. The buffer will * not be initialized by the default constructor. */ -template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer { - private: - /* Don't create an empty array. This causes problems with some compilers. */ - char buffer_[(Size > 0) ? Size : 1]; +template<size_t Size, size_t Alignment> class AlignedBuffer { + struct Empty { + }; + struct alignas(Alignment) Sized { + /* Don't create an empty array. This causes problems with some compilers. */ + std::byte buffer_[Size > 0 ? Size : 1]; + }; + + using BufferType = std::conditional_t<Size == 0, Empty, Sized>; + BLI_NO_UNIQUE_ADDRESS BufferType buffer_; public: operator void *() { - return buffer_; + return this; } operator const void *() const { - return buffer_; + return this; } void *ptr() { - return buffer_; + return this; } const void *ptr() const { - return buffer_; + return this; } }; @@ -351,7 +357,7 @@ template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer { */ template<typename T, int64_t Size = 1> class TypedBuffer { private: - AlignedBuffer<sizeof(T) * (size_t)Size, alignof(T)> buffer_; + BLI_NO_UNIQUE_ADDRESS AlignedBuffer<sizeof(T) * (size_t)Size, alignof(T)> buffer_; public: operator T *() diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh index 99acae43571..62de4b79e41 100644 --- a/source/blender/blenlib/BLI_set.hh +++ b/source/blender/blenlib/BLI_set.hh @@ -136,10 +136,10 @@ class Set { uint64_t slot_mask_; /** This is called to hash incoming keys. */ - Hash hash_; + BLI_NO_UNIQUE_ADDRESS Hash hash_; /** This is called to check equality of two keys. */ - IsEqual is_equal_; + BLI_NO_UNIQUE_ADDRESS IsEqual is_equal_; /** The max load factor is 1/2 = 50% by default. */ #define LOAD_FACTOR 1, 2 diff --git a/source/blender/blenlib/BLI_stack.hh b/source/blender/blenlib/BLI_stack.hh index a06515a7781..ed123f43a6b 100644 --- a/source/blender/blenlib/BLI_stack.hh +++ b/source/blender/blenlib/BLI_stack.hh @@ -96,7 +96,7 @@ class Stack { int64_t size_; /** The buffer used to implement small object optimization. */ - TypedBuffer<T, InlineBufferCapacity> inline_buffer_; + BLI_NO_UNIQUE_ADDRESS TypedBuffer<T, InlineBufferCapacity> inline_buffer_; /** * A chunk referencing the inline buffer. This is always the bottom-most chunk. @@ -105,7 +105,7 @@ class Stack { Chunk inline_chunk_; /** Used for allocations when the inline buffer is not large enough. */ - Allocator allocator_; + BLI_NO_UNIQUE_ADDRESS Allocator allocator_; public: /** diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index b8407a5453f..7f9470a9111 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -843,6 +843,18 @@ extern bool BLI_memory_is_zero(const void *arr, size_t arr_size); */ #define BLI_ENABLE_IF(condition) typename std::enable_if_t<(condition)> * = nullptr +#if defined(_MSC_VER) +# define BLI_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] +#elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(no_unique_address) +# define BLI_NO_UNIQUE_ADDRESS [[no_unique_address]] +# else +# define BLI_NO_UNIQUE_ADDRESS +# endif +#else +# define BLI_NO_UNIQUE_ADDRESS [[no_unique_address]] +#endif + /** \} */ #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh index acf47f67168..c23d846d277 100644 --- a/source/blender/blenlib/BLI_vector.hh +++ b/source/blender/blenlib/BLI_vector.hh @@ -84,10 +84,10 @@ class Vector { T *capacity_end_; /** Used for allocations when the inline buffer is too small. */ - Allocator allocator_; + BLI_NO_UNIQUE_ADDRESS Allocator allocator_; /** A placeholder buffer that will remain uninitialized until it is used. */ - TypedBuffer<T, InlineBufferCapacity> inline_buffer_; + BLI_NO_UNIQUE_ADDRESS TypedBuffer<T, InlineBufferCapacity> inline_buffer_; /** * Store the size of the vector explicitly in debug builds. Otherwise you'd always have to call diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh index 4ae1bf9000d..b0a3696f245 100644 --- a/source/blender/blenlib/BLI_vector_set.hh +++ b/source/blender/blenlib/BLI_vector_set.hh @@ -117,10 +117,10 @@ class VectorSet { uint64_t slot_mask_; /** This is called to hash incoming keys. */ - Hash hash_; + BLI_NO_UNIQUE_ADDRESS Hash hash_; /** This is called to check equality of two keys. */ - IsEqual is_equal_; + BLI_NO_UNIQUE_ADDRESS IsEqual is_equal_; /** The max load factor is 1/2 = 50% by default. */ #define LOAD_FACTOR 1, 2 |