| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 1 | // RUN: %clang_esan_frag -O0 %s -DPART1 -c -o %t-part1.o 2>&1 |
| 2 | // RUN: %clang_esan_frag -O0 %s -DPART2 -c -o %t-part2.o 2>&1 |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 3 | // RUN: %clang_esan_frag -O0 %s -DMAIN -c -o %t-main.o 2>&1 |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 4 | // RUN: %clang_esan_frag -O0 %t-part1.o %t-part2.o %t-main.o -o %t 2>&1 |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 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" { |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 14 | void part1(); |
| 15 | void part2(); |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 16 | } |
| 17 | |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 18 | //===-- compilation unit part1 without main function ----------------------===// |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 19 | |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 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 | }; |
| 47 | |
| 48 | void part1() |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 49 | { |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 50 | struct A a; |
| 51 | struct B b; |
| 52 | union U u; |
| 53 | struct S s; |
| 54 | struct D d; |
| 55 | for (int i = 0; i < (1 << 11); i++) |
| 56 | a.x = 0; |
| 57 | a.y = 1; |
| 58 | b.m = 2.0; |
| 59 | for (int i = 0; i < (1 << 21); i++) |
| 60 | b.n = 3.0; |
| 61 | u.f = 0.0; |
| 62 | u.d = 1.0; |
| 63 | s.s1 = 0; |
| 64 | d.d1 = 0; |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 65 | } |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 66 | #endif // PART1 |
| 67 | |
| 68 | //===-- compilation unit part2 without main function ----------------------===// |
| 69 | #ifdef PART2 |
| 70 | // No struct in this part. |
| 71 | void part2() |
| 72 | { |
| 73 | // do nothing |
| 74 | } |
| 75 | #endif // PART2 |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 76 | |
| 77 | //===-- compilation unit with main function -------------------------------===// |
| 78 | |
| 79 | #ifdef MAIN |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 80 | class C { |
| 81 | public: |
| 82 | struct { |
| 83 | int x; |
| 84 | int y; |
| 85 | } cs; |
| 86 | union { |
| 87 | float f; |
| 88 | double d; |
| 89 | } cu; |
| 90 | char c[10]; |
| 91 | }; |
| 92 | |
| 93 | // Same struct in both main and part1. |
| 94 | struct S { |
| 95 | int s1; |
| 96 | int s2; |
| 97 | }; |
| 98 | |
| 99 | // Different structs with the same name in main and part1. |
| 100 | struct D { |
| 101 | int d1; |
| 102 | int d2; |
| 103 | int d3; |
| 104 | }; |
| 105 | |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 106 | int main(int argc, char **argv) { |
| 107 | // CHECK: in esan::initializeLibrary |
| Qin Zhao | 7e4933f | 2016-05-25 17:49:00 +0000 | [diff] [blame] | 108 | // CHECK: in esan::initializeCacheFrag |
| 109 | // CHECK-NEXT: in esan::processCompilationUnitInit |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 110 | // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s) |
| 111 | // CHECK-NEXT: Register struct.A#2#11#11: 2 fields |
| 112 | // CHECK-NEXT: Register struct.B#2#3#2: 2 fields |
| 113 | // CHECK-NEXT: Register union.U#1#3: 1 fields |
| 114 | // CHECK-NEXT: Register struct.S#2#11#11: 2 fields |
| 115 | // CHECK-NEXT: Register struct.D#2#11#11: 2 fields |
| Qin Zhao | 7e4933f | 2016-05-25 17:49:00 +0000 | [diff] [blame] | 116 | // CHECK-NEXT: in esan::processCompilationUnitInit |
| Qin Zhao | 9e39638 | 2016-05-31 21:27:39 +0000 | [diff] [blame] | 117 | // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 0 class(es)/struct(s) |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 118 | // CHECK-NEXT: in esan::processCompilationUnitInit |
| 119 | // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s) |
| 120 | // CHECK-NEXT: Register class.C#3#14#13#13: 3 fields |
| 121 | // CHECK-NEXT: Register struct.anon#2#11#11: 2 fields |
| 122 | // CHECK-NEXT: Register union.anon#1#3: 1 fields |
| 123 | // CHECK-NEXT: Duplicated struct.S#2#11#11: 2 fields |
| 124 | // CHECK-NEXT: Register struct.D#3#11#11#11: 3 fields |
| 125 | struct C c[2]; |
| 126 | struct S s; |
| 127 | struct D d; |
| 128 | c[0].cs.x = 0; |
| 129 | c[1].cs.y = 1; |
| 130 | c[0].cu.f = 0.0; |
| 131 | c[1].cu.d = 1.0; |
| 132 | c[0].c[2] = 0; |
| 133 | s.s1 = 0; |
| 134 | d.d1 = 0; |
| 135 | d.d2 = 0; |
| 136 | part1(); |
| 137 | part2(); |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 138 | return 0; |
| Qin Zhao | 7e4933f | 2016-05-25 17:49:00 +0000 | [diff] [blame] | 139 | // CHECK: in esan::finalizeLibrary |
| 140 | // CHECK-NEXT: in esan::finalizeCacheFrag |
| Qin Zhao | 7e4933f | 2016-05-25 17:49:00 +0000 | [diff] [blame] | 141 | // CHECK-NEXT: in esan::processCompilationUnitExit |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 142 | // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s) |
| 143 | // CHECK-NEXT: Unregister class.C#3#14#13#13: 3 fields |
| Qin Zhao | bc929e4 | 2016-06-03 20:48:17 +0000 | [diff] [blame] | 144 | // CHECK-NEXT: {{.*}} class C |
| Qin Zhao | a4a7220 | 2016-06-10 02:10:34 +0000 | [diff] [blame] | 145 | // CHECK-NEXT: {{.*}} size = 32, count = 5, ratio = 3 |
| Qin Zhao | e24bc36 | 2016-06-17 04:50:11 +0000 | [diff] [blame] | 146 | // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 8, count = 2, type = %struct.anon = type { i32, i32 } |
| 147 | // CHECK-NEXT: {{.*}} # 1: offset = 8, size = 8, count = 2, type = %union.anon = type { double } |
| 148 | // CHECK-NEXT: {{.*}} # 2: offset = 16, size = 10, count = 1, type = [10 x i8] |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 149 | // CHECK-NEXT: Unregister struct.anon#2#11#11: 2 fields |
| Qin Zhao | bc929e4 | 2016-06-03 20:48:17 +0000 | [diff] [blame] | 150 | // CHECK-NEXT: {{.*}} struct anon |
| Qin Zhao | a4a7220 | 2016-06-10 02:10:34 +0000 | [diff] [blame] | 151 | // CHECK-NEXT: {{.*}} size = 8, count = 2, ratio = 1 |
| Qin Zhao | e24bc36 | 2016-06-17 04:50:11 +0000 | [diff] [blame] | 152 | // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32 |
| 153 | // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32 |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 154 | // CHECK-NEXT: Unregister union.anon#1#3: 1 fields |
| 155 | // CHECK-NEXT: Unregister struct.S#2#11#11: 2 fields |
| Qin Zhao | bc929e4 | 2016-06-03 20:48:17 +0000 | [diff] [blame] | 156 | // CHECK-NEXT: {{.*}} struct S |
| Qin Zhao | a4a7220 | 2016-06-10 02:10:34 +0000 | [diff] [blame] | 157 | // CHECK-NEXT: {{.*}} size = 8, count = 2, ratio = 2 |
| Qin Zhao | e24bc36 | 2016-06-17 04:50:11 +0000 | [diff] [blame] | 158 | // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 2, type = i32 |
| 159 | // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 0, type = i32 |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 160 | // CHECK-NEXT: Unregister struct.D#3#11#11#11: 3 fields |
| Qin Zhao | bc929e4 | 2016-06-03 20:48:17 +0000 | [diff] [blame] | 161 | // CHECK-NEXT: {{.*}} struct D |
| Qin Zhao | a4a7220 | 2016-06-10 02:10:34 +0000 | [diff] [blame] | 162 | // CHECK-NEXT: {{.*}} size = 12, count = 2, ratio = 2 |
| Qin Zhao | e24bc36 | 2016-06-17 04:50:11 +0000 | [diff] [blame] | 163 | // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32 |
| 164 | // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32 |
| 165 | // CHECK-NEXT: {{.*}} # 2: offset = 8, size = 4, count = 0, type = i32 |
| Qin Zhao | 7e4933f | 2016-05-25 17:49:00 +0000 | [diff] [blame] | 166 | // CHECK-NEXT: in esan::processCompilationUnitExit |
| Qin Zhao | 9e39638 | 2016-05-31 21:27:39 +0000 | [diff] [blame] | 167 | // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 0 class(es)/struct(s) |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 168 | // CHECK-NEXT: in esan::processCompilationUnitExit |
| 169 | // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s) |
| 170 | // CHECK-NEXT: Unregister struct.A#2#11#11: 2 fields |
| Qin Zhao | bc929e4 | 2016-06-03 20:48:17 +0000 | [diff] [blame] | 171 | // CHECK-NEXT: {{.*}} struct A |
| Qin Zhao | a4a7220 | 2016-06-10 02:10:34 +0000 | [diff] [blame] | 172 | // CHECK-NEXT: {{.*}} size = 8, count = 2049, ratio = 2048 |
| Qin Zhao | e24bc36 | 2016-06-17 04:50:11 +0000 | [diff] [blame] | 173 | // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 2048, type = i32 |
| 174 | // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32 |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 175 | // CHECK-NEXT: Unregister struct.B#2#3#2: 2 fields |
| Qin Zhao | bc929e4 | 2016-06-03 20:48:17 +0000 | [diff] [blame] | 176 | // CHECK-NEXT: {{.*}} struct B |
| Qin Zhao | a4a7220 | 2016-06-10 02:10:34 +0000 | [diff] [blame] | 177 | // CHECK-NEXT: {{.*}} size = 16, count = 2097153, ratio = 2097152 |
| Qin Zhao | e24bc36 | 2016-06-17 04:50:11 +0000 | [diff] [blame] | 178 | // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = float |
| 179 | // CHECK-NEXT: {{.*}} # 1: offset = 8, size = 8, count = 2097152, type = double |
| Qin Zhao | 4175a6d | 2016-06-02 18:45:25 +0000 | [diff] [blame] | 180 | // CHECK-NEXT: Unregister union.U#1#3: 1 fields |
| 181 | // CHECK-NEXT: Duplicated struct.S#2#11#11: 2 fields |
| 182 | // CHECK-NEXT: Unregister struct.D#2#11#11: 2 fields |
| Qin Zhao | bc929e4 | 2016-06-03 20:48:17 +0000 | [diff] [blame] | 183 | // CHECK-NEXT: {{.*}} struct D |
| Qin Zhao | a4a7220 | 2016-06-10 02:10:34 +0000 | [diff] [blame] | 184 | // CHECK-NEXT: {{.*}} size = 8, count = 1, ratio = 1 |
| Qin Zhao | e24bc36 | 2016-06-17 04:50:11 +0000 | [diff] [blame] | 185 | // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32 |
| 186 | // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 0, type = i32 |
| Qin Zhao | bc929e4 | 2016-06-03 20:48:17 +0000 | [diff] [blame] | 187 | // CHECK-NEXT: {{.*}}EfficiencySanitizer: total struct field access count = 2099214 |
| Derek Bruening | 515c15c | 2016-05-24 23:03:52 +0000 | [diff] [blame] | 188 | } |
| 189 | #endif // MAIN |