1*7c3d14c8STreehugger Robot // RUN: %clang_esan_frag -O0 %s -DPART1 -mllvm -esan-aux-field-info=0 -c -o %t-part1.o 2>&1
2*7c3d14c8STreehugger Robot // RUN: %clang_esan_frag -O0 %s -DPART2 -c -o %t-part2.o 2>&1
3*7c3d14c8STreehugger Robot // RUN: %clang_esan_frag -O0 %s -DMAIN -c -o %t-main.o 2>&1
4*7c3d14c8STreehugger Robot // RUN: %clang_esan_frag -O0 %t-part1.o %t-part2.o %t-main.o -o %t 2>&1
5*7c3d14c8STreehugger Robot // RUN: %env_esan_opts=verbosity=2 %run %t 2>&1 | FileCheck %s
6*7c3d14c8STreehugger Robot
7*7c3d14c8STreehugger Robot // We generate two different object files from this file with different
8*7c3d14c8STreehugger Robot // macros, and then link them together. We do this to test how we handle
9*7c3d14c8STreehugger Robot // separate compilation with multiple compilation units.
10*7c3d14c8STreehugger Robot
11*7c3d14c8STreehugger Robot #include <stdio.h>
12*7c3d14c8STreehugger Robot
13*7c3d14c8STreehugger Robot extern "C" {
14*7c3d14c8STreehugger Robot void part1();
15*7c3d14c8STreehugger Robot void part2();
16*7c3d14c8STreehugger Robot }
17*7c3d14c8STreehugger Robot
18*7c3d14c8STreehugger Robot //===-- compilation unit part1 without main function ----------------------===//
19*7c3d14c8STreehugger Robot
20*7c3d14c8STreehugger Robot #ifdef PART1
21*7c3d14c8STreehugger Robot struct A {
22*7c3d14c8STreehugger Robot int x;
23*7c3d14c8STreehugger Robot int y;
24*7c3d14c8STreehugger Robot };
25*7c3d14c8STreehugger Robot
26*7c3d14c8STreehugger Robot struct B {
27*7c3d14c8STreehugger Robot float m;
28*7c3d14c8STreehugger Robot double n;
29*7c3d14c8STreehugger Robot };
30*7c3d14c8STreehugger Robot
31*7c3d14c8STreehugger Robot union U {
32*7c3d14c8STreehugger Robot float f;
33*7c3d14c8STreehugger Robot double d;
34*7c3d14c8STreehugger Robot };
35*7c3d14c8STreehugger Robot
36*7c3d14c8STreehugger Robot // Same struct in both main and part1.
37*7c3d14c8STreehugger Robot struct S {
38*7c3d14c8STreehugger Robot int s1;
39*7c3d14c8STreehugger Robot int s2;
40*7c3d14c8STreehugger Robot };
41*7c3d14c8STreehugger Robot
42*7c3d14c8STreehugger Robot // Different structs with the same name in main and part1.
43*7c3d14c8STreehugger Robot struct D {
44*7c3d14c8STreehugger Robot int d1;
45*7c3d14c8STreehugger Robot int d2;
46*7c3d14c8STreehugger Robot struct {
47*7c3d14c8STreehugger Robot int x;
48*7c3d14c8STreehugger Robot int y;
49*7c3d14c8STreehugger Robot int z;
50*7c3d14c8STreehugger Robot } ds[10];
51*7c3d14c8STreehugger Robot };
52*7c3d14c8STreehugger Robot
part1()53*7c3d14c8STreehugger Robot void part1()
54*7c3d14c8STreehugger Robot {
55*7c3d14c8STreehugger Robot struct A a;
56*7c3d14c8STreehugger Robot struct B b;
57*7c3d14c8STreehugger Robot union U u;
58*7c3d14c8STreehugger Robot struct S s;
59*7c3d14c8STreehugger Robot struct D d;
60*7c3d14c8STreehugger Robot for (int i = 0; i < (1 << 11); i++)
61*7c3d14c8STreehugger Robot a.x = 0;
62*7c3d14c8STreehugger Robot a.y = 1;
63*7c3d14c8STreehugger Robot b.m = 2.0;
64*7c3d14c8STreehugger Robot for (int i = 0; i < (1 << 21); i++) {
65*7c3d14c8STreehugger Robot b.n = 3.0;
66*7c3d14c8STreehugger Robot d.ds[3].y = 0;
67*7c3d14c8STreehugger Robot }
68*7c3d14c8STreehugger Robot u.f = 0.0;
69*7c3d14c8STreehugger Robot u.d = 1.0;
70*7c3d14c8STreehugger Robot s.s1 = 0;
71*7c3d14c8STreehugger Robot d.d1 = 0;
72*7c3d14c8STreehugger Robot }
73*7c3d14c8STreehugger Robot #endif // PART1
74*7c3d14c8STreehugger Robot
75*7c3d14c8STreehugger Robot //===-- compilation unit part2 without main function ----------------------===//
76*7c3d14c8STreehugger Robot #ifdef PART2
77*7c3d14c8STreehugger Robot // No struct in this part.
part2()78*7c3d14c8STreehugger Robot void part2()
79*7c3d14c8STreehugger Robot {
80*7c3d14c8STreehugger Robot // do nothing
81*7c3d14c8STreehugger Robot }
82*7c3d14c8STreehugger Robot #endif // PART2
83*7c3d14c8STreehugger Robot
84*7c3d14c8STreehugger Robot //===-- compilation unit with main function -------------------------------===//
85*7c3d14c8STreehugger Robot
86*7c3d14c8STreehugger Robot #ifdef MAIN
87*7c3d14c8STreehugger Robot class C {
88*7c3d14c8STreehugger Robot public:
89*7c3d14c8STreehugger Robot struct {
90*7c3d14c8STreehugger Robot int x;
91*7c3d14c8STreehugger Robot int y;
92*7c3d14c8STreehugger Robot } cs;
93*7c3d14c8STreehugger Robot union {
94*7c3d14c8STreehugger Robot float f;
95*7c3d14c8STreehugger Robot double d;
96*7c3d14c8STreehugger Robot } cu;
97*7c3d14c8STreehugger Robot char c[10];
98*7c3d14c8STreehugger Robot };
99*7c3d14c8STreehugger Robot
100*7c3d14c8STreehugger Robot // Same struct in both main and part1.
101*7c3d14c8STreehugger Robot struct S {
102*7c3d14c8STreehugger Robot int s1;
103*7c3d14c8STreehugger Robot int s2;
104*7c3d14c8STreehugger Robot };
105*7c3d14c8STreehugger Robot
106*7c3d14c8STreehugger Robot // Different structs with the same name in main and part1.
107*7c3d14c8STreehugger Robot struct D {
108*7c3d14c8STreehugger Robot int d1;
109*7c3d14c8STreehugger Robot int d2;
110*7c3d14c8STreehugger Robot int d3;
111*7c3d14c8STreehugger Robot };
112*7c3d14c8STreehugger Robot
main(int argc,char ** argv)113*7c3d14c8STreehugger Robot int main(int argc, char **argv) {
114*7c3d14c8STreehugger Robot // CHECK: in esan::initializeLibrary
115*7c3d14c8STreehugger Robot // CHECK: in esan::initializeCacheFrag
116*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCompilationUnitInit
117*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 6 class(es)/struct(s)
118*7c3d14c8STreehugger Robot // CHECK-NEXT: Register struct.A#2#11#11: 2 fields
119*7c3d14c8STreehugger Robot // CHECK-NEXT: Register struct.B#2#3#2: 2 fields
120*7c3d14c8STreehugger Robot // CHECK-NEXT: Register union.U#1#3: 1 fields
121*7c3d14c8STreehugger Robot // CHECK-NEXT: Register struct.S#2#11#11: 2 fields
122*7c3d14c8STreehugger Robot // CHECK-NEXT: Register struct.D#3#14#11#11: 3 fields
123*7c3d14c8STreehugger Robot // CHECK-NEXT: Register struct.anon#3#11#11#11: 3 fields
124*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCompilationUnitInit
125*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 0 class(es)/struct(s)
126*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCompilationUnitInit
127*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s)
128*7c3d14c8STreehugger Robot // CHECK-NEXT: Register class.C#3#14#13#13: 3 fields
129*7c3d14c8STreehugger Robot // CHECK-NEXT: Register struct.anon#2#11#11: 2 fields
130*7c3d14c8STreehugger Robot // CHECK-NEXT: Register union.anon#1#3: 1 fields
131*7c3d14c8STreehugger Robot // CHECK-NEXT: Duplicated struct.S#2#11#11: 2 fields
132*7c3d14c8STreehugger Robot // CHECK-NEXT: Register struct.D#3#11#11#11: 3 fields
133*7c3d14c8STreehugger Robot struct C c[2];
134*7c3d14c8STreehugger Robot struct S s;
135*7c3d14c8STreehugger Robot struct D d;
136*7c3d14c8STreehugger Robot c[0].cs.x = 0;
137*7c3d14c8STreehugger Robot c[1].cs.y = 1;
138*7c3d14c8STreehugger Robot c[0].cu.f = 0.0;
139*7c3d14c8STreehugger Robot c[1].cu.d = 1.0;
140*7c3d14c8STreehugger Robot c[0].c[2] = 0;
141*7c3d14c8STreehugger Robot s.s1 = 0;
142*7c3d14c8STreehugger Robot d.d1 = 0;
143*7c3d14c8STreehugger Robot d.d2 = 0;
144*7c3d14c8STreehugger Robot part1();
145*7c3d14c8STreehugger Robot part2();
146*7c3d14c8STreehugger Robot return 0;
147*7c3d14c8STreehugger Robot // CHECK: in esan::finalizeLibrary
148*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::finalizeCacheFrag
149*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCompilationUnitExit
150*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s)
151*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister class.C#3#14#13#13: 3 fields
152*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} class C
153*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} size = 32, count = 5, ratio = 3, array access = 5
154*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 8, count = 2, type = %struct.anon = type { i32, i32 }
155*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 1: offset = 8, size = 8, count = 2, type = %union.anon = type { double }
156*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 2: offset = 16, size = 10, count = 1, type = [10 x i8]
157*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister struct.anon#2#11#11: 2 fields
158*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} struct anon
159*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} size = 8, count = 2, ratio = 1, array access = 0
160*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32
161*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32
162*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister union.anon#1#3: 1 fields
163*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister struct.S#2#11#11: 2 fields
164*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} struct S
165*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} size = 8, count = 2, ratio = 2, array access = 0
166*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 0: count = 2
167*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 1: count = 0
168*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister struct.D#3#11#11#11: 3 fields
169*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} struct D
170*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} size = 12, count = 2, ratio = 2, array access = 0
171*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32
172*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32
173*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 2: offset = 8, size = 4, count = 0, type = i32
174*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCompilationUnitExit
175*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 0 class(es)/struct(s)
176*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCompilationUnitExit
177*7c3d14c8STreehugger Robot // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 6 class(es)/struct(s)
178*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister struct.A#2#11#11: 2 fields
179*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} struct A
180*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} size = 8, count = 2049, ratio = 2048, array access = 0
181*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 0: count = 2048
182*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 1: count = 1
183*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister struct.B#2#3#2: 2 fields
184*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} struct B
185*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} size = 16, count = 2097153, ratio = 2097152, array access = 0
186*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 0: count = 1
187*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 1: count = 2097152
188*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister union.U#1#3: 1 fields
189*7c3d14c8STreehugger Robot // CHECK-NEXT: Duplicated struct.S#2#11#11: 2 fields
190*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister struct.D#3#14#11#11: 3 fields
191*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} struct D
192*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} size = 128, count = 2097153, ratio = 2097153, array access = 0
193*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 0: count = 1
194*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 1: count = 0
195*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 2: count = 2097152
196*7c3d14c8STreehugger Robot // CHECK-NEXT: Unregister struct.anon#3#11#11#11: 3 fields
197*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} struct anon
198*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} size = 12, count = 2097152, ratio = 4194304, array access = 2097152
199*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 0: count = 0
200*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 1: count = 2097152
201*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}} # 2: count = 0
202*7c3d14c8STreehugger Robot // CHECK-NEXT: {{.*}}EfficiencySanitizer: total struct field access count = 6293518
203*7c3d14c8STreehugger Robot }
204*7c3d14c8STreehugger Robot #endif // MAIN
205