Skip to content

Commit a70b39a

Browse files
committedJun 16, 2022
[clang] Don't emit type test/assume for virtual classes that should never participate in WPD
Reviewed By: pcc Differential Revision: https://reviews.llvm.org/D127876
1 parent 046ebeb commit a70b39a

File tree

6 files changed

+25
-24
lines changed

6 files changed

+25
-24
lines changed
 

Diff for: ‎clang/docs/LTOVisibility.rst

+8-7
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,14 @@ other classes receive hidden LTO visibility. Classes with internal linkage
3535
(e.g. classes declared in unnamed namespaces) also receive hidden LTO
3636
visibility.
3737

38-
During the LTO link, all classes with public LTO visibility will be refined
39-
to hidden LTO visibility when the ``--lto-whole-program-visibility`` lld linker
40-
option is applied (``-plugin-opt=whole-program-visibility`` for gold). This flag
41-
can be used to defer specifying whether classes have hidden LTO visibility until
42-
link time, to allow bitcode objects to be shared by different LTO links.
43-
Due to an implementation limitation, symbols associated with classes with hidden
44-
LTO visibility may still be exported from the binary when using this flag. It is
38+
During the LTO link, all classes with public LTO visibility but not marked with
39+
``[[clang::lto_visibility_public]]`` (see below) will be refined to hidden LTO
40+
visibility when the ``--lto-whole-program-visibility`` lld linker option is
41+
applied (``-plugin-opt=whole-program-visibility`` for gold). This flag can be
42+
used to defer specifying whether classes have hidden LTO visibility until link
43+
time, to allow bitcode objects to be shared by different LTO links. Due to an
44+
implementation limitation, symbols associated with classes with hidden LTO
45+
visibility may still be exported from the binary when using this flag. It is
4546
unsafe to refer to these symbols, and their visibility may be relaxed to hidden
4647
in a future compiler release.
4748

Diff for: ‎clang/lib/CodeGen/CGClass.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2695,9 +2695,9 @@ void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
26952695
if (SanOpts.has(SanitizerKind::CFIVCall))
26962696
EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc);
26972697
else if (CGM.getCodeGenOpts().WholeProgramVTables &&
2698-
// Don't insert type test assumes if we are forcing public std
2698+
// Don't insert type test assumes if we are forcing public
26992699
// visibility.
2700-
!CGM.HasLTOVisibilityPublicStd(RD)) {
2700+
!CGM.AlwaysHasLTOVisibilityPublic(RD)) {
27012701
llvm::Metadata *MD =
27022702
CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
27032703
llvm::Value *TypeId =

Diff for: ‎clang/lib/CodeGen/CGVTables.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,10 @@ void CodeGenModule::EmitDeferredVTables() {
11751175
DeferredVTables.clear();
11761176
}
11771177

1178-
bool CodeGenModule::HasLTOVisibilityPublicStd(const CXXRecordDecl *RD) {
1178+
bool CodeGenModule::AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD) {
1179+
if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>())
1180+
return true;
1181+
11791182
if (!getCodeGenOpts().LTOVisibilityPublicStd)
11801183
return false;
11811184

@@ -1200,9 +1203,6 @@ bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
12001203
if (!isExternallyVisible(LV.getLinkage()))
12011204
return true;
12021205

1203-
if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>())
1204-
return false;
1205-
12061206
if (getTriple().isOSBinFormatCOFF()) {
12071207
if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>())
12081208
return false;
@@ -1211,7 +1211,7 @@ bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
12111211
return false;
12121212
}
12131213

1214-
return !HasLTOVisibilityPublicStd(RD);
1214+
return !AlwaysHasLTOVisibilityPublic(RD);
12151215
}
12161216

12171217
llvm::GlobalObject::VCallVisibility CodeGenModule::GetVCallVisibilityLevel(

Diff for: ‎clang/lib/CodeGen/CodeGenModule.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -1382,10 +1382,10 @@ class CodeGenModule : public CodeGenTypeCache {
13821382
/// optimization.
13831383
bool HasHiddenLTOVisibility(const CXXRecordDecl *RD);
13841384

1385-
/// Returns whether the given record has public std LTO visibility
1386-
/// and therefore may not participate in (single-module) CFI and whole-program
1387-
/// vtable optimization.
1388-
bool HasLTOVisibilityPublicStd(const CXXRecordDecl *RD);
1385+
/// Returns whether the given record has public LTO visibility (regardless of
1386+
/// -lto-whole-program-visibility) and therefore may not participate in
1387+
/// (single-module) CFI and whole-program vtable optimization.
1388+
bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD);
13891389

13901390
/// Returns the vcall visibility of the given type. This is the scope in which
13911391
/// a virtual function call could be made which ends up being dispatched to a

Diff for: ‎clang/lib/CodeGen/ItaniumCXXABI.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
668668
CGM.HasHiddenLTOVisibility(RD);
669669
bool ShouldEmitWPDInfo =
670670
CGM.getCodeGenOpts().WholeProgramVTables &&
671-
// Don't insert type tests if we are forcing public std visibility.
672-
!CGM.HasLTOVisibilityPublicStd(RD);
671+
// Don't insert type tests if we are forcing public visibility.
672+
!CGM.AlwaysHasLTOVisibilityPublic(RD);
673673
llvm::Value *VirtualFn = nullptr;
674674

675675
{

Diff for: ‎clang/test/CodeGenCXX/lto-visibility-inference.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ void f(C1 *c1, C2 *c2, C3 *c3, C4 *c4, C5 *c5, C6 *c6, std::C7 *c7,
7979
// ITANIUM: type.test{{.*}}!"_ZTS2C4"
8080
// MS: type.test{{.*}}!"?AUC4@@"
8181
c4->f();
82-
// ITANIUM: type.test{{.*}}!"_ZTS2C5"
83-
// MS: type.test{{.*}}!"?AUC5@@"
82+
// ITANIUM-NOT: type.test{{.*}}!"_ZTS2C5"
83+
// MS-NOT: type.test{{.*}}!"?AUC5@@"
8484
c5->f();
85-
// ITANIUM: type.test{{.*}}!"_ZTS2C6"
86-
// MS: type.test{{.*}}!"?AUC6@@"
85+
// ITANIUM-NOT: type.test{{.*}}!"_ZTS2C6"
86+
// MS-NOT: type.test{{.*}}!"?AUC6@@"
8787
c6->f();
8888
// ITANIUM: type.test{{.*}}!"_ZTSSt2C7"
8989
// MS-STD: type.test{{.*}}!"?AUC7@std@@"

0 commit comments

Comments
 (0)