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:[^,]*]], ptr null }] 164 165 // FIXME: Should this use __cxa_guard_acquire? 166 // CHECK: define {{.*}} @[[E_INIT]]() 167 // CHECK: load {{.*}} ptr @_ZGV 168 // CHECK: store {{.*}}, ptr @[[E]], 169 170 // FIXME: Should this use __cxa_guard_acquire? 171 // CHECK: define {{.*}} @[[F_INIT]]() 172 // CHECK: load {{.*}} ptr @_ZGV 173 // CHECK: store {{.*}}, ptr @[[F]], 174 175 // CHECK: define {{.*}} @[[G_INIT:__cxx_global.*]]() 176 // CHECK: load {{.*}} ptr @_ZGV 177 // CHECK: [[G_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @[[G]]) 178 // CHECK: store {{.*}}, ptr [[G_ADDR]] 179 180 // CHECK: define {{.*}} @[[H_INIT:__cxx_global.*]]() 181 // CHECK: load {{.*}} ptr @_ZGV 182 // CHECK: [[H_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @[[H]]) 183 // CHECK: store {{.*}}, ptr [[H_ADDR]], 184 185 // FIXME: Should this use __cxa_guard_acquire? 186 // CHECK: define {{.*}} @[[XA_INIT]]() 187 // CHECK: load {{.*}} ptr @_ZGV 188 // CHECK: store {{.*}}, ptr @[[XA]], 189 190 // CHECK: define {{.*}} @[[XC_INIT:__cxx_global.*]]() 191 // CHECK: load {{.*}} ptr @_ZGV 192 // CHECK: [[XC_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @[[XC]]) 193 // CHECK: store {{.*}}, ptr [[XC_ADDR]], 194 195 // FIXME: Should this use __cxa_guard_acquire? 196 // CHECK: define {{.*}} @[[XE_INIT]]() 197 // CHECK: load {{.*}} ptr @_ZGV 198 // CHECK: store {{.*}}, ptr @[[XE]], 199 200 // CHECK: define {{.*}} @[[XG_INIT:__cxx_global.*]]() 201 // CHECK: load {{.*}} ptr @_ZGV 202 // CHECK: [[XG_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @[[XG]]) 203 // CHECK: store {{.*}}, ptr [[XG_ADDR]], 204 205 // CHECK: define {{.*}} @[[XH_INIT:__cxx_global.*]]() 206 // CHECK: load {{.*}} ptr @_ZGV 207 // CHECK: [[XH_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @[[XH]]) 208 // CHECK: store {{.*}}, ptr [[XH_ADDR]], 209 210 // FIXME: Should this use __cxa_guard_acquire? 211 // CHECK: define {{.*}} @[[XF_INIT]]() 212 // CHECK: load {{.*}} ptr @_ZGV 213 // CHECK: store {{.*}}, ptr @[[XF]], 214 215 // CHECK: define {{.*}} @[[XD_INIT:__cxx_global.*]]() 216 // CHECK: load {{.*}} ptr @_ZGV 217 // CHECK: [[XD_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @[[XD]]) 218 // CHECK: store {{.*}}, ptr [[XD_ADDR]], 219 220 // FIXME: Should this use __cxa_guard_acquire? 221 // CHECK: define {{.*}} @[[XB_INIT]]() 222 // CHECK: load {{.*}} ptr @_ZGV 223 // CHECK: store {{.*}}, ptr @[[XB]], 224 225 // CHECK-IMPORT: define {{.*}} @[[A_INIT:__cxx_global.*]]() 226 // CHECK-IMPORT: call noundef i32 @_Z11non_trivialv( 227 // CHECK-IMPORT: store {{.*}}, ptr @[[A]], 228 229 // CHECK-IMPORT: define {{.*}} @[[B_INIT:__cxx_global.*]]() 230 // CHECK-IMPORT: call i32 @__cxa_guard_acquire(ptr @_ZGV 231 // CHECK-IMPORT: store {{.*}}, ptr @[[B]], 232 233 // CHECK-IMPORT: define {{.*}} @[[C_INIT:__cxx_global.*]]() 234 // CHECK-IMPORT: call noundef i32 @_Z11non_trivialv( 235 // CHECK-IMPORT: [[C_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @[[C]]) 236 // CHECK-IMPORT: store {{.*}}, ptr [[C_ADDR]], 237 238 // CHECK-IMPORT: define {{.*}} @[[D_INIT:__cxx_global.*]]() 239 // CHECK-IMPORT: load {{.*}} ptr @_ZGV 240 // CHECK-IMPORT: [[D_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @[[D]]) 241 // CHECK-IMPORT: store {{.*}}, ptr [[D_ADDR]], 242 243 244 // CHECK-IMPORT: define {{.*}} @[[TU_INIT]]() 245 // CHECK-IMPORT: call void @[[A_INIT]]() 246 247 // CHECK-IMPORT: define {{.*}} @__tls_init() 248 // CHECK-IMPORT: call void @[[C_INIT]]() 249 // CHECK-IMPORT: call void @[[D_INIT]]() 250