<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - std::basic_string misbehavior when sizeof(CharT) > 8"
   href="https://bugs.llvm.org/show_bug.cgi?id=51816">51816</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::basic_string misbehavior when sizeof(CharT) > 8
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>georgthegreat@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=25247" name="attach_25247" title="Test using gtest">attachment 25247</a> <a href="attachment.cgi?id=25247&action=edit" title="Test using gtest">[details]</a></span>
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>
<span class="quote">>::deallocate(Allocator<WeirdChar12>&, WeirdChar12*, unsigned long)</span >
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.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>