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

    <tr>
        <th>Summary</th>
        <td>
            Stack overflow due to thread_local variable re-initialization
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

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

<pre>
    The following program, when compiled with Clang, produces an executable that, when run, results in a stack overflow due to recursive re-initialization of a variable with thread local storage duration. This reproduces with Clang 16 trunk back to at least Clang 13. I've only tested on x86_64 Linux.

The problem appears to be that the initialization of the `tlsdm thread local variable causes an invocation of the `ct<T>::mc` constructor; the constructor then calls `ct<T>::smf()` which references `tlsdm`; the reference triggers a check to see if the variable has been initialized; the variable is found to have not yet been initialized (presumably because construction is not yet complete); the constructor is invoked again, and the cycle repeats.

The problem only appears to occur when templates are involved.

I would not be surprised to learn that the program exhibits undefined-behavior according to the C++ standard, but I wasn't able to identify wording that lead me a conclusive answer.

```
$ cat t.cpp
template<typename T>
struct ct {
  struct mc {
    mc() { ct<T>::smf(); }
    void mf() const {}
  };
  thread_local static mc tlsdm;
  static void smf() { tlsdm.mf(); }
};
template<typename T>
thread_local typename ct<T>::mc ct<T>::tlsdm;
int main() {
  ct<int>::smf();
}

$ clang --version
clang version 16.0.0 (https://github.com/tahonermann/llvm-project.git 6073e0a2f7018fb01283f48e946a45aff5512eae)
Target: x86_64-unknown-linux-gnu
Thread model: posix
...

$ clang t.cpp -g -o t

$ ./t
Segmentation fault (core dumped)

$ gdb ./t
...
(gdb) break 'ct<int>::smf'
...
(gdb) run
... (several break and continue cycles) ...
Breakpoint 1, 0x0000555555554674 in ct<int>::smf() ()
(gdb) bt
#0  0x0000555555554674 in ct<int>::smf() ()
#1  0x00005555555546a1 in ct<int>::mc::mc() ()
#2  0x0000555555554559 in TLS init function for ct<int>::tlsdm ()
#3  0x00005555555546b9 in TLS wrapper function for ct<int>::tlsdm ()
#4  0x0000555555554679 in ct<int>::smf() ()
#5  0x00005555555546a1 in ct<int>::mc::mc() ()
#6  0x0000555555554559 in TLS init function for ct<int>::tlsdm ()
#7  0x00005555555546b9 in TLS wrapper function for ct<int>::tlsdm ()
#8  0x0000555555554679 in ct<int>::smf() ()
#9  0x00005555555546a1 in ct<int>::mc::mc() ()
#10 0x0000555555554559 in TLS init function for ct<int>::tlsdm ()
#11 0x00005555555546b9 in TLS wrapper function for ct<int>::tlsdm ()
#12 0x0000555555554679 in ct<int>::smf() ()
#13 0x00005555555546a1 in ct<int>::mc::mc() ()
#14 0x0000555555554559 in TLS init function for ct<int>::tlsdm ()
#15 0x00005555555546b9 in TLS wrapper function for ct<int>::tlsdm ()
#16 0x0000555555554679 in ct<int>::smf() ()
#17 0x00005555555546a1 in ct<int>::mc::mc() ()
#18 0x0000555555554559 in TLS init function for ct<int>::tlsdm ()
#19 0x00005555555546b9 in TLS wrapper function for ct<int>::tlsdm ()
#20 0x0000555555554679 in ct<int>::smf() ()
#21 0x0000555555554669 in main ()
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy1V01vozoU_TVkYwXxDVlkMe28SiPNrt2PDFzAr8ZGtkma9-vftQkkadKRZtpEKAm-9vG5534YSlkfti8dkEZyLvdMtGRQslW096JHsu9AkEr2A-NQkz0zHXnkVLTWhtPqsQJNqCDwBtVoaMmBmI6aZakahf2vQI_caMIEoUQbWr0SuQPV4IakHnGNxCnVqDTbAf5bM8EMo5z9Rw2TgsgGl-2oYm4Dx8J0CmhNuKwoR0SpaAsIpdwCn7x0TCPQQvHEnIQZMUjrlZSWBu5MDeFAtZntsU9-eFGOTKTgB2JAG_QdabwV2a8sIT-ZGN98L_juBd-mbysfboXkekKHAajSFricxMAvINce2VEvCwzXdX_pzuJpRUc96cvEDk3vllbGix9fvPgfL_6GV1_hGAZLaPSvQkm8-MFNPRuy9xhQyrm-gaD7xosKL9pYoH3Hqg41bECBsBrOZPF3Rl6sKClrW0C_Kak6mITVgH5PbBeXOqpRFxAnQaCe0ZZJGLtGjqK2IB3FQAhpyAHM1UqCdAebXD2uO6DZKXZy2OqFYPNym8gcDFgPb2jDtNP5FXFpS5nLXGpZ2HmHilt_MbhGfxh8lzBnGSArTOqpEgzg3tTYcCpw-_Ad1BdIP8hejrx2dDF39KgGxTQ4GTBDlTil07FEse46VjKsLFQLGiagXpeAkjF0h1aVVLUtaFxvFz160QNetgBFTVVt_StHQ3BfqtHb3JCpgiVhNQjDmgMyOkJ0U5nUpAcbYykqPrpypULvQV04YjNkuqbbKMGUQ-J-NQzT0KwGpp85DCAooro8dNYpIgQvL3-Yhgg5DvbV-SDB-yll7Sj5MJ8x2l7-_bRqJxl6crROSeBgT3Ps33jZZ6rPX3O7wUqsLJOpHuIzjs7i0JfNHTM307_J53yn3-tywWKxX7WB9yOXLJlAEV12z-Rm9m4Zmm_qd-J6HmgbWdc112vs5xrrbTJMg8chbLl-4Ae2WDtjBm3Boye8WuzKY-ljWeKNoZ0UoHoqkNoT57t-jVn-L1TGx3kkC_IYAho1eRAWTRmEURE3SQGbJKNJSpsmTcMIqKvtqS6pagF9-Xbs22vs-ULuxZrb_r1uxTjXr2u9vayB29mD1OxtMvm-f9tbl8lkjW5jZb2f4ltnpttnaHsspKlxNxTPQCsClqU9q_oBW9_M9rS8rctziBOHqECTDVmJhF8RKL8dsPzDhfY0nm2WiAaMEKbSBGhbHVaCQXmO_U7bRQvOg501SJs_oW0dwVuAn_T4SbI8sef7x0lEjrn03ptZwCgOyGdB4_AagoY3IbBxzL83kaIrpDTdWKSXn8_uDCLNKKYjpsFue4U_HezvQONreuUCulf26FB_g5vcUG7zZ8qlX6Zcdg_l8jspV3xeuc2XKRcGd1AuDO-jXBh9Wrkw_jLlknsol95JuezzyuVfplxxD-U291EuuiqQP1Yuui6HzEHYh6LLyfNj7Aq2YZbFWbgJkmxVb-N6E2_oyjDDYft883X24lFtebG5erVdjYpvf_NQZB-D3j0N4S3TerSH81OaF1Gx6rZhkVVpUzchUswgDct0E1RJFVCssKTImxWnJXC99dIHL_2-YtsoiKJgE27wNwkyv4AirKImjcI6brKKekkAKAf37ca-VO1KbR2Hcmw1GjnT-Ba0GKnWrBUAMz4dTSfV9uyJbuUobx3f_wGxIMvm">