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

    <tr>
        <th>Summary</th>
        <td>
            Static variable inside inline function emitted in a different section group than the function
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:codegen
      </td>
    </tr>

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

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

<pre>
    We ran into an interesting crash when upgrading from C++17 to C++20. We had an inline function being compiled into some object files built with C++17 and some built with C++20. This inline function has a `static const std::string` variable, which becomes constexpr in C++20. A simplified version is as follows (the `[[clang::nodestroy]]` generates shorter code but the issue also exists without it):

```
inline const std::string &get() {
 [[clang::no_destroy]] static const std::string empty;
    return empty;
}
```

The generated code for C++17 and C++20 can be seen in https://godbolt.org/z/evo95T1dj. In C++17, the string object is zero-initialized at runtime, so the object is stored in writable memory. (It's stored in `.bss`, so I don't know why the runtime zero-initialization is necessary, but I digress.) In C++20, the string object is stored as a bunch of zero bytes in the read-only section `.rodata` and not initialized at runtime.

The crash arose because the linker ended up picking `get` from a C++17 object but `get::empty` from a C++20 object. This meant that `get`'s runtime initialization was trying to write to read-only memory, which of course segfaulted. I haven't dug into how this particular linker selection ended up occurring (it was in an LTO build, which might have complicated things), but as far as I understand, since Clang is emitting `get` and `get::empty` in different COMDAT section groups, it's valid for the linker to mix and match them like this. On the other hand, if Clang had emitted `get::empty` in the same section group as `get`, the linker would have had to pick or discard both of them as a unit, so the bad mixing couldn't have occurred. Is this understanding correct, and if so, what's the reason for Clang using two different section groups here?

CC @rnk and @MaskRay 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJx8Vltv4zwO_TXKC9HAUdpcHvLQCwIU2A8D7BaYx4Vs0TanshSIdDOZX7-Q5DTpZRYI4qaWyMNzDikZZuo84k7dPai7p5kZpQ9xxwOiNzSrgz3tfiJE44G8BChPjMhCvoMmGu7h2KOH8dBFY9M_2xgGeFT6QemHxRoknH_oag4_EXpjSxxHHqEdfSMUPNSYI4bhQA5tScdhQAj1L2wEWnLIUI_kBI4k_VUK421Z-vVtyvnSE39J1xsGA2pVsRihBprgWYDFquW9Wt6zRPKdWlXwZiKZ2qHSj3DsqemhxiYMyGUL_j5EIH-d7x6YhoOjltDCG0ZO-YjBMLTBuXBkUHojPab0mfiHxhnflcw-WGSJ4aTuntJnVUGHHqMRZOA-RMEITbCpWoEUhZhHBOM4AP4mFs4MhFGAROltCls9qer8vaqmT_458fJt-aD0qkNReqP0FtT6oWyBbzD_9wNo-H-kAg4HOanlORoARJQx-k8v1PrpW8Tl-6XHd15s4aMN8ZMp3kWBxiSHASMm50EvcuAESu-V3nfB1sHJPMRO6f0fpff4FrZ3Lwv7aw7P_hI0eSAxPhUyOZMY_mAMN-RJyDj6gxaMQBy90JB9wyFvu6xnCTGbHI6RJNkLBhxCPM2TNZ5F6fX1IrWq5jVzoqBEewYbvNJrgVcfjnDsTznBlPITHCOTAT02yGziKUVJ7nkGS11E5nkS-PnKxX-tdAKVu6cefdNDaHM-qE_JoeQLEjT2Jnh3AsbScKmGGKwRkyyd1PFB4HvO5p-VLoPGxMCY2s-MjDmNI_-KEdBbtDAe4EDNazbuqkrGXVVlGpkrX0ylpPKnVdmbxXtfNuhq2jCNkQGNT11n5JIji3Wm_hPrR8Mg8ZQwSchiY_rjQk-R_TJcQgtNGCMnr3atGZ2gncMz9OYNi-J27Mp07MMRJIE6mCjUjM7EMyGMbqL9nZrQNGOcunpDkpGRT5P4Xy8_8uS0FxQDdb3knHkiO2pym0lPvuM0UyYDpZFmYno8w-gtRhbjcxwm3yA8phmRbIMDiXxUJlngWwXIg6W2xYhe4PHHP0_3L-8u6mIYD5wSUGmSN-PI5ta_8oMEGOh3zjAYafr0bgBHr5gJm8OP4tIgPUboJ8jUTnjTCZUB498R5uYwA35Elpi48sXjNahjGJ0tnKYEErJbIUSwxI2JFuog2QAZbe6w0acy3wdIbWwqrByUo7PFEDlkkTd7hYsrLnqU9TFik4MlWqgFDkVvU4icupaDL4M0MzFydu4xXCnyUQroMaJa7q879vER1G0V_WvR-Lb6x_Drv80JZna3tNvl1sxwt1hXVbW8Wy_1rN-tUK-MWWC7qc12vd3ojV1tsdKmWpstrlYz2ulKLxeLxV21qTZ3el4t22WFq4XGZtlUbaNuKxwMublzb0Oa5LN8LO7WerlazJyp0XG-5Wh9PrjSodGlptLp6hN3aedNPXasbiuXztFLLCFxuPtPOdXONwIgz2Txy9XibJ3UXX_jLY2QYqLzttkY3e7TuUTSj_W8CYPS-4RletwcYviVxdznIlnpfa7zfwEAAP__-I9Aiw">