[llvm-bugs] [Bug 51816] New: std::basic_string misbehavior when sizeof(CharT) > 8
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Sep 10 05:41:02 PDT 2021
https://bugs.llvm.org/show_bug.cgi?id=51816
Bug ID: 51816
Summary: std::basic_string misbehavior when sizeof(CharT) > 8
Product: libc++
Version: unspecified
Hardware: PC
OS: Windows NT
Status: NEW
Severity: enhancement
Priority: P
Component: All Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: georgthegreat at gmail.com
CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com
Created attachment 25247
--> https://bugs.llvm.org/attachment.cgi?id=25247&action=edit
Test using gtest
An attempt to compile std::basic_string with various weird character types
would lead to a multiple issues.
So far I have found the following:
1. stack allocation size would grow due to overallocation, i. e:
if constexpr (sizeof(Char) == 12) {
EXPECT_EQ(sizeof(s), 40u);
}
2. allocations would become power-of-two-exponential, i. e:
for (size_t i = 0; i < 47u; ++i) {
s.push_back({});
}
if constexpr (sizeof(Char) <= 4) {
// OK, do not request power-of-two blocks from allocator
EXPECT_EQ(
s.capacity(),
// capacity grows exponentially starting from 22 bytes
47u
);
} else if constexpr (sizeof(Char) == 8) {
// Bad
EXPECT_EQ(
s.capacity(),
// capacity grows exponentially as the power-of-two
63u
);
}
3. Memory leak is detected by ASan when both -fsized-deallocation is enabled
and stable ABI is used (i. e. _LIBCPP_ABI_VERSION == 2):
==1260518==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x6080000004a0
in thread T0:
object passed to delete has wrong type:
size of the allocated type: 84 bytes;
size of the deallocated type: 72 bytes.
#0 0x4cdc02 in void std::__y1::__libcpp_operator_delete<void*, unsigned
long>(void*, unsigned long)
/home/thegeorg/arcadia/contrib/libs/cxxsupp/libcxx/include/new:245:3
#1 0x4cdc02 in void std::__y1::__do_deallocate_handle_size<>(void*,
unsigned long) include/new:271:10
#2 0x4cdc02 in std::__y1::__libcpp_deallocate(void*, unsigned long,
unsigned long) include/new:285:14
#3 0x4cdc02 in std::__y1::allocator<WeirdChar12>::deallocate(WeirdChar12*,
unsigned long) include/memory:850:13
#4 0x4cdc02 in std::__y1::allocator_traits<Allocator<WeirdChar12>
>::deallocate(Allocator<WeirdChar12>&, WeirdChar12*, unsigned long)
include/__memory/allocator_traits.h:484:14
This is caused by incorrect alignment in __recommend() and attempt to allocate
odd number of characters. String capacity() must be even as odd bit will be
overwritten by __long_mask.
Though C++ standard does not limit sizeof(CharT), I suggest
static_assert(sizeof(CharT) <= 4) to be added into libc++.
Though this could break existing codebases, I consider the break fast to be the
better option.
I do not think SSO is anyway helpful whenever sizeof(CharT) >= 8. Maybe we
should ensure that std::basic_strin is always long is such cases.
--
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/20210910/66b6f569/attachment-0001.html>
More information about the llvm-bugs
mailing list