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

    <tr>
        <th>Summary</th>
        <td>
            [libc++] `std::to_address()` fails with explcitly-specified template arguments
        </td>
    </tr>

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

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

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

<pre>
    See https://godbolt.org/z/fan4Eddhr for a reproducer.

When `std::to_address()` is invoked in the simple case with explicitly-specified template arguments it fails to compile.

Example code:
```
#include <memory>

struct S { };

int main() {
    S s;

    S* a = std::to_address<S>(&s);
}
```
This conforms to ISO/IEC 14882:2020 (E) 20.10.4/1 [pointer.conversion] and should compile but instead gives the following for clang 17
```
In file included from <source>:1:
In file included from /opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/memory:884:
In file included from /opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/allocate_at_least.h:13:
In file included from /opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/allocator_traits.h:15:
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/pointer_traits.h:118:22: error: implicit instantiation of undefined template 'std::__pointer_traits_element_type<S>'
  118 |     typedef typename __pointer_traits_element_type<pointer>::type    element_type;
      | ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/pointer_traits.h:182:20: note: in instantiation of template class 'std::pointer_traits<S>' requested here
  182 | decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))
      | ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/pointer_traits.h:195:59: note: during template argument deduction for class template partial specialization '_HasToAddress<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer &>()))>' [with _Pointer = S]
  195 |   static const bool value = _HasArrow<_Pointer>::value || _HasToAddress<_Pointer>::value;
      | ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/pointer_traits.h:195:59: note: in instantiation of template class 'std::_HasToAddress<S>' requested here
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__type_traits/conjunction.h:27:32: note: in instantiation of template class 'std::_IsFancyPointer<S>' requested here
   27 | __expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int);
      | ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__type_traits/conjunction.h:38:39: note: while substituting explicitly-specified template arguments into function template '__and_helper' 
   38 | using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0));
      | ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/pointer_traits.h:200:5: note: in instantiation of template type alias '_And' requested here
  200 |     _And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value
      | ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/pointer_traits.h:204:1: note: in instantiation of default argument for '__to_address<S>' required here
  204 | __to_address(const _Pointer& __p) _NOEXCEPT {
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  205 |     return __to_address_helper<_Pointer>::__call(__p);
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  206 | }
      | ~
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/pointer_traits.h:235:59: note: while substituting deduced template arguments into function template '__to_address' [with _Pointer = S, $1 = (no value)]
  235 | auto to_address(const _Pointer& __p) noexcept -> decltype(std::__to_address(__p)) {
      | ^
<source>:8:12: note: while substituting explicitly-specified template arguments into function template 'to_address' 
    8 |     S* a = std::to_address<S>(&s);
      | ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/pointer_traits.h:38:8: note: template is declared here
   38 | struct __pointer_traits_element_type;
      |        ^
1 error generated.
Compiler returned: 1
```
Similarly for GCC 12.

