When using the relative vtable ABI, if a vtable is not dso_local, it's given private linkage (if not COMDAT) or hidden visibility (if COMDAT) to make it dso_local (to place it in rodata instead of data.rel.ro), and an alias generated with the original linkage and visibility. This alias could later be removed from the symbol table, e.g. if using a version script, at which point we lose all symbol information about the vtable. Use internal linkage instead of private linkage to avoid this. While I'm here, clarify the comment about why COMDAT vtables can't use internal (or private) linkage, and associate it with the else block where hidden visibility is applied instead of internal linkage.
17 lines
690 B
C++
17 lines
690 B
C++
// Check that no alias is emitted when the vtable is already dso_local. This can
|
|
// happen if the class is hidden.
|
|
|
|
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -o - -emit-llvm -fhalf-no-semantic-interposition | FileCheck %s --check-prefix=DEFAULT-VIS
|
|
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -o - -emit-llvm -fvisibility=hidden | FileCheck %s --check-prefix=HIDDEN-VIS
|
|
|
|
// DEFAULT-VIS: @_ZTV1A.local = internal unnamed_addr constant
|
|
// DEFAULT-VIS: @_ZTV1A ={{.*}} unnamed_addr alias { [3 x i32] }, ptr @_ZTV1A.local
|
|
// HIDDEN-VIS-NOT: @_ZTV1A.local
|
|
// HIDDEN-VIS: @_ZTV1A = hidden unnamed_addr constant
|
|
class A {
|
|
public:
|
|
virtual void func();
|
|
};
|
|
|
|
void A::func() {}
|