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
13extern "C" {
14  void part1();
15  void part2();
16}
17
18//===-- compilation unit part1 without main function ----------------------===//
19
20#ifdef PART1
21struct A {
22  int x;
23  int y;
24};
25
26struct B {
27  float m;
28  double n;
29};
30
31union U {
32  float f;
33  double d;
34};
35
36// Same struct in both main and part1.
37struct S {
38  int s1;
39  int s2;
40};
41
42// Different structs with the same name in main and part1.
43struct D {
44  int d1;
45  int d2;
46  struct {
47    int x;
48    int y;
49    int z;
50  } ds[10];
51};
52
53void 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.
78void part2()
79{
80  // do nothing
81}
82#endif // PART2
83
84//===-- compilation unit with main function -------------------------------===//
85
86#ifdef MAIN
87class C {
88public:
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.
101struct S {
102  int s1;
103  int s2;
104};
105
106// Different structs with the same name in main and part1.
107struct D {
108  int d1;
109  int d2;
110  int d3;
111};
112
113int 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