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

    <tr>
        <th>Summary</th>
        <td>
            [clang-14, C++20] Link error when calling GNU string literal operator template from a function template
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    Minimal code to reproduce error:
```c++
// literal.hpp

#include <array>
#include <iostream>

template<typename Char, Char... chars>
consteval std::array<Char, sizeof...(chars) + 1> operator ""_arr()
{
    return { chars..., '\0' };
}

template <typename T>
void print(T t) {
    std::string s(("abcd"_arr).data());
    std::cout << s << std::endl;
}
```

```c++
// main.cpp

#include <iostream>
#include "string_literal.hpp"

int main() {
 print(7);
    return 0;
}
```
Compiling:
```bash
$ c++ -std=c++20 -o program main.cpp
In file included from main.cpp:2:
./literal.hpp:12:50: warning: string literal operator templates are a GNU extension [-Wgnu-string-literal-operator-template]
consteval std::array<Char, sizeof...(chars) + 1> operator ""_arr()
 ^
1 warning generated.
/usr/bin/ld: /tmp/main-333f4a.o: in function `void print<int>(int)':
main.cpp:(.text._Z5printIiEvT_[_Z5printIiEvT_]+0xc): undefined reference to `std::array<char, (4)+(1)> operator"" _arr<char, (char)97, (char)98, (char)99, (char)100>()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```

More information:
1. Compilation fails with clang 14.0.6, but succeeds with clang 15.0.7 (or gcc 11.3.0).
2. Compilation succeeds if the call to the string literal template is done from a regular function (*not* function template), i.e.:
```c++
// main.cpp

int main() {
 std::string s(("abcd"_arr).data());
    std::cout << s << std::endl;
 return 0;
}
``` 
3. Compliation succeeds if the string literal template is decalred as `constexpr` rather than `consteval`, i.e.
```c++
// literal.hpp
template<typename Char, Char... chars>
constexpr std::array<Char, sizeof...(chars) + 1> operator ""_arr()
{
    return { chars..., '\0' };
}
...
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVkuP2zgS_jX0pWBCIiVLPvjgR3sRYLOnLBbYS4OSyhYnFCmQlLszv35ASvKjuycJcpgZwLBNFotV31cvCufkWSNuSL4j-WEhBt8au7FGt7ioTPNt81lq2QkFtWkQvAGLvTXNUCOgtcYSviXJgSRbskrGT03YLnzGXXYk7AhKerRC0bbvp_1JyqWu1dAgEL4X1opvhD99JJPGeYuiu4njt8euV8Ij4Xv_rUctOoR9Kyxh-_hLKYW6FdZd9WqjnceLUOB8E5zn28nuflZ08nc0J0opYeWozNZA2A5Swp_A9GiFNxYIY4SxZ2EtYSVh68mvYkIOAGDRD1YDKXajF_HOPRBWkHyfEFYAKQ6Ez1wVh4-wwT24L1cgFyMb6K3UnrDyC_jo5L3xKz7nrdRncNHNkjAmqrq5ur6mjfBigsDWV28erqjN4IMfhO_BXf_MUtSN-gDFnBAPEf9elnRCalp_L0Xep8GdmLER6fN9tjF2f5vUPloZ4d7xNRNZvKVgCmHyQ3x70_VSSX1-XxGVcO3sbgYTclhG_g7TkiWwNNBbc7aie8PEJw0nqRAmpA2crLk7w7fsapMSdryHz7dpEOYJ4Vt4EVaPDsKUE9PRW1LPSedAWAQB__rPfwFfPWonjQaS75b_O-thOaovJ_XlrL681mN--GvKDUg-ZUI6w4Mz6qCDDb1m1-AsYccqBP6ogh9A2NF3PWHHQOOSc37KBDVBIjWcBl37CHiV3NUZ38fvJ8LKmC3rUMgz83fhIKykHl89ff5_HjU_yafLl2eS795uHAjbJa91TLotDLrBk9TYgMUTWtR17Lhklbwjr57II6zMoiM7wso03nPjbKQMImcPKuPf9bp4sy7frNeP6zRJRvQT9DHCSowpNY8DUFJ_RQu16TqhGzgJqbCBF-lbwFfpx0mShnsHh7C8BIwOQ3pfTC0C77du-lEP-WxsOHwythtPzyFIKYxVGLejYTfajU5CmtGErgKmavDghrpGbB5P5DShRXDNWDjXNaQp5TQJXXI0wR5NXO-QJ_AtQi2UCnDC_zcldm3n0kFjNI5FLMDieVDC3uVc4HerjSdse9u9VhaLQZEU6c-N3o-a6p-2wb9pZvxMl4VxzccAKPlxAL5HOtZCWWxAuFBSY2d67W242wrfogXfCn2TXYQKpme2f-GV86vPk9fe_oOfJ-HYIxmLZsObNV-LBW7SVZHxNOOcL9pNWaWsYsgZz7MKK5atKyxWGRcsQV5kuJAbljCepCxN87TMOT2lxSnLRZoITIp12ZAswU5IRZW6dNTY80I6N-BmlaRlvlCiQuXi45UxjS8QhQF6fljYTdBZVsPZkSxR0nl3u8VLr-KrNxb-Ms1iTOZZTPID_Fvqr2NTg5cWdaztkFthJP5ofM7F_a58F4NVm9b73sU5EdLmLH07VLQ2XRhO6jL_LHtrfsPaE3aMqBxhx4j6jwAAAP__MXRohw">