<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Clang produces an incomplete comdat"
   href="https://bugs.llvm.org/show_bug.cgi?id=47747">47747</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Clang produces an incomplete comdat
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>rafael@espindo.la
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Given

common.hh:
-------------------------
struct zed {
    zed() noexcept;
};
template <typename T>
thread_local zed var;
-------------------------

test1.cc:
-------------------------
#include "common.hh"
inline void* foobaz() {
    return &var<int>;
}
-------------------------

test2.cc:
-------------------------
#include "common.hh"
void* foobar() {
    return &var<int>;
}
-------------------------

Compile with just

$ clang++ -c test1.cc -o test1.o
$ clang++ -c test2.cc -o test2.o

$ readelf -gsW test2.o

....
COMDAT group section [    7] `.group' [_Z3varIiE] contains 4 sections:
   [Index]    Name
   [    8]   .text.startup
   [    9]   .rela.text.startup
   [   10]   .tbss._Z3varIiE
   [   11]   .tbss._ZGV3varIiE
...
    10: 0000000000000000    56 FUNC    WEAK   DEFAULT    8 _ZTH3varIiE


So the symbol _ZTH3varIiE is in a section that is in the _Z3varIiE
comdat.

But in the other file:

$ readelf -gsW test1.o

COMDAT group section [    3] `.group' [_Z3varIiE] contains 4 sections:
   [Index]    Name
   [    4]   .text.startup
   [    5]   .rela.text.startup
   [    6]   .tbss._Z3varIiE
   [    7]   .tbss._ZGV3varIiE

We have the same comdat, but the symbol _ZTH3varIiE is missing. This
means that if the two files are linked, _ZTH3varIiE can be resolved to
0.

GCC correctly outputs _ZTH3varIiE in both files.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>