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

    <tr>
        <th>Summary</th>
        <td>
            Prevailing COMDAT LTO creates broken IR Module and crashes LLD
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          darkness-ai
      </td>
    </tr>
</table>

<pre>
    Hello, encountered a linkage error (broken module) when compiling a C++ program.
Small reproducer - [https://godbolt.org/z/dhecaqsj9] (https://godbolt.org/z/dhecaqsj9) (checked with clang-trunk) - will be pasted in end as well in case the link breaks.
The error message received is:
```
Alias must point to a definition
ptr @_ZN7DerivedIiED1Ev
LLVM ERROR: Broken module found, compilation aborted!
```
Few key notes, the bug happens for destructors, only when linking with regular LTO, and depends on the linkage order of the different modules.
My current understanding of the bug is as follows:

1. First module (reproducer - broken1.cpp) - includes a template instantiation of a derived class.
    1. The IR for that module includes the 3 C++ destructors D0 (Deleting object destructor), D1 (Complete Object Destructor) and D2 (Base Object Destructor)
    2. All of those 3 are inside of comdat D5 (`_ZN7DerivedIiED5Ev`)
    3. D1 is actually and alias for D2 (guessing because all the members are trivially destructible)
2. Second module (reproducer - broken2.cpp) - includes usage of shared_ptr for the same template
    1. This module only use the deleting object destructor D0
    2. Now the IR includes only the D0 destructor definition in comdat with the same name D0
3. During LTO linkage (if broken2.o is linked before broken1.o) (Didn't debug to make sure this is the exact flow. Based on inputs and outputs of the stages)
    1. The linker inserts the `_ZN7DerivedIiED0Ev` symbol under the `_ZN7DerivedIiED0Ev` comdat
    2. It sets `_ZN7DerivedIiED5Ev` to be non-prevailing as it includes the symbol `_ZN7DerivedIiED0Ev`  which is already defined
    3. During the removal of symbols from `_ZN7DerivedIiED5Ev` it changes the linkage type of `_ZN7DerivedIiED2Ev` to be available_externally
    4. `_ZN7DerivedIiED1Ev` is still an alias for `_ZN7DerivedIiED2Ev` which is now invalid as `_ZN7DerivedIiED2Ev` is an available_externally symbol
    5. The module is broken with alias must point to definition

When the linkage order is reversed (i.e. broken1.o is first linked), then the `_ZN7DerivedIiED5Ev` is the prevailing one, and `_ZN7DerivedIiED2Ev` keeps the weak_odr linkage type, and everything works.

Possible solutions I can think of:

- Have clang always emit all 3 destructors on per module (at least for LTO) basis.
- Don't allow D1 destructor to alias D2 destructor - seems like a bad idea, but will fix the final error.
- Making libLTO handle prevailing COMDATs by checking that one is a superset of the other and picking the superset

Reproducer program -
broken.h:
```
template<typename T>
class Base{
    public:
        Base(T val) :  m_val(val) {}
        virtual ~Base() {}
        T val() const {return m_val;};
    protected:
        T m_val;
};

template<typename T>
class Derived : public Base<T> {
    public:
        Derived(): Base<T>(0) {}
        Derived(T val): Base<T>(val) {}
        ~Derived() {}
};
```
broken1.cpp:
```
#include"broken.h"

template class Derived<int>;
```
broken2.cpp:
#include <memory>
#include "broken.h"

int foo2(int b) {
    return std::make_shared<Derived<int>>(b).get()->val();
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10.2)
project(default VERSION 0.0.1)

set(CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=lld")
set(CMAKE_CXX_FLAGS "-O1 -flto")

add_library(broken SHARED
            broken2.cpp
            broken1.cpp)
target_compile_features(broken PUBLIC cxx_std_17)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyNWNty4rgW_RrnRYULTEjCAw8Ek9OpIZ2uJKfP1HmhZFuABtvySHIS5utnbck2JgldTdFubEn7svbaFydR2WH2TeS5CqIFE2Wq6tIKLTLGWS7LPd8KJrRWmgXRTaLVXpSsUFmdiyCasrcdblNVVBJ7tziyCKJbfFml1VbzIgyGcTCcPxc8z5kWeJrVqdBswILJ7c7aygTjeRDd4btVWaJyGyq9xd0_-JftRMr_Nn9Ng0lM2n9_PyzD_hT3ezjyJu2OpTkvtwOr63JPywM8hUmJYBU3FptkCefhtGFvAINuU24EszvhYGCJFnxvGn9edi0ohTCGINIiFfKV5DgL3a7gath83e08l5Be1MaySsnSMqsAWCY2spRWqtLvqiyQvhyu___9OhaaRN7LZTxavvrl1ernA1s-PT0-QQ277ceDbRC6jKLoA8JJKOOJ0vAviEZfGnUn3theHFiprDB0lhxO6i3b8aoSpYFQDRsNgEut0m6LKvODjzwhQ3F3CGuxrXOu2erlkXZxoJkJyMgMTnRAElhKZ-CA2riHmdxswDfg4d1oMX44sLTWbgFuCW0sJJKy5hwZKQ0FbKPA3rce7u46CtmdxKkWHRDihICey6MwrSpPCFmmeQ1XERQrigr4CTwjtVZ6LKGZAuaiQoQyra0MH-gjWtw_OcjsjneaO8Fk9rhLkR6qLB6SfbHIhXUuJn-J1PZ2wELCNB7RtgXCi42CPfptcX-bwz2OaN8tEfirPUejo5DNwXYHqTJkHdfOa5kJegomZXAknpA8kOYDLSegJZjUlzgOyUoKTGprZP3BGcQd9wkYb9q2Rt6QpwlStoZiqg8ETyGKBLF2ZljokU5EC4RMXNnx2mD7s0gVpP8ywtEXEa5dzsI_s4OibE1J56MmmOGF6AjwIbxwq9HlcqBuCkR2Nm4I7AnY39WbOwGWdMY4UfQQJOidPBYGV4x8IFyidVaWdGk1EPC1JiuQgF2qARO56ZBQFBhaAn8TAY9FlwaqKZqxzMoguiYnKMNQowq-h76aAkIASM9j8Y4Asw0SL2REtIw5Q6vaGhdxVVv3u8lWpNGWCsz0U8I4czRxTmjrZX8m2tARjZlDgZrv68Gvd3q8TrC_t8wIaDhHY_IV_aBU5aDS4pU3LQ0e29MUbqw4qxu1UaY7lwM5ukZ28LFEET7JEh8sEqhFoV65S0MvG6miVXHeUliU7tDPGoPaYNtD5Vj9-VzU95CTbxyptBbvaPUlpdjRtMvwi_OjRq9BIKlv8rKX0mfVdTiUoL0s4aJ0HfbsAYKs_NK-BpijmRPPnrbEmobIPkP4F632Y6P11_9RG_vcmyAPFEAhAq8phUIRHjOFVjeutfhUaoqzbUWdD5sPV49dqhRtrzwLyl6Iyh98wwiyVpk-CXh7nsw9IEOpHSvdjSr--kOh3AJRZlReEwaG3WPAIXtpuFGbD81zwL7xV-GHJqD5xg-GiQK0ozo9PmldSPsKiB1rMMpULjBUOW64YWDKEm5ka9GAxcqXGE59m9pFr-zRUOSih0bRezxA7oqCiheKEYc8TFqZ4OR8Uls_zG3ku4MJcUYyufmsU_nA3aCSy4SqI3Iny08CsXh8iOcvYBGmDhobfWrCFUTI0RIVsCI-2LaiKVy0Q76S7X7R7eqD-XRsSs1YzAZ-xVMq3J0bGbs2NF5QqF29fwnGS7_qJhBXfIPr22NmVHWSy7QTyZqP2xfdvDCkoav1mB9ZsXZ3N-0zyLmOT8-9Sk2NHGvLRsS5nY1ot46-DAZglxa21mWjaOwOjfvGagyeKQ2oH-19OZ7x0PRO_j46TTo5bz0wHojxgnay3wGuEeEdc1P3UQAeDs_BcTzXYv758C9wB94nmk82nYBxypn-XHuGVkE0bhpaEEUdB6PoK3DZCY6wHOWUbP-l9uhUe6cOYVhgwlP60IWpv3jWGCrhG6UiKsX4mbRwdIA1LDPW8Wg8p5ll7Yc7qPxsPGFPUsItUtXBO8DDjr4npHM_FiggYiWNNaF9t51rqVNUoLEUdbHW4u9aahewn8un5_vH72j0o2EYdXMP6E4TIjagHfE6t6zdOAyH4ajb56_GGbd4mP-xXD9_mz8t4_Xq_vsfy6f13Wr-n2cCbLDBEDrI4Vuc4xodVfUPL_78s3fkccQGm9yq_m5_5Vm2RonUHAHq3va95lNy0qcf6jOL7dtVQymuAffav52K9UZwBI2GwlbTj__eru7x-vr-vkYk16NrHL3IZuNsOp7yCyttLmY_PtZsN-6mmLPwAtsOARivH3w_ovqcam52WFyt4ota57MPf0fAwFAnIazCTZ6_tv8NuljdSWNqsvNucjW8nFzsZjdX02EaRdnNzURkYnqTTqKry4lIJynP0sur6QXGF5GbWTDBm15U4h3biSDAJ_GFnEXDKBpejSbDm8lkdBkm6dVwk2wmEJvw8XSE939RwMmQ7KA_cFzomTMJE7nBYu542C0iP-W2FMKpg3xe42VOzzKu9yVeswZcXjj1M2f-vzXEo8Y">