Index: lld/ELF/Relocations.cpp =================================================================== --- lld/ELF/Relocations.cpp +++ lld/ELF/Relocations.cpp @@ -663,6 +663,10 @@ Msg += Src + "\n>>> "; Msg += Sec.getObjMsg(Offset); + if (Sym.getName().startswith("_ZTV")) + Msg += "\nthe vtable symbol may be undefined because the class is missing " + "its key function (see https://lld.llvm.org/missingkeymethod)"; + if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) || Config->NoinhibitExec) { warn(Msg); Index: lld/docs/missingkeymethod.rst =================================================================== --- /dev/null +++ lld/docs/missingkeymethod.rst @@ -0,0 +1,84 @@ +Missing Key Method +================== + +If your build failed with a linker error something like this:: + + foo.cc:28: error: undefined reference to 'vtable for C' + the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeymethod) + +it's likely that your class C has a key method (defined by the ABI as the first +non-pure, non-inline, virtual method), but you haven't actually defined it. + +When a class has a key method, the compiler emits the vtable (and some other +things as well) only in the translation unit that defines that key method. Thus, +if you're missing the key method, you'll also be missing the vtable. If no other +function calls your missing method, you won't see any undefined reference errors +for it, but you will see undefined references to the vtable symbol. + +When a class has no non-pure, non-inline, virtual methods, there is no key +method, and the compiler is forced to emit the vtable in every translation unit +that references the class. In this case, it is emitted in a COMDAT section, +which allows the linker to eliminate all duplicate copies. This is still +wasteful in terms of object file size and link time, so it's always advisable to +ensure there is at least one eligible method that can serve as the key method. + +Here are the most common mistakes that lead to this error: + +Failing to define a virtual destructor +-------------------------------------- + +Say you have a base class declared in a header file:: + + class B { + public: + B(); + virtual ~B(); + ... + }; + +Here, ``~B`` is the first non-pure, non-inline, virtual method, so it is the key +method. If you forget to define ``B::~B`` in your source file, the compiler will +not emit the vtable for ``B``, and you'll get an undefined reference to "vtable +for B". + +This is just an example of the more general mistake of forgetting to define the +key method, but it's quite common because virtual destructors are likely to be +the first eligible key method and it's easy to forget to implement them. It's +also more likely that you won't have any direct references to the destructor, so +you won't see any undefined reference errors that point directly to the problem. + +The solution in this case is to implement the missing method. + +Forgetting to declare a virtual method in an abstract class as pure +------------------------------------------------------------------- + +Say you have an abstract base class declared in a header file:: + + class A { + public: + A(); + virtual ~A() {} + virtual int foo() = 0; + ... + virtual int bar(); + ... + }; + +This base class is intended to be abstract, but you forgot to mark one of the +methods pure. Here, ``A::bar``, being non-pure, is nominated as the key method, +and as a result, the vtable for ``A`` is not emitted, because the compiler is +waiting for a translation unit that defines ``A::bar``. + +The solution in this case is to add the missing ``= 0`` to the declaration of +``A::bar``. + +Key method is defined, but the linker doesn't see it +---------------------------------------------------- + +It's also possible that you have defined the key method somewhere, but the +object file containing the definition of that method isn't being linked into +your application. + +The solution in this case is to check your build file to make sure that the +object file or the library file containing the key method is given to the +linker. Index: lld/test/ELF/undef.s =================================================================== --- lld/test/ELF/undef.s +++ lld/test/ELF/undef.s @@ -20,6 +20,9 @@ # CHECK: >>> referenced by undef.s # CHECK: >>> {{.*}}:(.text+0x10) +# CHECK: error: undefined symbol: vtable for Foo +# CHECK: the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeymethod) + # CHECK: error: undefined symbol: zed2 # CHECK: >>> referenced by {{.*}}.o:(.text+0x0) in archive {{.*}}2.a @@ -60,3 +63,4 @@ call bar call zed1 call _Z3fooi + call _ZTV3Foo