[PATCH] D50968: [AST] make a static local variable in a hidden inlined fuction visible

Hiroshi Inoue via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 20 05:46:50 PDT 2018


inouehrs created this revision.
inouehrs added reviewers: rnk, doug.gregor, rsmith.
Herald added subscribers: JDevlieghere, eraman.

LLVM bootstarp fails due to a SEGV in `DebugInfo/PDB/pdbdump-debug-subsections.test` on PPC64le Fedora 28 if configured with -DBUILD_SHARED_LIBS=ON.
This SEGV is caused by `make_shared` in the C++ standard library because two copies of a hidden function `_Sp_make_shared_tag::_S_ti()` are created in `llvm-pdbutil` binary and `libLLVMObjectYAML.so`. Two copies of a static local variable `__tag` in this function are also created and this results in the malfunction of `make_shared`.
`_Sp_make_shared_tag::_S_ti()` is marked as hidden due to -fvisibility-inlines-hidden option.

This patch makes static local variable in a method marked as hidden by -fvisibility-inlines-hidden visible from linker by setting the visibility default. As long as I tested, gcc does not mark `__tag` hidden.

Alternatively we can remove -fvisibility-inlines-hidden from LLVM build options, but it may increase the binary size more significantly. Also I think that this is not unique to our problem; other programs using -fvisibility-inlines-hidden may hit the same problem.


https://reviews.llvm.org/D50968

Files:
  lib/AST/Decl.cpp
  test/CodeGenCXX/visibility-inlines-hidden.cpp


Index: test/CodeGenCXX/visibility-inlines-hidden.cpp
===================================================================
--- test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -36,6 +36,18 @@
 
 extern template struct X1<float>;
 
+// CHECK: @_ZZN5test73fooEvE3var = linkonce_odr global i32 0, comdat
+namespace test7 {
+  inline int foo(void) {
+    static int var = 0;
+    var++;
+    return var;
+  }
+  void bar(void) {
+    foo();
+  }
+}
+
 void use(X0 *x0, X1<int> *x1, X2 *x2, X1<float> *x3) {
   // CHECK-LABEL: define linkonce_odr void @_ZN2X02f1Ev
   x0->f1();
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -1262,6 +1262,16 @@
         !isTemplateInstantiation(FD->getTemplateSpecializationKind()))
       return LinkageInfo::none();
 
+    // Hiding a static local variable in an hidden function may
+    // affect the behavior of the program by having multiple copies of the
+    // variable in the program and dynamic link libraries.
+    // To avoid such problem, we make a static local variable visible from
+    // the linker even the containing function is hidden from the linker.
+    if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD)) {
+      assert(cast<VarDecl>(D)->isStaticLocal());
+      return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false);
+    }
+
     LV = getLVForDecl(FD, computation);
   }
   if (!isExternallyVisible(LV.getLinkage()))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50968.161462.patch
Type: text/x-patch
Size: 1522 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180820/d0dceb32/attachment.bin>


More information about the llvm-commits mailing list