<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 - std::type_index equality broken across shared library boundaries on Linux"
   href="https://bugs.llvm.org/show_bug.cgi?id=33542">33542</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::type_index equality broken across shared library boundaries on Linux
          </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>wenzel.jakob@epfl.ch
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Dear all,

I'm consistently running into issues where Clang does not preserve
std::type_index equality across shared library boundaries.

I've created a minimal failing example (<a href="https://github.com/wjakob/clang_issue">https://github.com/wjakob/clang_issue</a>)
with the following structure:

1. A shared library "shared.so" exports a simple type named "Test"

    #define EXPORT __attribute__ ((visibility("default")))

    class EXPORT Test {
    public:
        Test();
    };

2. Two shared libraries mod1.so and mod2.so export the following function

   EXPORT std::type_index get_mod[1/2]() { return typeid(Test); }

3. An executable "main" loads both mod1.so and mod2.so and checks if get_mod1()
== get_mod2().


On my machine (Linux/x86_64, Clang trunk), I observe different results
depending on the C++ standard library being used:

- libstdc++ states that the std::type_index return values agree.

- libc++ states that the std::type_index return values DO NOT agree. :(

My hunch is that Clang never exports the typeid data structure despite the
visibility("default") annotation, which seems to be confirmed by "nm":

$ nm shared.so | grep Test | c++filt                                           
                                                             00000000000006a0 T
Test::Test()
00000000000006a0 T Test::Test()
$

Potentially libstdc++ then compares type mangled type names, whereas libc++ is
more strict and requires the underlying typeid data structure to be at the same
address in memory.

Interestingly, this seems to be a Linux-specific inconsistency. The issue does
not appear on Mac OS (again, using Clang and libc++).

This has unfortunately become a serious issue in a modular software platform
that is currently in development (dynamic_casts stop working, etc.). I'm
wondering if

1. This is a bug in Clang or libc++? If so, how can it be fixed?

2. Is there a magic incantation/command line flag that is missing on Linux to
enable a consistent behavior across platforms?

Thank you and best regards,
Wenzel</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>