<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=http://email.email.llvm.org/c/eJylVstu4zgQ_Br5QsTQwy8dfBjHycJAMDvIZAbYk0GJLYsTmfKSlB3P12-1HrGTTfayBmFZJJtdXV3ddFar8zKYhc6rIPmC4bzVZtf9tuTIHgnLQjtxkNaLuhC-JHGwlNf7g65IiUNtva4NL1U6y4N41Y5boRoSvm7308uh0rn2QhvnpfFaDiYf-GZ3pjXDeVba81h81yYnsZhEURJToWQcTef5tEgpnOdFEk1m6WQeytlkERWFStk5mxeNyVs_eW28hGvMase-wnUQDt-zsB_da5zoQmwfNqvbb9-235_W2593jyJI7kQ073YIfIL4HkM8dgQJQ0eywpWA_-yEdBzYbUdEHI4vZjg5iBfbraW_G3Ke1DaXBwlezvBwGyRrMbxjWxAjkFRY8o01QbJ6xUdG6eJj8O33Uyk9zFxTecdMSiP-XD-Ko66rlnamB4CNOGlf1o3HhrPY6xdw32fkhlOCNCAqB4P2lAahgkhFY_EEbvulT1L4L_m8ySccV5XISGSNrlgTF7LEHh6YpIxyCZcwkz6I504wZ9pCb6cS0NlSMeCL5NgDDJQ8O_A2FiuOTOSVJuOBnjcPoSXr3gY5BboWDoEMRLgj30K9HTYAZynBnRUYVyvA-rqi6MBJYf4M42tPeqPAUh6wxXE9IG5tKm0QCuKE9am2jgbN1gev9_o37Pd6VyIC55o9fQZJGsVLBjSYZyF3LHL_DmWfKXbQiYJxckJNVjdGAcaPFRN2LaENVwpOHBCxBqSlnqRLBcVfxA9wDhKHitl8fdh8vdv-3HzfrDYPm6e_mOCipQ495JUPBo6atiRhzqoSDkGzLO0ZBFqC4Fvv7rzP6upKQEO20YI6-byKqm4qJZxvk_miwUMGBXSzXYGCeUhKjS_g_9BH6pD1ftApHExZMgPJTFx2FrI6QVm9kN4y7GjPPS13nNBTqfOyJesoK62uFi86RwqZgIxADF1x39PpamS8kCZHWVJeSqPdnpXjULA4OyN_IuQcXaAAU4DagXc9z_TOzQdA3yUbXCLSxlVnSIT7OamOFUAuvT-0PbNtebyRTm5cVcf9uLY7TK3TaD5fcN9sVX2ThvE8Tjh_pj619XudNhz6SdV3FcBOneDaZ55l7huJVgGdPMsdtQE2bjxSy0SlSSpHskELs8vf511d1VqNGlst3yLeQbJNNsZ1hReG3T9uDrb-RTmay71GjRGaxv00iebhqFyGFKXTNCmUytMoneBnLtWcosViGs9kPh9VMqPKLYMp8MfXt17MUeCRD6FdpiztUH9dKQ5ze-26e7RvzHEwXY_-fwR6GYdxHOK2DMNwHsXjSIWULfJZOM1nE4WuNwkhBV295nFkl-2RWbNzWKxQA5ckj9CE9M4QDQErgDV0FcZzYxX96vF77StavrlyONv_dUcM_xVY7Luu6Yu9fCZu-9dXLPp_gz8Cwy05auNetkH_A14D1A8>53170</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            ODR violation in std::string::reserve due to change that makes reserve never reduce capacity
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            libc++,
            c++20,
            regression,
            miscompilation
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
            ldionne,
            mkurdej
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          zygoloid
      </td>
    </tr>
</table>

<pre>
    `std::string::reserve` is part of the precompiled portion of libc++, due to the explicit instantiation of `std::string` in the library. Since 841132efda2157c5f9e07cf31469470a6481ffd9, the function contains this:

```
#if _LIBCPP_STD_VER > 17
    // Reserve never shrinks as of C++20.
    if (__requested_capacity <= capacity()) return;
#endif
```

