Reland "Fix vtable not receiving hidden visibility when using push(visibility)"

I had to reland this change in order to make the test work on windows

This change should resolve https://bugs.llvm.org/show_bug.cgi?id=35022

https://reviews.llvm.org/D39627

llvm-svn: 319269
This commit is contained in:
Jake Ehrlich 2017-11-29 00:54:20 +00:00
parent 5fb3ad71a2
commit ba874ad83e
7 changed files with 41 additions and 19 deletions

View File

@ -240,7 +240,7 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
getModule(), LTy, Ty.isConstant(getContext()), Linkage, Init, Name,
nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
setGlobalVisibility(GV, &D);
setGlobalVisibility(GV, &D, ForDefinition);
if (supportsCOMDAT() && GV->isWeakForLinker())
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));

View File

@ -100,7 +100,7 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
VTT->setComdat(CGM.getModule().getOrInsertComdat(VTT->getName()));
// Set the right visibility.
CGM.setGlobalVisibility(VTT, RD);
CGM.setGlobalVisibility(VTT, RD, ForDefinition);
}
llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {

View File

@ -51,7 +51,7 @@ llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD,
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
const ThunkInfo &Thunk, llvm::Function *Fn) {
CGM.setGlobalVisibility(Fn, MD);
CGM.setGlobalVisibility(Fn, MD, ForDefinition);
}
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
@ -730,7 +730,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
// Create the variable that will hold the construction vtable.
llvm::GlobalVariable *VTable =
CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage);
CGM.setGlobalVisibility(VTable, RD);
CGM.setGlobalVisibility(VTable, RD, ForDefinition);
// V-tables are always unnamed_addr.
VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

View File

@ -669,7 +669,8 @@ llvm::ConstantInt *CodeGenModule::getSize(CharUnits size) {
}
void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
const NamedDecl *D) const {
const NamedDecl *D,
ForDefinition_t IsForDefinition) const {
// Internal definitions always have default visibility.
if (GV->hasLocalLinkage()) {
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
@ -678,7 +679,8 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
// Set visibility for definitions.
LinkageInfo LV = D->getLinkageAndVisibility();
if (LV.isVisibilityExplicit() || !GV->hasAvailableExternallyLinkage())
if (LV.isVisibilityExplicit() ||
(IsForDefinition && !GV->hasAvailableExternallyLinkage()))
GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));
}
@ -1059,7 +1061,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
void CodeGenModule::SetCommonAttributes(const Decl *D,
llvm::GlobalValue *GV) {
if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
setGlobalVisibility(GV, ND);
setGlobalVisibility(GV, ND, ForDefinition);
else
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
@ -1115,8 +1117,8 @@ void CodeGenModule::SetInternalFunctionAttributes(const Decl *D,
setNonAliasAttributes(D, F);
}
static void setLinkageAndVisibilityForGV(llvm::GlobalValue *GV,
const NamedDecl *ND) {
static void setLinkageForGV(llvm::GlobalValue *GV,
const NamedDecl *ND) {
// Set linkage and visibility in case we never see a definition.
LinkageInfo LV = ND->getLinkageAndVisibility();
if (!isExternallyVisible(LV.getLinkage())) {
@ -1132,10 +1134,6 @@ static void setLinkageAndVisibilityForGV(llvm::GlobalValue *GV,
// separate linkage types for this.
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
}
// Set visibility on a declaration only if it's explicit.
if (LV.isVisibilityExplicit())
GV->setVisibility(CodeGenModule::GetLLVMVisibility(LV.getVisibility()));
}
}
@ -1204,7 +1202,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
// Only a few attributes are set on declarations; these may later be
// overridden by a definition.
setLinkageAndVisibilityForGV(F, FD);
setLinkageForGV(F, FD);
setGlobalVisibility(F, FD, NotForDefinition);
if (FD->getAttr<PragmaClangTextSectionAttr>()) {
F->addFnAttr("implicit-section-name");
@ -2441,7 +2440,8 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
setLinkageAndVisibilityForGV(GV, D);
setLinkageForGV(GV, D);
setGlobalVisibility(GV, D, NotForDefinition);
if (D->getTLSKind()) {
if (D->getTLSKind() == VarDecl::TLS_Dynamic)
@ -3260,7 +3260,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
setFunctionDLLStorageClass(GD, Fn);
// FIXME: this is redundant with part of setFunctionDefinitionAttributes
setGlobalVisibility(Fn, D);
setGlobalVisibility(Fn, D, ForDefinition);
MaybeHandleStaticInExternC(D, Fn);
@ -3856,7 +3856,7 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
/*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
if (emitter) emitter->finalize(GV);
setGlobalVisibility(GV, VD);
setGlobalVisibility(GV, VD, ForDefinition);
GV->setAlignment(Align.getQuantity());
if (supportsCOMDAT() && GV->isWeakForLinker())
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));

View File

@ -710,7 +710,8 @@ public:
llvm::ConstantInt *getSize(CharUnits numChars);
/// Set the visibility for the given LLVM GlobalValue.
void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D,
ForDefinition_t IsForDefinition) const;
/// Set the TLS mode for the given LLVM GlobalValue for the thread-local
/// variable declaration D.

View File

@ -1527,7 +1527,7 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
// Set the right visibility.
CGM.setGlobalVisibility(VTable, RD);
CGM.setGlobalVisibility(VTable, RD, ForDefinition);
// Use pointer alignment for the vtable. Otherwise we would align them based
// on the size of the initializer which doesn't make sense as only single
@ -1637,6 +1637,7 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
Name, VTableType, llvm::GlobalValue::ExternalLinkage);
VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
CGM.setGlobalVisibility(VTable, RD, NotForDefinition);
if (RD->hasAttr<DLLImportAttr>())
VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -triple x86_64-linux-unknown -emit-llvm %s -o - | FileCheck %s
#pragma GCC visibility push(hidden)
struct Base {
virtual ~Base() = default;
virtual void* Alloc() = 0;
};
class Child : public Base {
public:
Child() = default;
void* Alloc();
};
void test() {
Child x;
}
// CHECK: @_ZTV5Child = external hidden unnamed_addr constant