1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DIMPORT=1 -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-IMPORT,CHECK-NO-NS,CHECK-IMPORT-NO-NS --implicit-check-not=unused 2 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DIMPORT=1 -DNS -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-IMPORT,CHECK-NS,CHECK-IMPORT-NS --implicit-check-not=unused 3 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DIMPORT=2 -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NO-NS --implicit-check-not=unused 4 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DIMPORT=2 -DNS -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NS --implicit-check-not=unused 5 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NO-NS --implicit-check-not=unused 6 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DNS -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NS --implicit-check-not=unused 7 8 // Check that we behave sensibly when importing a header containing strong and 9 // weak, ordered and unordered global initializers. 10 // 11 // Our behavior is as follows: 12 // 13 // -- for variables with one or more specific points of initialization 14 // (non-template variables, whether or not they are inline or thread_local), 15 // emit them if (and only if) a header containing a point of initialization 16 // is transitively #included / imported. 17 // 18 // -- for variables with unordered initialization (any kind of templated 19 // variable -- excluding explicit specializations), emit them if any part 20 // of any module that triggers an instantiation is imported. 21 // 22 // The intent is to: 23 // 24 // 1) preserve order of initialization guarantees 25 // 2) preserve the behavior of globals with ctors in headers, and specifically 26 // of std::ios_base::Init (do not run the iostreams initializer nor force 27 // linking in the iostreams portion of the static library unless <iostream> 28 // is included) 29 // 3) behave conservatively-correctly with regard to unordered initializers: we 30 // might run them in cases where a traditional compilation would not, but 31 // will never fail to run them in cases where a traditional compilation 32 // would do so 33 // 34 // Perfect handling of unordered initializers would require tracking all 35 // submodules containing points of instantiation, which is very hard when those 36 // points of instantiation are within definitions that we skip because we 37 // already have a (non-visible) definition for the entity: 38 // 39 // // a.h 40 // template<typename> int v = f(); 41 // inline int get() { return v<int>; } 42 // 43 // // b.h 44 // template<typename> int v = f(); 45 // inline int get() { return v<int>; } 46 // 47 // If a.h and b.h are built as a module, we will only have a point of 48 // instantiation for v<int> in one of the two headers, because we will only 49 // parse one of the two get() functions. 50 51 #pragma clang module build m 52 module m { 53 module a { 54 header "foo.h" { size 123 mtime 456789 } 55 } 56 module b {} 57 } 58 59 #pragma clang module contents 60 #pragma clang module begin m.a 61 inline int non_trivial() { return 3; } 62 63 #ifdef NS 64 namespace ns { 65 #endif 66 67 int a = non_trivial(); 68 inline int b = non_trivial(); 69 thread_local int c = non_trivial(); 70 inline thread_local int d = non_trivial(); 71 72 template<typename U> int e = non_trivial(); 73 template<typename U> inline int f = non_trivial(); 74 template<typename U> thread_local int g = non_trivial(); 75 template<typename U> inline thread_local int h = non_trivial(); 76 77 inline int unused = 123; // should not be emitted 78 79 template<typename T> struct X { 80 static int a; 81 static inline int b = non_trivial(); 82 static thread_local int c; 83 static inline thread_local int d = non_trivial(); 84 85 template<typename U> static int e; 86 template<typename U> static inline int f = non_trivial(); 87 template<typename U> static thread_local int g; 88 template<typename U> static inline thread_local int h = non_trivial(); 89 90 static inline int unused = 123; // should not be emitted 91 }; 92 93 template<typename T> int X<T>::a = non_trivial(); 94 template<typename T> thread_local int X<T>::c = non_trivial(); 95 template<typename T> template<typename U> int X<T>::e = non_trivial(); 96 template<typename T> template<typename U> thread_local int X<T>::g = non_trivial(); 97 98 inline void use(bool b, ...) { 99 if (b) return; 100 use(true, e<int>, f<int>, g<int>, h<int>, 101 X<int>::a, X<int>::b, X<int>::c, X<int>::d, 102 X<int>::e<int>, X<int>::f<int>, X<int>::g<int>, X<int>::h<int>); 103 } 104 105 #ifdef NS 106 } 107 #endif 108 109 #pragma clang module end 110 #pragma clang module endbuild 111 112 #if IMPORT == 1 113 // Import the module and the m.a submodule; runs the ordered initializers and 114 // the unordered initializers. 115 #pragma clang module import m.a 116 #elif IMPORT == 2 117 // Import the module but not the m.a submodule; runs only the unordered 118 // initializers. 119 #pragma clang module import m.b 120 #else 121 // Load the module but do not import any submodules; runs only the unordered 122 // initializers. FIXME: Should this skip all of them? 123 #pragma clang module load m 124 #endif 125 126 // CHECK-IMPORT-NO-NS-DAG: @[[A:a]] = global i32 0, align 4 127 // CHECK-IMPORT-NO-NS-DAG: @[[B:b]] = linkonce_odr global i32 0, comdat, align 4 128 // CHECK-IMPORT-NO-NS-DAG: @[[C:c]] = thread_local global i32 0, align 4 129 // CHECK-IMPORT-NO-NS-DAG: @[[D:d]] = linkonce_odr thread_local global i32 0, comdat, align 4 130 // CHECK-NO-NS-DAG: @[[E:_Z1eIiE]] = linkonce_odr global i32 0, comdat, align 4 131 // CHECK-NO-NS-DAG: @[[F:_Z1fIiE]] = linkonce_odr global i32 0, comdat, align 4 132 // CHECK-NO-NS-DAG: @[[G:_Z1gIiE]] = linkonce_odr thread_local global i32 0, comdat, align 4 133 // CHECK-NO-NS-DAG: @[[H:_Z1hIiE]] = linkonce_odr thread_local global i32 0, comdat, align 4 134 135 // CHECK-IMPORT-NS-DAG: @[[A:_ZN2ns1aE]] = global i32 0, align 4 136 // CHECK-IMPORT-NS-DAG: @[[B:_ZN2ns1bE]] = linkonce_odr global i32 0, comdat, align 4 137 // CHECK-IMPORT-NS-DAG: @[[BG:_ZGVN2ns1bE]] = linkonce_odr global i64 0, comdat($[[B]]), align 8 138 // CHECK-IMPORT-NS-DAG: @[[C:_ZN2ns1cE]] = thread_local global i32 0, align 4 139 // CHECK-IMPORT-NS-DAG: @[[D:_ZN2ns1dE]] = linkonce_odr thread_local global i32 0, comdat, align 4 140 // CHECK-IMPORT-NS-DAG: @[[DG:_ZGVN2ns1dE]] = linkonce_odr thread_local global i64 0, comdat($[[D]]), align 8 141 // CHECK-NS-DAG: @[[E:_ZN2ns1eIiEE]] = linkonce_odr global i32 0, comdat, align 4 142 // CHECK-NS-DAG: @[[F:_ZN2ns1fIiEE]] = linkonce_odr global i32 0, comdat, align 4 143 // CHECK-NS-DAG: @[[G:_ZN2ns1gIiEE]] = linkonce_odr thread_local global i32 0, comdat, align 4 144 // CHECK-NS-DAG: @[[H:_ZN2ns1hIiEE]] = linkonce_odr thread_local global i32 0, comdat, align 4 145 146 // CHECK-DAG: @[[XA:_ZN(2ns)?1XIiE1aE]] = linkonce_odr global i32 0, comdat, align 4 147 // CHECK-DAG: @[[XB:_ZN(2ns)?1XIiE1bE]] = linkonce_odr global i32 0, comdat, align 4 148 // CHECK-DAG: @[[XC:_ZN(2ns)?1XIiE1cE]] = linkonce_odr thread_local global i32 0, comdat, align 4 149 // CHECK-DAG: @[[XD:_ZN(2ns)?1XIiE1dE]] = linkonce_odr thread_local global i32 0, comdat, align 4 150 // CHECK-DAG: @[[XE:_ZN(2ns)?1XIiE1eIiEE]] = linkonce_odr global i32 0, comdat, align 4 151 // CHECK-DAG: @[[XF:_ZN(2ns)?1XIiE1fIiEE]] = linkonce_odr global i32 0, comdat, align 4 152 // CHECK-DAG: @[[XG:_ZN(2ns)?1XIiE1gIiEE]] = linkonce_odr thread_local global i32 0, comdat, align 4 153 // CHECK-DAG: @[[XH:_ZN(2ns)?1XIiE1hIiEE]] = linkonce_odr thread_local global i32 0, comdat, align 4 154 155 // It's OK if the order of the first 6 of these changes. 156 // CHECK: @llvm.global_ctors = appending global 157 // CHECK-SAME: @[[E_INIT:[^,]*]], {{[^@]*}} @[[E]] 158 // CHECK-SAME: @[[F_INIT:[^,]*]], {{[^@]*}} @[[F]] 159 // CHECK-SAME: @[[XA_INIT:[^,]*]], {{[^@]*}} @[[XA]] 160 // CHECK-SAME: @[[XE_INIT:[^,]*]], {{[^@]*}} @[[XE]] 161 // CHECK-SAME: @[[XF_INIT:[^,]*]], {{[^@]*}} @[[XF]] 162 // CHECK-SAME: @[[XB_INIT:[^,]*]], {{[^@]*}} @[[XB]] 163 // CHECK-IMPORT-SAME: @[[TU_INIT:[^,]*]], i8* null }] 164 165 // FIXME: Should this use __cxa_guard_acquire? 166 // CHECK: define {{.*}} @[[E_INIT]]() 167 // CHECK: load {{.*}} (i64* @_ZGV 168 // CHECK: store {{.*}}, i32* @[[E]], 169 170 // FIXME: Should this use __cxa_guard_acquire? 171 // CHECK: define {{.*}} @[[F_INIT]]() 172 // CHECK: load {{.*}} (i64* @_ZGV 173 // CHECK: store {{.*}}, i32* @[[F]], 174 175 // CHECK: define {{.*}} @[[G_INIT:__cxx_global.*]]() 176 // CHECK: load {{.*}} (i64* @_ZGV 177 // CHECK: store {{.*}}, i32* @[[G]], 178 179 // CHECK: define {{.*}} @[[H_INIT:__cxx_global.*]]() 180 // CHECK: load {{.*}} (i64* @_ZGV 181 // CHECK: store {{.*}}, i32* @[[H]], 182 183 // FIXME: Should this use __cxa_guard_acquire? 184 // CHECK: define {{.*}} @[[XA_INIT]]() 185 // CHECK: load {{.*}} (i64* @_ZGV 186 // CHECK: store {{.*}}, i32* @[[XA]], 187 188 // CHECK: define {{.*}} @[[XC_INIT:__cxx_global.*]]() 189 // CHECK: load {{.*}} (i64* @_ZGV 190 // CHECK: store {{.*}}, i32* @[[XC]], 191 192 // FIXME: Should this use __cxa_guard_acquire? 193 // CHECK: define {{.*}} @[[XE_INIT]]() 194 // CHECK: load {{.*}} (i64* @_ZGV 195 // CHECK: store {{.*}}, i32* @[[XE]], 196 197 // CHECK: define {{.*}} @[[XG_INIT:__cxx_global.*]]() 198 // CHECK: load {{.*}} (i64* @_ZGV 199 // CHECK: store {{.*}}, i32* @[[XG]], 200 201 // CHECK: define {{.*}} @[[XH_INIT:__cxx_global.*]]() 202 // CHECK: load {{.*}} (i64* @_ZGV 203 // CHECK: store {{.*}}, i32* @[[XH]], 204 205 // FIXME: Should this use __cxa_guard_acquire? 206 // CHECK: define {{.*}} @[[XF_INIT]]() 207 // CHECK: load {{.*}} (i64* @_ZGV 208 // CHECK: store {{.*}}, i32* @[[XF]], 209 210 // CHECK: define {{.*}} @[[XD_INIT:__cxx_global.*]]() 211 // CHECK: load {{.*}} (i64* @_ZGV 212 // CHECK: store {{.*}}, i32* @[[XD]], 213 214 // FIXME: Should this use __cxa_guard_acquire? 215 // CHECK: define {{.*}} @[[XB_INIT]]() 216 // CHECK: load {{.*}} (i64* @_ZGV 217 // CHECK: store {{.*}}, i32* @[[XB]], 218 219 // CHECK-IMPORT: define {{.*}} @[[A_INIT:__cxx_global.*]]() 220 // CHECK-IMPORT: call i32 @_Z11non_trivialv( 221 // CHECK-IMPORT: store {{.*}}, i32* @[[A]], 222 223 // CHECK-IMPORT: define {{.*}} @[[B_INIT:__cxx_global.*]]() 224 // CHECK-IMPORT: call i32 @__cxa_guard_acquire(i64* @_ZGV 225 // CHECK-IMPORT: store {{.*}}, i32* @[[B]], 226 227 // CHECK-IMPORT: define {{.*}} @[[C_INIT:__cxx_global.*]]() 228 // CHECK-IMPORT: call i32 @_Z11non_trivialv( 229 // CHECK-IMPORT: store {{.*}}, i32* @[[C]], 230 231 // CHECK-IMPORT: define {{.*}} @[[D_INIT:__cxx_global.*]]() 232 // CHECK-IMPORT: load {{.*}} (i64* @_ZGV 233 // CHECK-IMPORT: store {{.*}}, i32* @[[D]], 234 235 236 // CHECK-IMPORT: define {{.*}} @[[TU_INIT]]() 237 // CHECK-IMPORT: call void @[[A_INIT]]() 238 239 // CHECK-IMPORT: define {{.*}} @__tls_init() 240 // CHECK-IMPORT: call void @[[C_INIT]]() 241 // CHECK-IMPORT: call void @[[D_INIT]]() 242