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