r344190 - [AST] Use -fvisibility value when ignoring -fv-i-h* inline static locals

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 10 14:59:56 PDT 2018


Author: rnk
Date: Wed Oct 10 14:59:56 2018
New Revision: 344190

URL: http://llvm.org/viewvc/llvm-project?rev=344190&view=rev
Log:
[AST] Use -fvisibility value when ignoring -fv-i-h* inline static locals

Summary:
In r340386 we added code to give static locals in inline functions
default visibility. Instead, we should use the "default" visibility
passed on the command line, which could be hidden or protected, as GCC
does.

Some code bases use both -fvisibility=hidden and
-fvisibility-inlines-hidden to hide inline functions of classes that are
explicitly marked with default visibility.

Fixes PR39236

Reviewers: hans, thakis

Subscribers: eraman, llvm-commits

Differential Revision: https://reviews.llvm.org/D53052

Modified:
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=344190&r1=344189&r2=344190&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Oct 10 14:59:56 2018
@@ -725,7 +725,7 @@ LinkageComputer::getLVForNamespaceScopeD
       // If we're paying attention to global visibility, apply
       // -finline-visibility-hidden if this is an inline method.
       if (useInlineVisibilityHidden(D))
-        LV.mergeVisibility(HiddenVisibility, true);
+        LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false);
     }
   }
 
@@ -915,7 +915,7 @@ LinkageComputer::getLVForClassMember(con
     // Note that we do this before merging information about
     // the class visibility.
     if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D))
-      LV.mergeVisibility(HiddenVisibility, true);
+      LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false);
   }
 
   // If this class member has an explicit visibility attribute, the only
@@ -1265,14 +1265,24 @@ LinkageInfo LinkageComputer::getLVForLoc
     // If a function is hidden by -fvisibility-inlines-hidden option and
     // is not explicitly attributed as a hidden function,
     // we should not make static local variables in the function hidden.
+    LV = getLVForDecl(FD, computation);
     if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
-        !(!hasExplicitVisibilityAlready(computation) &&
-          getExplicitVisibility(FD, computation))) {
+        !LV.isVisibilityExplicit()) {
       assert(cast<VarDecl>(D)->isStaticLocal());
-      return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false);
+      // If this was an implicitly hidden inline method, check again for
+      // explicit visibility on the parent class, and use that for static locals
+      // if present.
+      if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
+        LV = getLVForDecl(MD->getParent(), computation);
+      if (!LV.isVisibilityExplicit()) {
+        Visibility globalVisibility =
+            computation.isValueVisibility()
+                ? Context.getLangOpts().getValueVisibilityMode()
+                : Context.getLangOpts().getTypeVisibilityMode();
+        return LinkageInfo(VisibleNoLinkage, globalVisibility,
+                           /*visibilityExplicit=*/false);
+      }
     }
-
-    LV = getLVForDecl(FD, computation);
   }
   if (!isExternallyVisible(LV.getLinkage()))
     return LinkageInfo::none();

Modified: cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp?rev=344190&r1=344189&r2=344190&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp Wed Oct 10 14:59:56 2018
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
 // RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck -check-prefixes=CHECK-NO-VIH %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility hidden -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-VIS-HIDDEN
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility protected -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-VIS-PROTECTED
 
 // When a function is hidden due to -fvisibility-inlines-hidden option, static local variables of the function should not be hidden by the option.
 
@@ -9,12 +11,15 @@
 // CHECK-DAG: @_ZZ11inline_funcvE3var = linkonce_odr global i32 0, comdat
 // CHECK-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
 // CHECK-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
 // CHECK-DAG: define i32 @_Z4funcv()
 // CHECK-DAG: define hidden i32 @_Z11hidden_funcv()
 // CHECK-DAG: define i32 @_Z12default_funcv()
 // CHECK-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
 // CHECK-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
 // CHECK-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
 
 // CHECK-NO-VIH-DAG: @_ZZ4funcvE3var = internal global i32 0
 // CHECK-NO-VIH-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
@@ -22,13 +27,47 @@
 // CHECK-NO-VIH-DAG: @_ZZ11inline_funcvE3var = linkonce_odr global i32 0, comdat
 // CHECK-NO-VIH-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
 // CHECK-NO-VIH-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-NO-VIH-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
 // CHECK-NO-VIH-DAG: define i32 @_Z4funcv()
 // CHECK-NO-VIH-DAG: define hidden i32 @_Z11hidden_funcv()
 // CHECK-NO-VIH-DAG: define i32 @_Z12default_funcv()
 // CHECK-NO-VIH-DAG: define linkonce_odr i32 @_Z11inline_funcv()
 // CHECK-NO-VIH-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
 // CHECK-NO-VIH-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-NO-VIH-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
 
+// CHECK-VIS-HIDDEN-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ11inline_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-VIS-HIDDEN-DAG: define hidden i32 @_Z4funcv()
+// CHECK-VIS-HIDDEN-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-VIS-HIDDEN-DAG: define i32 @_Z12default_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-VIS-HIDDEN-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+// CHECK-VIS-PROTECTED-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ11inline_funcvE3var = linkonce_odr protected global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-VIS-PROTECTED-DAG: define protected i32 @_Z4funcv()
+// CHECK-VIS-PROTECTED-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-VIS-PROTECTED-DAG: define i32 @_Z12default_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-VIS-PROTECTED-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
 
 int func(void) {
   static int var = 0;
@@ -54,6 +93,14 @@ inline int __attribute__((visibility("de
   static int var = 0;
   return var++;
 }
+struct __attribute__((visibility("default"))) ExportedClass {
+  int inl_method() {
+    static int var = 0;
+    return var++;
+  }
+  int ext_method();
+};
+int ExportedClass::ext_method() { return inl_method(); }
 void bar(void) {
   func();
   inline_func();
@@ -62,4 +109,3 @@ void bar(void) {
   default_func();
   inline_default_func();
 }
-




More information about the cfe-commits mailing list