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 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/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/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]]()