diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2662,10 +2662,7 @@ SourceLocation Loc) { if (SanOpts.has(SanitizerKind::CFIVCall)) EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc); - else if (CGM.getCodeGenOpts().WholeProgramVTables && - // Don't insert type test assumes if we are forcing public std - // visibility. - !CGM.HasLTOVisibilityPublicStd(RD)) { + else if (CGM.getCodeGenOpts().WholeProgramVTables) { llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); llvm::Value *TypeId = diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -1255,26 +1255,6 @@ DeferredVTables.clear(); } -bool CodeGenModule::HasLTOVisibilityPublicStd(const CXXRecordDecl *RD) { - if (!getCodeGenOpts().LTOVisibilityPublicStd) - return false; - - const DeclContext *DC = RD; - while (1) { - auto *D = cast(DC); - DC = DC->getParent(); - if (isa(DC->getRedeclContext())) { - if (auto *ND = dyn_cast(D)) - if (const IdentifierInfo *II = ND->getIdentifier()) - if (II->isStr("std") || II->isStr("stdext")) - return true; - break; - } - } - - return false; -} - bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) { LinkageInfo LV = RD->getLinkageAndVisibility(); if (!isExternallyVisible(LV.getLinkage())) @@ -1291,7 +1271,22 @@ return false; } - return !HasLTOVisibilityPublicStd(RD); + if (getCodeGenOpts().LTOVisibilityPublicStd) { + const DeclContext *DC = RD; + while (1) { + auto *D = cast(DC); + DC = DC->getParent(); + if (isa(DC->getRedeclContext())) { + if (auto *ND = dyn_cast(D)) + if (const IdentifierInfo *II = ND->getIdentifier()) + if (II->isStr("std") || II->isStr("stdext")) + return false; + break; + } + } + } + + return true; } llvm::GlobalObject::VCallVisibility diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1317,11 +1317,6 @@ /// optimization. bool HasHiddenLTOVisibility(const CXXRecordDecl *RD); - /// Returns whether the given record has public std LTO visibility - /// and therefore may not participate in (single-module) CFI and whole-program - /// vtable optimization. - bool HasLTOVisibilityPublicStd(const CXXRecordDecl *RD); - /// Returns the vcall visibility of the given type. This is the scope in which /// a virtual function call could be made which ends up being dispatched to a /// member function of this class. This scope can be wider than the visibility diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -696,10 +696,7 @@ CGM.HasHiddenLTOVisibility(RD); bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination && CGM.HasHiddenLTOVisibility(RD); - bool ShouldEmitWPDInfo = - CGM.getCodeGenOpts().WholeProgramVTables && - // Don't insert type tests if we are forcing public std visibility. - !CGM.HasLTOVisibilityPublicStd(RD); + bool ShouldEmitWPDInfo = CGM.getCodeGenOpts().WholeProgramVTables; llvm::Value *VirtualFn = nullptr; { diff --git a/clang/test/CodeGenCXX/lto-visibility-inference.cpp b/clang/test/CodeGenCXX/lto-visibility-inference.cpp --- a/clang/test/CodeGenCXX/lto-visibility-inference.cpp +++ b/clang/test/CodeGenCXX/lto-visibility-inference.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -std=c++11 -fms-extensions -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=ITANIUM %s -// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11 -fms-extensions -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=MS --check-prefix=MS-STD %s -// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11 -fms-extensions -fwhole-program-vtables -flto-visibility-public-std -emit-llvm -o - %s | FileCheck --check-prefix=MS --check-prefix=MS-NOSTD %s +// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11 -fms-extensions -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=MS %s +// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11 -fms-extensions -fwhole-program-vtables -flto-visibility-public-std -emit-llvm -o - %s | FileCheck --check-prefix=MS %s struct C1 { virtual void f(); @@ -86,16 +86,13 @@ // MS: type.test{{.*}}!"?AUC6@@" c6->f(); // ITANIUM: type.test{{.*}}!"_ZTSSt2C7" - // MS-STD: type.test{{.*}}!"?AUC7@std@@" - // MS-NOSTD-NOT: type.test{{.*}}!"?AUC7@std@@" + // MS: type.test{{.*}}!"?AUC7@std@@" c7->f(); // ITANIUM: type.test{{.*}}!"_ZTSNSt2C72C8E" - // MS-STD: type.test{{.*}}!"?AUC8@C7@std@@" - // MS-NOSTD-NOT: type.test{{.*}}!"?AUC8@C7@std@@" + // MS: type.test{{.*}}!"?AUC8@C7@std@@" c8->f(); // ITANIUM: type.test{{.*}}!"_ZTSN6stdext2C9E" - // MS-STD: type.test{{.*}}!"?AUC9@stdext@@" - // MS-NOSTD-NOT: type.test{{.*}}!"?AUC9@stdext@@" + // MS: type.test{{.*}}!"?AUC9@stdext@@" c9->f(); // ITANIUM: type.test{{.*}}!"_ZTSN5other3C10E" // MS: type.test{{.*}}!"?AUC10@other@@"