-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Labels
ABIApplication Binary InterfaceApplication Binary Interfacelibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.regression:20Regression in 20 releaseRegression in 20 releaseregression:21Regression in 21 releaseRegression in 21 release
Milestone
Description
The following code shows how the size of std::deque has changed in LLVM version 21.
// t.h
#include <deque>
#include <memory>
#include <cassert>
struct malloc_allocator_base {
static std::size_t outstanding_bytes;
static std::size_t alloc_count;
static std::size_t dealloc_count;
static bool disable_default_constructor;
static std::size_t outstanding_alloc() {
assert(alloc_count >= dealloc_count);
return (alloc_count - dealloc_count);
}
static void reset() {
assert(outstanding_alloc() == 0);
disable_default_constructor = false;
outstanding_bytes = 0;
alloc_count = 0;
dealloc_count = 0;
}
};
size_t malloc_allocator_base::outstanding_bytes = 0;
size_t malloc_allocator_base::alloc_count = 0;
size_t malloc_allocator_base::dealloc_count = 0;
bool malloc_allocator_base::disable_default_constructor = false;
template <class T>
class malloc_allocator : public malloc_allocator_base {
public:
typedef T value_type;
malloc_allocator() noexcept { assert(!disable_default_constructor); }
template <class U>
malloc_allocator(malloc_allocator<U>) noexcept {}
T* allocate(std::size_t n) {
const std::size_t nbytes = n * sizeof(T);
++alloc_count;
outstanding_bytes += nbytes;
return static_cast<T*>(std::malloc(nbytes));
}
void deallocate(T* p, std::size_t n) {
const std::size_t nbytes = n * sizeof(T);
++dealloc_count;
outstanding_bytes -= nbytes;
std::free(static_cast<void*>(p));
}
friend bool operator==(malloc_allocator, malloc_allocator) { return true; }
friend bool operator!=(malloc_allocator x, malloc_allocator y) { return !(x == y); }
};
int sizeOfCreatedDeque();
std::deque<int, malloc_allocator<int> > dq;
t.C
#include "t.h"
int sizeOfCreatedDeque() {
dq.push_front(1);
dq.push_front(2);
dq.push_front(3);
return sizeof(dq);
}
// t2.C
#include "t.h"
#include <iostream>
int main() {
using namespace std;
int previousSize = sizeOfCreatedDeque();
int currentSize = sizeof(dq);
if (currentSize != previousSize)
cerr << "ABI break std::deque`s size changed from " << previousSize << " to " << currentSize << endl;
return 0;
}
Compile t2.C with LLVM 21/20 clang and t.C with previous version, for example LLVM 19 . Then, run executable:
I'm getting the following:
**ABI break std::deques size changed from 48 to 56** I compiled t.C` with clang version 18.1.8 but any version prior to PR 76756 would do as well.
My investigation point to #76756 as culprit.
Metadata
Metadata
Assignees
Labels
ABIApplication Binary InterfaceApplication Binary Interfacelibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.regression:20Regression in 20 releaseRegression in 20 releaseregression:21Regression in 21 releaseRegression in 21 release
Type
Projects
Status
Done