It looks like perhaps the declarations need to be refined with some SFINAE.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWF2P27oR_TX0y2AFiZIs-cEPXn_cLlAkATZF-ybQ4tjmDU2qJLXJ3of-9oKUVrZsJ5u09ya7MOLYpoYzZ86cGZJZK_YKcU7ye5KvJqx1B23mW4P7I5tsNX-ePyLCwbnGknRB6IbQzV7zrZYu0mZP6OYPQjc7prI15wcDO22AgcHGaN7WaCISr0i86P795wEVkGlsHffG0oXTFePcoLWEloTOyDQGYUGoJ_0JOQgF7oBgxbGRCDWzCJ-FOwB-aaSohZPPd7bBWuwEcnB4bCRzCMzs2yMqZ0E42DEhLTgNtT42QuLIn_UX1lnWHL1D3U_TuH91H2kqVC1bjkDS5RGP2jyTdH1uxjrT1g4egRT3QIoVSe_PfxbKwZEJ1YXoF3XfAwA8gr1YHb4ldAEMSLqCW1Cly0fvgTc3tR61wUKxuhnDx4OwUGu10-YYwHh4fE_o5mG9hCQrS0rSBY1pDISWa-8ijaMkjjJCNwmQ_L7RQjk0Ua3VExortCL5CpjiYA-6lfwFW9i2DoSyDhmHvXhCG9K301Lqz0LtAzlqydQekuKmow8Kdt5QjziHndFHj7vVranRR50ukiFVX1lON7pxhG56t8yd54s2aPx3fvu7pIjiKCF0s_Vp2UQRoZveiF9D6H14bZ78mpecL8oy-8lbV1W_Od0wKXXNHFbMVRKZddHBY5H-co-0qZxhwtnOofxUSH_d1j0jRxsnpaex5zKgMdr4_3jh8EIRWMmUE8wJrUDvoFUcd0Kd6wahxVBtVTXeokKJXlMq99zgUIDFS8kmSQmkWPraBb-C4y68K3ZEeM1W_2tHbl_pzw16Q-NlZ6IBYS-Sr38Jzr1ceHiVdhhgVtcAD7DWklk7Ands9YQmGPx3i9YhhwMaHMAtaQiYYy0DFl74yictOKGzK1vVh0s4z3vM4IM39sQkSZe1VtbB8BidvmjrrH-9EdxnvrLy2TnuvDVeVq86H3DkbR0y0UuutadVDTNOMAmhdTIp_uhyRmhR_Y3Zj3oxtJkTKD8JfbgBf0cNkt-H1n9ama7gkeSrgSWzvC9B65gTNXSWt1pLeGKyxfCEj3BhjP58y9d-WbH0dr6KxWj1G6rLG_z4wbq8DPlbZfnnB-fJ9UIkb1b93qrA4RAeLUi6SOn_E92D3TBVPw95fEV2wLPOE6HCLw1TvHK6csanfFlVqNhWYiV2lQvcMMhHrFhHUUTSNVSVf_KAsvHAlEK583ntp5Dm27imvmumI9Z8PvgxwrZb64RrnVeY7x64ldOw6-2POusYiAIGANKuc7bW71MtFIfq7w_3yw8fqnfvV-v7f_wW6vZMfc569JnJPgkd7ISW8Yt6vJX6pLFvmfl3EzhMAUwKFljsgfk6VWkcD-NHWJkuha1CCVwoF13CdR2cLYALeXsr2GX93P9N7DjuWCvdqQ365he4d-Pw1GEpzBWUWV_1o851NST4qc4flap379f_Wq4_fByf6wa4_vMDfycf8iGdBl1r1Midc8pf9KSqqpmUhJaddzfY_yP-XHo17YIqVldGfwkp0uuGd0O6wij042p1nv2vTh90CYRmSfhEaKl0N2l45E-DCU27bLLWafg-UimNX2psHNz5krytfSNLfbovbxcui3Z8jvbKn9C_XPkvkBycO52Y_tfrjl-uS6F5lucIDoELG_LGLvXlpd_1d0avnA2vAu3_hniT7qwLe1RomEPe328t-_B7_QjTCSQ371wexVFIZuRzkMvflktI6OiW7MGB1PqTBSk-ITRoDqzpbna6CIP-WlDomaFhi2D6o3WoGauPCI-bh3eLdTTh85TP0hmb4DyZzvIiy7IsnxzmOzbdbfM05ZyzupjGaRxvMzpFnKUJz_JyIuY0pmk8o9NkGhc0iWZlTUtap_k051maMpLFeGRCRlI-HSNt9hNhbYvzaZFls4lkW5Q23HJSKsV2SDMl-Wpi5v6hu227tySLpbDOnsw44WS4Hz17LF-9eo3ZXTwO15Wvl9CkNXJ-cdEq3KHdRrU-ErrxDvVvd43Rv2PteR6C9INdiPO_AQAA__9P78wY">