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 
use(bool b,...)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