[llvm-bugs] [Bug 45099] New: std::any uses mismatched allocation and deallocation
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Mar 4 06:20:38 PST 2020
https://bugs.llvm.org/show_bug.cgi?id=45099
Bug ID: 45099
Summary: std::any uses mismatched allocation and deallocation
Product: libc++
Version: unspecified
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P
Component: All Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: tkoeppe at google.com
CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com
The constructors of std::any that create an object of type T use
std::allocator<T> to allocate memory and "::new ((T*)p)" placement new to
construct the object. (That is, memory allocation subject only to
specializations of std::allocator, and construction only to overloads of global
operator new for user pointer types.)
By contrast, destruction uses "delete (T*)p". This means that overloaded
operators T::operator delete will be used.
(In the above, the cast notation "(T*)" doesn't appear literally in the code,
but is just my way of indicating the argument type. Specifically, note that
there is no cast to void* in the placement new.)
This mismatch results in undefined behaviour whenever a suitable amount of user
customization is present for T. Examples can be constructed to exercise all
aspects of this (specializing std::allocator, adding a ::operator
new(std::size_t, T*) overload, or adding overloaded operators T::operator
delete).
One example:
================
#include <any>
#include <cstddef>
#include <cstdlib>
struct U {
int big[128];
static void* operator new(std::size_t n) { return std::malloc(n); }
static void operator delete(void* p) { std::free(p); }
};
int main() {
std::any a(std::in_place_type<U>);
return std::any_cast<U*>(a) != nullptr; // avoid optimizing everything
away
}
================
The generated code clearly shows one call to "operator new" and one to "free".
One solution would be to make the construction use an unqualified new
expression "new _Tp(...)"; this means that standard library code will call
user-defined functions for internal bookkeeping. An alternative solution would
be to also use std::allocator to deallocate the allocation.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200304/912f3138/attachment.html>
More information about the llvm-bugs
mailing list