That results in an ODR violation, even without any mixing of `-std` versions in user code. The version of `std::string::reserve` in the library will be built in C++20 mode (because that's required when building libc++ these days). But a client using `-std=c++17` will either get the C++17 behavior or the C++20 behavior depending on whether the function happens to be inlined (or worse, the optimizer might assume the C++17 behavior and then link against the C++20 version, resulting in unbounded UB).

I think the options are either:
* Use `_LIBCPP_INLINE_VISIBILITY` for this function and increase code size everywhere; the symbol in the libc++ prebuilt library would still exist but would never be used.
* Give this symbol consistent behavior, by always using the C++20 semantics (which are valid semantics in C++17 and before).
* Use some fancy mechanism to switch between different symbols for the C++17 and C++20 semantics.

I previously reported this in https://reviews.llvm.org/D91778#inline-902723; now that libc++ is built in C++20 mode, this is causing actual breakage for us.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJx9Vctu4zgQ_Br5QsTQw4_44MM4ThYGgtlBJjPAnAxKbEmcSJSXpOJ4vn6r9YidbLKBYMcim11dXV1MG3VaB4vQeRUkX_A4b7Up-v8tObLPhGWhnThI60WTC1-SOFjKmvqgK1Li0FivG8NLlU6zIN50z41QLQnfdPvp5VDpTHuhjfPSeC3HkA9yczrTheE8K-1pKr5rk5G4nkVRElOuZBzNl9k8X1G4zPIkmi1Ws2UoF7PrKM_VipNzeN6arMuTNcZLpMZb7ThXuA3C8XMRDk__M050Lvb3u83Nt2_774_b_c_bBxEktyJa9jsE_oL4Do946AkShp7JClcC_pMT0nFhNz0RcTg9h-HkIL7e7y3905LzpPaZPEjwckKGmyDZivE3tgUxClkJS761Jkg2r_jIKJ1_DL77fCylR5hrK--YSWnE39sH8aybqqOd6QFgI47al03rseEkav0C7oeOXHFL0AZU5RDQndKiVBCpaCoewe2w9EkL_yOfN_1E4qoSKYm01RVr4kyWqJGBSUopk0iJMOmDeOkEc6Yt9HYsAZ0jFQM-S44zIEDJkwNvU7HhykRWaTIe6HnzWFqyHWLQU6Dr4BDIQIUF-Q7qzbgBOEsJ7qzAc7ECrK8rig7cFObPML7upDcKLOUBWxzPA-rWptIGpaBORB8b62jUbHPwutZ_EF_rokQFzrU1fQZJGsVLBjSYJyELFrl_h3LoFCfoRcE4uaEmbVqjAOPHhgm7lNCOJwUnjohYA9LSQNJ5guIv4gc4B4njxOy-3u--3u5_7r7vNrv73eMvJjjvqIOHvPLBwDHTliTCWVXCoWiWpT2BQEsQfJfdneq0qS4ENHYbFtTL51VUTVsp4XzXzBcNHlIooH_bDyiYh6TU9Az-L_1MPbIhD5zCIZQlM5LMxKUnIasjlDUI6S3Djmr2tMxxQ4-lzsqOrGdZaXWxeNY5WsgEpARi6IL7gU7XoOO5NBnGkrJSGu1qVo7DwOLslPyR0HO4QA6mALUH7wae6V2aD4C-aza4RKWtq06QCPs5qZ4VQC69P3Se2Vkeb6Sjm1bVcz1tbIFX21W0XF6zb3aqvlqF8TJOuH-mOXbze9k2HPrJ1PcTwEmd4NlnnmXmWwmrgE6eZEFdga2bTtQ6UatkJSde-4rWb-yNT_4_PxrvJSa26A1G1PKJ2GIu7Rxe0-LSGR150tpq_ZaMAtPQplPchPjBjAxfVwfb_KYMvnWnMb4EP7qbJ9EynJTrXKWzKE3jlZSRjOfz1Uymi3A-WyUzitUymlQypcqtgzmoiS8v1JgJwlc2snZ-ZakA9n7Kx3e1dv0VPXh-HMy3E72OwzgOcY2GYbiM4mmkQkqvMyDIFjMFO5yF0IiuXhs8seuupLQtHBYrDMe5-xO4ky4M0QhXIZWhCxBPrVX0e8guW9w3dv3nVDRVo9WkI2fdMfMv1Ai-rA">