<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/139052>139052</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Clang Crash When Defining operator<< as a Friend Template Function of a Class Template since clang 20
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mariete1223
</td>
</tr>
</table>
<pre>
Clang crashes during instantiation of a friend function template declared outside the class when used with BinaryTree<T>. The crash occurs in the function InstantiateFunctionDefinition in clang 20. **Haven“t been able to reduce code more**
## Assertion
```
clang++: /root/llvm-project/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:5767: void clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl*, bool, bool, bool): Assertion `It != Primary->redecls().end() && "Should't get here without a definition"' failed.`
```
## Stack dump
```
Stack dump:
0. Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -gdwarf-4 -g -o /app/output.s -mllvm --x86-asm-syntax=intel -fno-verbose-asm -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -x c++ <source>
1. <eof> parser at end of file
2. <source>:19:26: instantiating function definition 'operator<<<int>'
#0 0x0000000003f7c0a8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f7c0a8)
#1 0x0000000003f79d34 llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f79d34)
#2 0x0000000003ebebf8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#3 0x0000790a8e642520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#4 0x0000790a8e6969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
#5 0x0000790a8e642476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
#6 0x0000790a8e6287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
#7 0x0000790a8e62871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
#8 0x0000790a8e639e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#9 0x0000000007244186 clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7244186)
#10 0x0000000007241b46 clang::Sema::PerformPendingInstantiations(bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7241b46)
#11 0x0000000006790242 clang::Sema::ActOnEndOfTranslationUnitFragment(clang::TUFragmentKind) (.part.0) Sema.cpp:0:0
#12 0x0000000006790ae2 clang::Sema::ActOnEndOfTranslationUnit() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6790ae2)
#13 0x00000000065fe6eb clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x65fe6eb)
#14 0x00000000065f09ea clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x65f09ea)
#15 0x000000000491ebe8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x491ebe8)
#16 0x0000000004c11f15 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4c11f15)
#17 0x0000000004b9131e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b9131e)
#18 0x0000000004d05d39 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4d05d39)
#19 0x0000000000da788f cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xda788f)
#20 0x0000000000d9da5a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#21 0x00000000049854a9 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#22 0x0000000003ebf094 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3ebf094)
#23 0x0000000004985abf clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#24 0x0000000004947f0d clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4947f0d)
#25 0x0000000004948f9e clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4948f9e)
#26 0x0000000004950df5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4950df5)
#27 0x0000000000da37f8 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xda37f8)
#28 0x0000000000c28b74 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc28b74)
#29 0x0000790a8e629d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#30 0x0000790a8e629e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#31 0x0000000000d9d505 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xd9d505)
```
## Program
```
#include <iostream>
#include <memory>
template <typename T>
class BinaryTree;
template <typename T>
std::ostream& operator<<(std::ostream& os, BinaryTree<T>& b);
template <typename T>
struct Node {
Node(T data) : data(data) {}
T data;
};
template <typename T>
struct BinaryTree {
std::unique_ptr<Node<T>> root;
BinaryTree() = default;
BinaryTree(T data) {
root = std::make_unique<Node<T>>(data);
}
friend std::ostream& operator<< <T>(std::ostream& os, BinaryTree& b) {
return (b.root)? os << b.root->data : os << "<empty tree>";
}
};
int main() {
BinaryTree<int> a(1);
std::cout << a << std::endl;
}
```
## To quickly reproduce
it happens since clang 20
https://gcc.godbolt.org/z/WWWqdcbjj
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzkWktv4zgS_jXMhZAhUbIehxwcJ57p2dntYOLZPhqUWLI5TZFqkkon--sXpGRLch7TAZLGAhu4EYePqq--KhaLZFNj-F4CXKLlFVpeX9DOHpS-bKjmYCEiJL4oFXu8XAsq97jS1BzAYNZpLveYS2OptJxariRWNaa41hwkw3UnK99ooWkFtYAZVIJqYFh11nAG2B4AV4Iag78fQOLOAMPfuT3gKy6pftxqABSvtyi-WeCtG-t0Y1VVnTaYSz__pObTCQlshrZrqLnkvpdLp0nuMQkXGJEVIqtf6T1ItCboKrG4BJCYlgKwVVgD6yrAlWKAG6WhH49C_yExIjFeGQPaSx6a03D4hCuvCJEr94lXGJGNVsoishHivglarf6C6vgnIhurlDCIbIZpG8FLRDZ30NDh13YgcGLhNVRiUbUtilfLLM2cmnvFWW8jilcoXnkB_turzCCSTyepTlfwu6po37eeShwnV8JTssalUuLp78LhmTCUhp8sRiRC8TW-1byh-jFA8Y0GFxEGkRyRYgGS9d8wIikiKUaE3B1UJxgimcV7sPgAGnyAqM5iitnECIJIhmvKBbBF74WpR0a_3VlafcWsa9qnfpv0xa4vXKCwuNVqr2mDqd53DUhrBpeq1rmwUk3LBegAHlqhNOijHwN6NN8EVnfyKyKbksvRzS46cLBn36mugwQHexwoJ5e2rZPe2bazC4ODxkUJDoKHPA2oaQLzKC19QPE1lxYEDmqpgnvQpTLg-nFwh4NgX1WBC6vqQLlE8fWreN1gI2lrDsrioK6UUDpgnO6lMpZXptfh1968-QFXgx0oXhsfOSi-QeEqcsSheA2qRvENbqk2oDG12OUFVeOaC0DhigzDxqnxKnKxQ1JH8iS1yP24zkevY0Qy1YKmVmkUr_sPl9ZJIhkKnZ_iEIcP4fEnrrMqpDn2K8_HtHk0_ZdbzaX1EbDVtAJE8nGQpt93ylgNtPGxucZOi4_U_J1CAZGr8GGA5xZQDz46A1-wOHkO_FoAlV37Wd7xvaQCkbyTPqkzLJRT8RFQHZgRKplBhRLKOsdrFzR_QKXuQT_22H6lkgmnMR84nI1ZK2nhwQ6pLfT_evnxID8rQppDmpAlCQej-oT5kKe7NAkEl91DsJdd31EtjFqkHrKfMgJO5gKLtKgr3NqDBsp2X7kQb5Pu54_Sl-dwkyzFe-MpeCvsJEtHwelcMMmzOsa0VNq-TayfOIrNnoiNyjcLjMpRYD4XGBdQpG8T6KeMAotpgGUkSaI8_V_Z7957dQ3m9ca7PBCeGR-VyQvG34KulW5uQTIu95-m5ZnbaT8euIM2Ap9lsDQrQpKQ54GvKvtZ3kj2ud5qKo3wkP-U3G403budd-657Z_H9n9wVzl4UxYt1XbhFjl2gs_SiMNDzvFQeCueU5XyrswNWEbm4hnSZQ0plFOkt35XnXzfqvZ3uAfRh-uUq88t_dbBrXW75KTZDfxFq679A2q_Z6ZnC2Ak45-KdQI-Na3SbpO04Ae_Pwm9mSMJyRkJYQH0CQmru-3Zqva1c_oTFuoAaQS8nAJOighKyKeA14rBLyBXPrH0TTcPUHUWhqYPCa4ByAgzncGsoqiOlrPUp91GLNkzOD8IYY9hRJjNEJZFFEcwJ7LX2Wc4Vz4-x-XLJn1I_A44RyvymRUsXLK4mFox4B2NuT9tRflrxrrd6P3R9_hG9LMtN2Q0y_MaV1W0a9yxYlohr7Smjz6NrKsD1bhS0liH0qWVNZ63kbU_rH6MET3Kkw0knNtQMLqk-Ej7Otr6vDCx5K6hQvwbKqv0p6YVzxrkM8s4xckYCtfjOB9cTPN70E83IRLNk0S-TGjRn99Hocfzzk57Vn1vv_T6gxKKVxUVoqTV110t54m9VzyEzjpaq6ahkp2v4me9Z-wwTrVOO3UETMixmsv9sF30rj1N2O2qh4co6v8oqeHVzvjhA4Wzwa5hZzXl7jzdd5-Jo0K4peBPdsd-N2RShvnw6Qn3UxDJBG1KRt3p70QVyY9HoN9U-Ywzzg8udVhMz1jPHU_6nj86eUdrEI8zLl_32wccxHrEY8DH58FFyxr_PwfHWWH4fBQkc9aSrA7Zi6x5r9EnO-ORylnqPpvoBkySxPoVHdOhq1k5MzHsfasEb_YYSmfFTJLXBbyVlN9UaV5m5DdV_s6NnTHyWi4-RUBLuR5ue95A4hAmP4VKR9ZI5bzgKpYhq5cvwb6efJ8VCM9UBi-54CdS-QHVqqdnJC87q0PirB6K6mMlcgTvU8lqSAR_v0O_e-3hkI24Z9VfWJG8zBLsEL-34l70qLg4u80pWPHGyzI_5STwdIt6EghJiHc7N2dnLNV2NzHrh1VAMlERnRdqy3CJe-Hv7icvfFD97DPB8db_6SMBIjGXlegYYLdojtfC_t573tdAo_Rj33N6A0Px2j62IGkDeNv39S9g0yevq7-ZMe7Dp0tpfHYRTvJnBxm3Lp68rrkuf-j-Ac26qyz-l3ImZm40xtj_iUi-xYxa6tdVvBq-56em7Apl18OEYaRX51p_VO-IfKL9ZGgn-bcOdq2_5_CYBvPiG-xf4OLjlAkDw2k2vsYMatqJl0ZNjDtpdj9OsJ9-gtHQr7DrsTzBMRIyqhlpGV5O_969-OS4H3Pz4N9z6GA77RdtuehfKAsUb7AyeNDSNwcovnGgvVfHTkQIitfQtPYRWx9LN75pbtbJu1xaPCTrOZJZNPavN9gFTjQjaSwOVWePEOjxy6kXJBNjWL20urcKf-t49VU8Yg2tVqyroB_ALT7QtgVpsOGygtOjcd99sLb1Ty5k0z-cLfaKlUrYhdJ7RDb_QWTz5cuXb6wq__rrgl3GrIgLegGXUZakabHMkvjicJlmRZQxqMsQlhBnJCvqDFiVZnlYMErhgl-SkCzDZZiHRbRM4kVUk5hFjJGirktaZygJoaFcLNwW53RfcGM6uIziIlySC0FLEMa_5xMyJD-CltcX-tI_QZfd3qAkFNxYM4qw3AoYXvn9qQd_OYDE_dW53J-HIDWY4k0fsccXany8Mu__J8DaZ7ZT55zRi06LyzNCuT105aJSzfg6fvZm7u00iGwGU-8vyX8DAAD__2kc8Hg">