forked from OSchip/llvm-project
[MinGW] Reject explicit non-default visibility applied to dllexport/dllimport declaration
dllimport/dllexport is incompatible with protected/hidden visibilities. (Arguably dllexport semantics is compatible with protected but let's reject the combo for simplicity.) When an explicit visibility attribute applies on a dllexport/dllimport declaration, report a Frontend error (Sema does not compute visibility). Reviewed By: mstorsjo Differential Revision: https://reviews.llvm.org/D133266
This commit is contained in:
parent
05737fa209
commit
91d8324366
|
@ -282,6 +282,8 @@ def err_duplicate_mangled_name : Error<
|
|||
"definition with same mangled name '%0' as another definition">;
|
||||
def err_cyclic_alias : Error<
|
||||
"%select{alias|ifunc}0 definition is part of a cycle">;
|
||||
def err_non_default_visibility_dllstorage : Error<
|
||||
"non-default visibility cannot be applied to '%0' declaration">;
|
||||
def err_ifunc_resolver_return : Error<
|
||||
"ifunc resolver function must return a pointer">;
|
||||
|
||||
|
|
|
@ -1099,8 +1099,6 @@ llvm::ConstantInt *CodeGenModule::getSize(CharUnits size) {
|
|||
|
||||
void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
|
||||
const NamedDecl *D) const {
|
||||
if (GV->hasDLLExportStorageClass() || GV->hasDLLImportStorageClass())
|
||||
return;
|
||||
// Internal definitions always have default visibility.
|
||||
if (GV->hasLocalLinkage()) {
|
||||
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
|
||||
|
@ -1111,6 +1109,14 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
|
|||
// Set visibility for definitions, and for declarations if requested globally
|
||||
// or set explicitly.
|
||||
LinkageInfo LV = D->getLinkageAndVisibility();
|
||||
if (GV->hasDLLExportStorageClass() || GV->hasDLLImportStorageClass()) {
|
||||
// Reject explicit non-default visibility on dllexport/dllimport.
|
||||
if (LV.isVisibilityExplicit() && LV.getVisibility() != DefaultVisibility)
|
||||
getDiags().Report(D->getLocation(),
|
||||
diag::err_non_default_visibility_dllstorage)
|
||||
<< (GV->hasDLLExportStorageClass() ? "dllexport" : "dllimport");
|
||||
return;
|
||||
}
|
||||
if (LV.isVisibilityExplicit() || getLangOpts().SetVisibilityForExternDecls ||
|
||||
!GV->isDeclarationForLinker())
|
||||
GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));
|
||||
|
|
|
@ -4,10 +4,18 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-gnu -fdeclspec -fvisibility-inlines-hidden -o - %s | FileCheck %s --check-prefix=GNU
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-gnu -fdeclspec -fvisibility=hidden -o - %s | FileCheck %s --check-prefix=GNU
|
||||
|
||||
// RUN: %clang_cc1 -emit-llvm-only -verify -triple x86_64-windows-gnu -fdeclspec -DERR1 -o - %s
|
||||
// RUN: %clang_cc1 -emit-llvm-only -verify -triple x86_64-windows-gnu -fdeclspec -fvisibility=hidden -DERR1 -o - %s
|
||||
// RUN: %clang_cc1 -emit-llvm-only -verify -triple x86_64-windows-gnu -fdeclspec -DERR2 -o - %s
|
||||
|
||||
#define CONCAT2(x, y) x##y
|
||||
#define CONCAT(x, y) CONCAT2(x, y)
|
||||
#define USE(func) void CONCAT(use, __LINE__)() { func(); }
|
||||
|
||||
#define HIDDEN __attribute__((visibility("hidden")))
|
||||
#define PROTECTED __attribute__((visibility("protected")))
|
||||
#define DEFAULT __attribute__((visibility("default")))
|
||||
|
||||
// MSVC-DAG: declare dllimport void @"?bar@foo@@QEAAXXZ"(
|
||||
// GNU-DAG: define linkonce_odr hidden void @_ZN3foo3barEv(
|
||||
|
||||
|
@ -24,3 +32,17 @@ __attribute__((dllexport)) void exported() {}
|
|||
// GNU-DAG: define weak_odr dso_local dllexport void @_Z15exported_inlinev(
|
||||
__declspec(dllexport) inline void exported_inline() {}
|
||||
USE(exported_inline)
|
||||
|
||||
#if defined(ERR1)
|
||||
// expected-error@+1 {{non-default visibility cannot be applied to 'dllimport' declaration}}
|
||||
__attribute__((dllimport)) HIDDEN void imported_hidden();
|
||||
|
||||
__attribute__((dllexport)) DEFAULT void exported_default() {}
|
||||
// expected-error@+1 {{non-default visibility cannot be applied to 'dllexport' declaration}}
|
||||
__attribute__((dllexport)) HIDDEN void exported_hidden() { imported_hidden(); }
|
||||
#elif defined(ERR2)
|
||||
struct PROTECTED C {
|
||||
// expected-error@+1 {{non-default visibility cannot be applied to 'dllexport' declaration}}
|
||||
__attribute__((dllexport)) void exported_protected() {}
|
||||
};
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue