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 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. 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 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