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