[clang] 6f9c485 - [MinGW] Reject explicit hidden visibility applied to dllexport and hidden/protected applied to dllimport

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 12 15:56:44 PDT 2022


Author: Fangrui Song
Date: 2022-09-12T15:56:36-07:00
New Revision: 6f9c4851ab7c729812bc8f48b19de3f84a64f6f0

URL: https://github.com/llvm/llvm-project/commit/6f9c4851ab7c729812bc8f48b19de3f84a64f6f0
DIFF: https://github.com/llvm/llvm-project/commit/6f9c4851ab7c729812bc8f48b19de3f84a64f6f0.diff

LOG: [MinGW] Reject explicit hidden visibility applied to dllexport and hidden/protected applied to dllimport

Hidden visibility is incompatible with dllexport.
Hidden and protected visibilities are incompatible with dllimport.
(PlayStation uses dllexport protected.)

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

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticFrontendKinds.td
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/test/CodeGenCXX/dllstorage-visibility.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 50f7e2b9221d0..98ac3915a391c 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -282,6 +282,10 @@ 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_hidden_visibility_dllexport : Error<
+  "hidden visibility cannot be applied to 'dllexport' declaration">;
+def err_non_default_visibility_dllimport : Error<
+  "non-default visibility cannot be applied to 'dllimport' declaration">;
 def err_ifunc_resolver_return : Error<
   "ifunc resolver function must return a pointer">;
 

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index ad6eb32ccc649..bbd42956a4b09 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -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,21 @@ 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 incompatible dlllstorage and visibility annotations.
+    if (!LV.isVisibilityExplicit())
+      return;
+    if (GV->hasDLLExportStorageClass()) {
+      if (LV.getVisibility() == HiddenVisibility)
+        getDiags().Report(D->getLocation(),
+                          diag::err_hidden_visibility_dllexport);
+    } else if (LV.getVisibility() != DefaultVisibility) {
+      getDiags().Report(D->getLocation(),
+                        diag::err_non_default_visibility_dllimport);
+    }
+    return;
+  }
+
   if (LV.isVisibilityExplicit() || getLangOpts().SetVisibilityForExternDecls ||
       !GV->isDeclarationForLinker())
     GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));

diff  --git a/clang/test/CodeGenCXX/dllstorage-visibility.cpp b/clang/test/CodeGenCXX/dllstorage-visibility.cpp
index 8f34afbb801ff..cd6e2de555c6d 100644
--- a/clang/test/CodeGenCXX/dllstorage-visibility.cpp
+++ b/clang/test/CodeGenCXX/dllstorage-visibility.cpp
@@ -4,10 +4,19 @@
 // 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
+// RUN: %clang_cc1 -emit-llvm-only -verify -triple x86_64-windows-gnu -fdeclspec -DERR3 -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 at foo@@QEAAXXZ"(
 // GNU-DAG: define linkonce_odr hidden void @_ZN3foo3barEv(
 
@@ -24,3 +33,31 @@ __attribute__((dllexport)) void exported() {}
 // GNU-DAG: define weak_odr dso_local dllexport void @_Z15exported_inlinev(
 __declspec(dllexport) inline void exported_inline() {}
 USE(exported_inline)
+
+__attribute__((dllexport)) DEFAULT void exported_default() {}
+
+// MSVC-DAG: define protected dllexport void @"?exported_protected@@YAXXZ"(
+// GNU-DAG: define protected dllexport void @_Z18exported_protectedv(
+#pragma GCC visibility push(protected)
+__attribute__((dllexport)) void exported_protected() {}
+#pragma GCC visibility pop
+
+#if defined(ERR1)
+// expected-error at +1 {{non-default visibility cannot be applied to 'dllimport' declaration}}
+__attribute__((dllimport)) HIDDEN void imported_hidden();
+
+// expected-error at +1 {{hidden visibility cannot be applied to 'dllexport' declaration}}
+__attribute__((dllexport)) HIDDEN void exported_hidden() { imported_hidden(); }
+
+#elif defined(ERR2)
+// expected-error at +1 {{non-default visibility cannot be applied to 'dllimport' declaration}}
+__attribute__((dllimport)) PROTECTED void imported_protected();
+
+void foo() { imported_protected(); }
+
+#elif defined(ERR3)
+struct HIDDEN C2 {
+  // expected-error at +1 {{hidden visibility cannot be applied to 'dllexport' declaration}}
+  __attribute__((dllexport)) void exported_hidden() {}
+};
+#endif


        


More information about the cfe-commits mailing list