<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/60709>60709</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Memory leak in std::string comparison after libc++ aaef3b82f4f0
        </td>
    </tr>

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

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

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

<pre>
    It's mysterious, but bisection clearly points to aaef3b82f4f0. Here is a reduced reproducer:

```
$ cat /tmp/a.cc
#include <memory>
#include <string>

struct S {
  std::string ToString() { return std::string(data, sizeof(data)); }
  void inc() { data[0]++; }
  char data[40] = {'a'};
};

int main() {
  std::unique_ptr<S> s = std::make_unique<S>();
  for (; s->ToString() < "foo"; s->inc()) {
 }
  return 0;
}

$ build2/bin/clang++ -g -fsanitize=address -stdlib=libc++ /tmp/a.cc -std=c++20
$ ASAN_OPTIONS="detect_leaks=1" ASAN_SYMBOLIZER_PATH=build2/bin/llvm-symbolizer LD_LIBRARY_PATH=build2/lib/x86_64-unknown-linux-gnu ./a.out

=================================================================
==245534==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 48 byte(s) in 1 object(s) allocated from:
    #0 0x5622d7ad056d in operator new(unsigned long) /work/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:95:3
 #1 0x7f6f1fe6ffa1 in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::__init(char const*, unsigned long) (build2/lib/x86_64-unknown-linux-gnu/libc++.so.1+0x5afa1)
 #2 0x5622d7ad3494 in S::ToString() /tmp/a.cc:5:35
    #3 0x5622d7ad2c5f in main /tmp/a.cc:12:13
    #4 0x7f6f1faea189 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

SUMMARY: AddressSanitizer: 48 byte(s) leaked in 1 allocation(s).
```

Dropping the `-std=c++20` flag makes the leak go away. 

The diff below also makes it go away.

```
diff --git a/libcxx/include/__compare/ordering.h b/libcxx/include/__compare/ordering.h
index 572a15cf3485..1d02bc570d9f 100644
--- a/libcxx/include/__compare/ordering.h
+++ b/libcxx/include/__compare/ordering.h
@@ -40,7 +40,7 @@ template<class _Tp, class... _Args>
 inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
 
 struct _CmpUnspecifiedParam {
- _LIBCPP_HIDE_FROM_ABI consteval
+  _LIBCPP_HIDE_FROM_ABI constexpr
 _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
 
 template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUV0lv4zoS_jX0pWBBIiXLPvjgJUYH6LwEcd6h50JQFGVzQpEakkrs_PoBJXlLgsb03B4gSDT5VbH2KjPn5E4LMUfZEmXrEWv93tj5R21KUY8KUx7n9x7h3EF9dF5YaVqH8AqK1kMhneBeGg1cCWbVERojtXfgDTAmKlJMcZVWcQQ_hBUgHTCwomy5KMGKxpqwtIgsULxG8ek9iYen_4lT4MwDwhtfNwhvWMT56YhIzVVbCkBkVYva2CMid98dOm-l3l0Ou7fztuUetoDyZb8D4HwZ5CGLngJezLYnxVOEZwEJVvjW6s9IhKcl8yyYxskPYarzxiw8ZAkoX59ueTOyBKn5FdcOmy1jlK0RXobnloTvmT2B0oACRNad5DhnCOcBSgY1btbdW2oPNZP6cuEXhVst_9MK2niLyGqLyB247oozoGavgvaoAdFzO18FUBkLYZMswY0RuftsPbIChHFlDML4DDrb4VayK90Hi8c3Cl6HDE6haKUqMcKbImi54YqFa4MhYbyDceWYll5-CETWrCytcA7GzpdKFoislSz4AL6Jsw6CyHo4xFcxudgu_qKPTy_3j39tEVkjjEvhBfdUCfbqEFknCOMetf31sHz8ef-vu2f6tHj5gcj6k7BKvdVjd6wLo-SHsPBzTX_eL58Xz7--EAR58eYwndBJOm71qzbveqykbg_jnW4h6gQ3rb8xD1n_458rRXCaZSTt13fPz4_PiCzgp2Cv28HFoaJA7w1RQl8XoHfLlVXW0gruu30wFaRTKI5eIDx1IQ6lhgRM8W_B_WmLKWU4Cywra-pz1QIAQJjEEB-yCcZlzso4m4T0BtMIy7yxoMU7wtNWd6W2BGVCbM5CrL0b-3qKgMaa_r4NN3UjlbBj688-Z47p4UO1eKelUMKLiDcNIotZhsiCnDIHkwTiQ15NqqQSk6piSZDmnMiUJv2iYE5yeqqNq1Biuvr1BRhOqLdMenfChez_DjpYydgrYHh6kNQy2LMrZtxo5xFeBD7fmGb6P8Z8DxgyNHImShBexoeMVSwJReVsE3zlIZLO0mCTbS_Y5zp102vIojNuduNucsUM86wKzEKB_UKb4PAiN8Tp2TtMsGTaRRulQQvqPLOecqYU7dhxFxSMQl67oytF4xDe6MarQe3PBNE-yDsNd06uo33798PD4vlXyIxFX_5usuVT9IekEGWfBINDpdHDafR9n-6TypqmCX3T7wWgSfylfk5iqBTbQWgmrkN1CbgzwN7ZMYJrZi97AaWsKiiEMu_AlDMDnfRnit-MDh3teLyTHthgrsMB4c0wFyC8oTRkGrNhbWwpQgxEeyj-BH1qsKU4QJZjlmS8Iuk0i6KkjHHBszwuZxUkcTxJ0x48Ho__TKJT21kOTer_EBClMUpjGKcxwqscEF6eVv2BF3WjmA-tnSvmHNCXJmRm9yOKIqALu3PnCQqkVlKLPonFobFQGKOAUqMFNRV968cTPJWOOlYL-obIamB54gQoX6F8BVEI76sxYvgM4xld1c3f2jWCy0qK8olZVl_GhDGEVrl6eqI_7td3dPP8-EAXy_tBrjemzqaD3yIPjR2u_e6-oIf-XpS-gHRlbAbaiAMXje_kO88vw-e3Fu7MJTQrlKCyoh6RFcLJxZwX60ntw6dh1kum6MnPYe9dsNebDeet0bvL1lCL7z6ly6ick3JGZmwk5skkn5A4Icl0tJ9XCS94mYp0lpJZVeVJnrO4KkjGsoxXk2Qk5zjGJMYJSbIkS6YR53FelbNpnJecJ5yhNBY1kyoKHS4ydjeSzrViPonzeDZSrBDKdX89ML5U8TAdZuuRnXdtsWh3DqWxks67CxsvvRLzh0tzv2lxw_Tep4N0RgOrvLBwNehd_0EZtVbN9943rvPlBuHNTvp9W0Tc1EN7_tqlO01CPe6U-W8AAAD__31q3lA">