[PATCH] D101156: [Clang] Support a user-defined __dso_handle

Andrew Savonichev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon May 24 03:54:11 PDT 2021


asavonic updated this revision to Diff 347341.
asavonic edited the summary of this revision.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101156/new/

https://reviews.llvm.org/D101156

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/dso-handle-custom.cpp


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - -DHIDDEN | FileCheck %s --check-prefixes CHECK,CHECK-HIDDEN
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK-DEFAULT: @__dso_handle = global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK-HIDDEN: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** @__dso_handle to i8*))
+
+#ifdef HIDDEN
+void *__dso_handle __attribute__((__visibility__("hidden"))) = &__dso_handle;
+#else
+void *__dso_handle = &__dso_handle;
+#endif
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -4337,6 +4337,23 @@
   }
 
   llvm::Type* InitType = Init->getType();
+
+  bool ReplaceInitWithGV = false;
+  llvm::GlobalValue *OrigEntry = GetGlobalValue(getMangledName(D));
+  if (Init == OrigEntry && OrigEntry->getValueType() != InitType) {
+    // Type of the initializer does not match the type of the global -
+    // GetAddrOfGlobalVar is going to recreate it, replace all uses of
+    // the original entry and erase the original entry from the
+    // module.
+    //
+    // However, if Init is an address of the global itself, then it is
+    // not a use, and thus it will not be replaced. It will become a
+    // dangling pointer after GetAddrOfGlobalVar. Replace it once we
+    // get a new GV.
+    //
+    ReplaceInitWithGV = true;
+  }
+
   llvm::Constant *Entry =
       GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative));
 
@@ -4404,6 +4421,9 @@
     getCUDARuntime().handleVarRegistration(D, *GV);
   }
 
+  if (ReplaceInitWithGV)
+    Init = llvm::ConstantExpr::getBitCast(GV, GV->getValueType());
+
   GV->setInitializer(Init);
   if (emitter)
     emitter->finalize(GV);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101156.347341.patch
Type: text/x-patch
Size: 2379 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210524/78f4f15d/attachment.bin>


More information about the cfe-commits mailing list