<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/74721>74721</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
undefined reference to `vtable for Derived' for exported key function
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
JVApen
</td>
</tr>
</table>
<pre>
This problem is a variation on the problem of https://lld.llvm.org/missingkeyfunction, though none of the solutions mentioned are the problem.
liba.h
````
#pragma once
#define EXPORT __attribute__((visibility("default")))
class Base
{
public:
Base() = default;
~Base() = default;
virtual void bsf() = 0;
};
class Derived : public Base
{
public:
Derived() = default;
~Derived() = default;
EXPORT void bsf() override;
};
````
liba.cpp
````
#include "liba.h"
void Derived::bsf()
{
}
````
main.cpp
````
#include "liba.h"
int main()
{
[[maybe_unused]] auto x = Derived{};
}
````
CMakeLists.txt
````
cmake_minimum_required(VERSION 2.22)
project(visibility)
add_compile_options(-Wall -Wextra -fvisibility=hidden)
add_link_options(-W,-z,defs)
add_library(a SHARED liba.cpp)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE a)
````
>From the command line:
````
> objdump -C -t CMakeFiles/main.dir/main.cpp.o | grep Derived
0000000000000000 l d .text._ZN7DerivedC2Ev 0000000000000000 .text._ZN7DerivedC2Ev
0000000000000000 w F .text._ZN7DerivedC2Ev 0000000000000034 .hidden Derived::Derived()
0000000000000000 *UND* 0000000000000000 vtable for Derived
> objdump -C -t liba.so | grep Derived
0000000000002810 l O .data.rel.ro 0000000000000018 .hidden vtable for Derived
0000000000002828 l O .data.rel.ro 0000000000000018 .hidden typeinfo for Derived
0000000000000670 l O .rodata 0000000000000009 .hidden typeinfo name for Derived
00000000000017a0 g F .text 000000000000000a Derived::bsf()
````
The method Derived::bsf() is the key function ` (defined by the ABI as the first non-pure, non-inline, virtual function)`.
This has a definition in liba.cpp
As the Ctor/Dtor are inline, main.cpp has an implementation of the constructor that requires the vtable.
In the content of the object file liba.so, we can see that Derived::bsf() is an exported function, and the dtor method seems to be created as a hidden function. The vtable also exists. The main.o file requires the symbol for the vtable to exist. On linking, it doesn't find it.
Based on what we read on https://lld.llvm.org/missingkeyfunction, all requirements related to the keyfunction are met. As such, I believe the liba.o file should have the vtable symbol exported such that main.o can use it.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykV0tv67oR_jX0ZmBBph-yF144doymaE8uctNzi24MShxZPKFIlaScuIv-9oLUw4_ESdBrGI4ew2---WaGnDBrxV4hLsn0jkw3A1a7QpvlX3-uKlSDVPPj8rkQFiqjU4klCAsMDswI5oRWoBW4Avu3OofCucqS8YrQLaFbKXkk5aGMtNkTui2FtULtX_CY1yrzCISuwRW63hegtEKP4AGtlrV_baFE5S-QAzN47iwi8YbEq-ZXipRFRftkFp--zRM6rgzblwy0yrB_xjEXCuH-n789Pj3DbsecMyKtHe52hM4JnR-EFamQwh3DPeWYs1o6Qimhi_Z7RiKTzFq4Y7Zzkdw1F1WdSpF5UcItADRWHnQBZLyBDnl8dzL571c2B2FczSQctOCQ2vzMNu6tSLI5XZ_R3KARB-RAxito-H2TebvwK_LfM2u1v4pAH9AYwfHjIN6n91QCWVV9UgRCZbLmCITStmAoPYcINDri4xUZr3pOV7qcaH3KqWRC_UlOQjnwMB_S8BKGxr0r2THFXa1qi5xMN2S6AVY7DW9B-i6m5O5Cya_or__OXvBvwjobuTd3yzYr2QvuSqFEWZc7g_-uhQmJ_3n_9PvD4w-gUdMwZ8iV0b8wc1c9dmHCON9luqyExJ2uwmZA6Hz4B5MShn_gmzMMhvnZ8vGmEJyj6nE8ghTq5WI5oevhfwhdc8ztBx6lSA0zvt8Z_P6X1dP9BvrCem-Nb5jVjqXS96nPEvQZ74wdM3t0DY8GXKDtrH97evi5er4HdsK-kYrmd2t0GfbATJclUxykUNh35wdrx_eg01-8LisYrmHoIKR0K6TnsA1kuTDdZVZVkQaSrGFvsOqrJkDFVx-Qvvg4QOTwzUW7f_1IWvs1vT_AO_MPzW5Aw6vH3t6AvsIeTyBqEn_Zuhcb0C1H7YfQ1T9-bAhdXYPHMRxCfiHX5lKQ99qGQrHfEZDOR17AR4g4cywyKCOj4dr5aA4Xny7MW4wuPdB5k6JveOmA3bFCoXL9OXQ8S-ITtNEe_Fq2xcfMeweKlV8EMEpYDHs4K4R3uWGf79XvuuG5QCjRFfrWJu-nG99dL3iEbkABMouB0HkzLHBIj8FkdfcArLHOhbHOTy_DqjboBxp_LVToTbruj-nTyLMgszjqOAkLBfNTVfAggk-h4PI4WzWu1k77Zt04bcI4dHLS9W-DpUCUlUQ_O7VzWt5uG8o6U2d-vSuYg3a3btCburqYqx5Ut86hch2MTv3mDbmQ2BW95_CKkDEFFrEBvy0yU4BvlTYOOZxPgn5L8w64J9imyiKWFpyGFCEzyPyaoFdbU936CJ77GIBJqwHfwtEVngd9dEP5Imh7LFMtQy2eNPDuwuoIHn0q1ItQe09QOOAarSI08fErDsJdCOZnKO7H4levwKt3xsL9_zEX-5Ou5eozacGgDOE73ZVpX6W-Gkp0Eaws2Dor_PoHSFEKPDRjc0hUq4AtdC05FKx910bdatGnxgM1qWzl8-mtLfqgB3w55ovxgg1wOUri0WIWz-aTQbHM2DSfzUaULXi6yCeU0tk8GdERjROGkykbiCWN6djfjybTEZ1Ei3ESZ_P5fJTHcTJlGZnEWDIhe4UGwtoal8kkoaOBZClKG_5foVThK4SXfmqabgZm6dcM03pvySSWIf89ihNO4rJWXSsbzNGgykK6ySz-YF-lSbjtFTnfGQa1kcvLtO6FK-o0ynQZcnzo_gz7eWcb2PrDN0TzvwAAAP__0aIC4A">