[PATCH] D103495: [static initializers] Don't put ordered dynamic initializers of static variables into global_ctors

Wolfgang Pieb via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 1 16:55:44 PDT 2021


wolfgangp created this revision.
wolfgangp added reviewers: rnk, jyu2.
wolfgangp requested review of this revision.

Commit c19f4f8069 <https://github.com/llvm/llvm-project/commit/c19f4f8069722f6804086d4438a0254104242c46> caused some ordered dynamic initialization of static member variables to be treated like unordered initialization, i.e. put into global_ctors. This caused issues in some configurations, specifically when init_array is not used. This patch proposes to restrict this behaviour to the Microsoft ABI, where it is apparently necessary for correctness.

2 existing test cases are affected by this change.

This fixes PR50266.


https://reviews.llvm.org/D103495

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/static-init-order.cpp
  clang/test/Modules/initializers.cpp


Index: clang/test/Modules/initializers.cpp
===================================================================
--- clang/test/Modules/initializers.cpp
+++ clang/test/Modules/initializers.cpp
@@ -232,9 +232,9 @@
 // CHECK-IMPORT: load {{.*}} (i64* @_ZGV
 // CHECK-IMPORT: store {{.*}}, i32* @[[D]],
 
-
 // CHECK-IMPORT: define {{.*}} @[[TU_INIT]]()
 // CHECK-IMPORT: call void @[[A_INIT]]()
+// CHECK-IMPORT: call void @[[B_INIT]]()
 
 // CHECK-IMPORT: define {{.*}} @__tls_init()
 // CHECK-IMPORT: call void @[[C_INIT]]()
Index: clang/test/CodeGenCXX/static-init-order.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/static-init-order.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 %s -std=c++17 -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+// Make sure we generate a single initialization routine and put its address into the
+// global_ctors. Check that the initialization routine makes 2 calls to individual
+// initializer functions in the correct order.
+
+// CHECK:     @llvm.global_ctors = {{.*}}@[[INIT:_GLOBAL__sub_I[A-Za-z0-9_\.]+]]
+// CHECK:     define {{.*}} @[[VARINIT1:__cxx_global_var_init]]
+// CHECK-NOT: }
+// CHECK:     call void @_ZN1AC1Ev
+// CHECK:     define {{.*}} @[[VARINIT2:__cxx_global_var_init\.[0-9]+]]
+// CHECK-NOT: }
+// CHECK:     call void @_ZN1BC1Ev
+// CHECK:     define {{.*}} @[[INIT]]
+// CHECK-NOT: }
+// CHECK:     call void @[[VARINIT1]]
+// CHECK:     call void @[[VARINIT2]]
+
+class A {
+public:
+  A() {
+  }
+};
+
+class B {
+public:
+  B() {
+  }
+};
+
+class StaticsClass {
+private:
+  static inline A A_Var;
+  static inline B B_Var;
+};
Index: clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
===================================================================
--- clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
+++ clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
@@ -47,7 +47,7 @@
 // CHECK: @_ZGVN5test12t2E = linkonce_odr global i64 0, align 8
 // CHECK: @_ZGVN5test21AIvE8instanceE = weak_odr global i64 0, align 8
 // CHECK: @_ZGVN5test12t1IiEE = linkonce_odr global i64 0, align 8
-// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.2, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.4, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I__, i8* null }]
+// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.2, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.4, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I__, i8* null }]
 // CHECK: @llvm.global_dtors = appending global [4 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test12t2E, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test21AIvE8instanceE, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test12t1IiEE, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__D_a, i8* null }]
 
 // CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
Index: clang/lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -503,7 +503,8 @@
                                           PrioritizedCXXGlobalInits.size());
     PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
   } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
-             getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR) {
+             (getTarget().getCXXABI().isMicrosoft() &&
+              getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR)) {
     // C++ [basic.start.init]p2:
     //   Definitions of explicitly specialized class template static data
     //   members have ordered initialization. Other class template static data


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103495.349109.patch
Type: text/x-patch
Size: 4220 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210601/27a36db0/attachment.bin>


More information about the cfe-commits mailing list