Author: inouehrs
Date: Tue Aug 21 22:43:27 2018
New Revision: 340386

URL: http://llvm.org/viewvc/llvm-project?rev=340386&view=rev
Log:
[AST] correct the behavior of -fvisibility-inlines-hidden option (don't make 
static local variables hidden)

The command line option -fvisibility-inlines-hidden makes inlined method 
hidden, but it is expected not to affect the visibility of static local 
variables in the function.
However, Clang makes the static local variables in the function also hidden as 
reported in PR37595. This problem causes LLVM bootstarp failure on Fedora 28 if 
configured with -DBUILD_SHARED_LIBS=ON.

This patch makes the behavior of -fvisibility-inlines-hidden option to be 
consistent with that of gcc; the option does not change the visibility of the 
static local variables if the containing function does not associated with 
explicit visibility attribute and becomes hidden due to this option.

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


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

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=340386&r1=340385&r2=340386&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue Aug 21 22:43:27 2018
@@ -1262,6 +1262,16 @@ LinkageInfo LinkageComputer::getLVForLoc
         !isTemplateInstantiation(FD->getTemplateSpecializationKind()))
       return LinkageInfo::none();
 
+    // 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.
+    if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
+        !(!hasExplicitVisibilityAlready(computation) &&
+          getExplicitVisibility(FD, computation))) {
+      assert(cast<VarDecl>(D)->isStaticLocal());
+      return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false);
+    }
+
     LV = getLVForDecl(FD, computation);
   }
   if (!isExternallyVisible(LV.getLinkage()))

Added: 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=340386&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp Tue Aug 
21 22:43:27 2018
@@ -0,0 +1,65 @@
+// 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
+
+// When a function is hidden due to -fvisibility-inlines-hidden option, static 
local variables of the function should not be hidden by the option.
+
+// CHECK-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// 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: 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-NO-VIH-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-NO-VIH-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-NO-VIH-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// 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: 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()
+
+
+int func(void) {
+  static int var = 0;
+  return var++;
+}
+inline int inline_func(void) {
+  static int var = 0;
+  return var++;
+}
+int __attribute__((visibility("hidden"))) hidden_func(void) {
+  static int var = 0;
+  return var++;
+}
+inline int __attribute__((visibility("hidden"))) inline_hidden_func(void) {
+  static int var = 0;
+  return var++;
+}
+int __attribute__((visibility("default"))) default_func(void) {
+  static int var = 0;
+  return var++;
+}
+inline int __attribute__((visibility("default"))) inline_default_func(void) {
+  static int var = 0;
+  return var++;
+}
+void bar(void) {
+  func();
+  inline_func();
+  hidden_func();
+  inline_hidden_func();
+  default_func();
+  inline_default_func();
+}
+


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to