1 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s --check-prefixes=CHECK,ALIGN 2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s --check-prefixes=CHECK,NULL 3 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment,null -DCHECK_LAMBDA | FileCheck %s --check-prefixes=LAMBDA 4 5 // CHECK-LABEL: define void @_Z22load_non_null_pointersv 6 void load_non_null_pointers() { 7 int var; 8 var = *&var; 9 10 int arr[1]; 11 arr[0] = arr[0]; 12 13 char c = "foo"[0]; 14 15 // CHECK-NOT: and i64 {{.*}}, !nosanitize 16 // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize 17 // CHECK: ret void 18 } 19 20 // CHECK-LABEL: define void @_Z31use_us16_aligned_array_elementsv 21 void use_us16_aligned_array_elements() { 22 static const unsigned short Arr[] = {0, 1, 2}; 23 auto use_array = [](const unsigned short(&X)[3]) -> void {}; 24 use_array(Arr); 25 26 // CHECK-NOT: br i1 true 27 // ALIGN-NOT: call void @__ubsan_handle_type_mismatch 28 // CHECK: ret void 29 } 30 31 struct A { 32 int foo; 33 34 // CHECK-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv 35 void do_nothing() { 36 // ALIGN: %[[THISINT1:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize 37 // ALIGN: and i64 %[[THISINT1]], 3, !nosanitize 38 // NULL: icmp ne %struct.A* %[[THIS1:[a-z0-9]+]], null, !nosanitize 39 // NULL: ptrtoint %struct.A* %[[THIS1]] to i64, !nosanitize 40 // CHECK: call void @__ubsan_handle_type_mismatch 41 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 42 // CHECK: ret void 43 } 44 45 #ifdef CHECK_LAMBDA 46 // LAMBDA-LABEL: define linkonce_odr void @_ZN1A22do_nothing_with_lambdaEv 47 void do_nothing_with_lambda() { 48 // LAMBDA: icmp ne %struct.A* %[[THIS2:[a-z0-9]+]], null, !nosanitize 49 // LAMBDA: %[[THISINT2:[0-9]+]] = ptrtoint %struct.A* %[[THIS2]] to i64, !nosanitize 50 // LAMBDA: and i64 %[[THISINT2]], 3, !nosanitize 51 // LAMBDA: call void @__ubsan_handle_type_mismatch 52 53 auto f = [&] { 54 foo = 0; 55 }; 56 f(); 57 58 // LAMBDA-NOT: call void @__ubsan_handle_type_mismatch 59 // LAMBDA: ret void 60 } 61 62 // Check the IR for the lambda: 63 // 64 // LAMBDA-LABEL: define linkonce_odr void @_ZZN1A22do_nothing_with_lambdaEvENKUlvE_clEv 65 // LAMBDA: call void @__ubsan_handle_type_mismatch 66 // LAMBDA-NOT: call void @__ubsan_handle_type_mismatch 67 // LAMBDA: ret void 68 #endif 69 70 // CHECK-LABEL: define linkonce_odr i32 @_ZN1A11load_memberEv 71 int load_member() { 72 // ALIGN: %[[THISINT3:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize 73 // ALIGN: and i64 %[[THISINT3]], 3, !nosanitize 74 // NULL: icmp ne %struct.A* %[[THIS3:[a-z0-9]+]], null, !nosanitize 75 // NULL: ptrtoint %struct.A* %[[THIS3]] to i64, !nosanitize 76 // CHECK: call void @__ubsan_handle_type_mismatch 77 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 78 return foo; 79 // CHECK: ret i32 80 } 81 82 // CHECK-LABEL: define linkonce_odr i32 @_ZN1A11call_methodEv 83 int call_method() { 84 // ALIGN: %[[THISINT4:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize 85 // ALIGN: and i64 %[[THISINT4]], 3, !nosanitize 86 // NULL: icmp ne %struct.A* %[[THIS4:[a-z0-9]+]], null, !nosanitize 87 // NULL: ptrtoint %struct.A* %[[THIS4]] to i64, !nosanitize 88 // CHECK: call void @__ubsan_handle_type_mismatch 89 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 90 return load_member(); 91 // CHECK: ret i32 92 } 93 94 // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_1Ev 95 void assign_member_1() { 96 // ALIGN: %[[THISINT5:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize 97 // ALIGN: and i64 %[[THISINT5]], 3, !nosanitize 98 // NULL: icmp ne %struct.A* %[[THIS5:[a-z0-9]+]], null, !nosanitize 99 // NULL: ptrtoint %struct.A* %[[THIS5]] to i64, !nosanitize 100 // CHECK: call void @__ubsan_handle_type_mismatch 101 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 102 foo = 0; 103 // CHECK: ret void 104 } 105 106 // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_2Ev 107 void assign_member_2() { 108 // ALIGN: %[[THISINT6:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize 109 // ALIGN: and i64 %[[THISINT6]], 3, !nosanitize 110 // NULL: icmp ne %struct.A* %[[THIS6:[a-z0-9]+]], null, !nosanitize 111 // NULL: ptrtoint %struct.A* %[[THIS6]] to i64, !nosanitize 112 // CHECK: call void @__ubsan_handle_type_mismatch 113 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 114 (__extension__ (this))->foo = 0; 115 // CHECK: ret void 116 } 117 118 // CHECK-LABEL: define linkonce_odr void @_ZNK1A15assign_member_3Ev 119 void assign_member_3() const { 120 // ALIGN: %[[THISINT7:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize 121 // ALIGN: and i64 %[[THISINT7]], 3, !nosanitize 122 // NULL: icmp ne %struct.A* %[[THIS7:[a-z0-9]+]], null, !nosanitize 123 // NULL: ptrtoint %struct.A* %[[THIS7]] to i64, !nosanitize 124 // CHECK: call void @__ubsan_handle_type_mismatch 125 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 126 const_cast<A *>(this)->foo = 0; 127 // CHECK: ret void 128 } 129 130 // CHECK-LABEL: define linkonce_odr i32 @_ZN1A22call_through_referenceERS_ 131 static int call_through_reference(A &a) { 132 // ALIGN: %[[OBJINT:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize 133 // ALIGN: and i64 %[[OBJINT]], 3, !nosanitize 134 // ALIGN: call void @__ubsan_handle_type_mismatch 135 // NULL-NOT: call void @__ubsan_handle_type_mismatch 136 return a.load_member(); 137 // CHECK: ret i32 138 } 139 140 // CHECK-LABEL: define linkonce_odr i32 @_ZN1A20call_through_pointerEPS_ 141 static int call_through_pointer(A *a) { 142 // CHECK: call void @__ubsan_handle_type_mismatch 143 return a->load_member(); 144 // CHECK: ret i32 145 } 146 }; 147 148 struct B { 149 operator A*() const { return nullptr; } 150 151 // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEPS_ 152 static int load_member(B *bp) { 153 // Check &b before converting it to an A*. 154 // CHECK: call void @__ubsan_handle_type_mismatch 155 // 156 // Check the result of the conversion before using it. 157 // NULL: call void @__ubsan_handle_type_mismatch 158 // 159 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 160 return static_cast<A *>(*bp)->load_member(); 161 // CHECK: ret i32 162 } 163 }; 164 165 struct Base { 166 int foo; 167 168 virtual int load_member_1() = 0; 169 }; 170 171 struct Derived : public Base { 172 int bar; 173 174 // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_2Ev 175 int load_member_2() { 176 // ALIGN: %[[THISINT8:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize 177 // ALIGN: and i64 %[[THISINT8]], 7, !nosanitize 178 // ALIGN: call void @__ubsan_handle_type_mismatch 179 // NULL: icmp ne %struct.Derived* %[[THIS8:[a-z0-9]+]], null, !nosanitize 180 // NULL: ptrtoint %struct.Derived* %[[THIS8]] to i64, !nosanitize 181 // CHECK: call void @__ubsan_handle_type_mismatch 182 // 183 // Check the result of the cast before using it. 184 // CHECK: call void @__ubsan_handle_type_mismatch 185 // 186 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 187 return dynamic_cast<Base *>(this)->load_member_1(); 188 // CHECK: ret i32 189 } 190 191 // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_3Ev 192 int load_member_3() { 193 // ALIGN: %[[THISINT9:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize 194 // ALIGN: and i64 %[[THISINT9]], 7, !nosanitize 195 // ALIGN: call void @__ubsan_handle_type_mismatch 196 // ALIGN: call void @__ubsan_handle_type_mismatch 197 // NULL: icmp ne %struct.Derived* %[[THIS9:[a-z0-9]+]], null, !nosanitize 198 // NULL: ptrtoint %struct.Derived* %[[THIS9]] to i64, !nosanitize 199 // CHECK: call void @__ubsan_handle_type_mismatch 200 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 201 return reinterpret_cast<Derived *>(static_cast<Base *>(this))->foo; 202 // CHECK: ret i32 203 } 204 205 // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_1Ev 206 int load_member_1() override { 207 // ALIGN: %[[THISINT10:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize 208 // ALIGN: and i64 %[[THISINT10]], 7, !nosanitize 209 // ALIGN: call void @__ubsan_handle_type_mismatch 210 // NULL: icmp ne %struct.Derived* %[[THIS10:[a-z0-9]+]], null, !nosanitize 211 // NULL: ptrtoint %struct.Derived* %[[THIS10]] to i64, !nosanitize 212 // CHECK: call void @__ubsan_handle_type_mismatch 213 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 214 return foo + bar; 215 // CHECK: ret i32 216 } 217 }; 218 219 void force_irgen() { 220 A *a; 221 a->do_nothing(); 222 #ifdef CHECK_LAMBDA 223 a->do_nothing_with_lambda(); 224 #endif 225 a->load_member(); 226 a->call_method(); 227 a->assign_member_1(); 228 a->assign_member_2(); 229 a->assign_member_3(); 230 A::call_through_reference(*a); 231 A::call_through_pointer(a); 232 233 B::load_member(nullptr); 234 235 Base *b = new Derived; 236 b->load_member_1(); 237 238 Derived *d; 239 d->load_member_2(); 240 d->load_member_3(); 241 242 load_non_null_pointers(); 243 use_us16_aligned_array_elements(); 244 } 245