[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