245 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s --check-prefixes=CHECK,ALIGN2// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s --check-prefixes=CHECK,NULL3// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment,null -DCHECK_LAMBDA | FileCheck %s --check-prefixes=LAMBDA4 5// CHECK-LABEL: define{{.*}} void @_Z22load_non_null_pointersv6void 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 {{.*}}, !nosanitize16 // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize17 // CHECK: ret void18}19 20// CHECK-LABEL: define{{.*}} void @_Z31use_us16_aligned_array_elementsv21void 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 true27 // ALIGN-NOT: call void @__ubsan_handle_type_mismatch28 // CHECK: ret void29}30 31struct A {32 int foo;33 34 // CHECK-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv35 void do_nothing() {36 // ALIGN: %[[THISINT1:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize37 // ALIGN: and i64 %[[THISINT1]], 3, !nosanitize38 // NULL: icmp ne ptr %[[THIS1:[a-z0-9]+]], null, !nosanitize39 // NULL: ptrtoint ptr %[[THIS1]] to i64, !nosanitize40 // CHECK: call void @__ubsan_handle_type_mismatch41 // CHECK-NOT: call void @__ubsan_handle_type_mismatch42 // CHECK: ret void43 }44 45#ifdef CHECK_LAMBDA46 // LAMBDA-LABEL: define linkonce_odr void @_ZN1A22do_nothing_with_lambdaEv47 void do_nothing_with_lambda() {48 // LAMBDA: icmp ne ptr %[[THIS2:[a-z0-9]+]], null, !nosanitize49 // LAMBDA: %[[THISINT2:[0-9]+]] = ptrtoint ptr %[[THIS2]] to i64, !nosanitize50 // LAMBDA: and i64 %[[THISINT2]], 3, !nosanitize51 // LAMBDA: call void @__ubsan_handle_type_mismatch52 53 auto f = [&] {54 foo = 0;55 };56 f();57 58 // LAMBDA-NOT: call void @__ubsan_handle_type_mismatch59 // LAMBDA: ret void60 }61 62// Check the IR for the lambda:63//64// LAMBDA-LABEL: define linkonce_odr void @_ZZN1A22do_nothing_with_lambdaEvENKUlvE_clEv65// LAMBDA: call void @__ubsan_handle_type_mismatch66// LAMBDA-NOT: call void @__ubsan_handle_type_mismatch67// LAMBDA: ret void68#endif69 70 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN1A11load_memberEv71 int load_member() {72 // ALIGN: %[[THISINT3:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize73 // ALIGN: and i64 %[[THISINT3]], 3, !nosanitize74 // NULL: icmp ne ptr %[[THIS3:[a-z0-9]+]], null, !nosanitize75 // NULL: ptrtoint ptr %[[THIS3]] to i64, !nosanitize76 // CHECK: call void @__ubsan_handle_type_mismatch77 // CHECK-NOT: call void @__ubsan_handle_type_mismatch78 return foo;79 // CHECK: ret i3280 }81 82 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN1A11call_methodEv83 int call_method() {84 // ALIGN: %[[THISINT4:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize85 // ALIGN: and i64 %[[THISINT4]], 3, !nosanitize86 // NULL: icmp ne ptr %[[THIS4:[a-z0-9]+]], null, !nosanitize87 // NULL: ptrtoint ptr %[[THIS4]] to i64, !nosanitize88 // CHECK: call void @__ubsan_handle_type_mismatch89 // CHECK-NOT: call void @__ubsan_handle_type_mismatch90 return load_member();91 // CHECK: ret i3292 }93 94 // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_1Ev95 void assign_member_1() {96 // ALIGN: %[[THISINT5:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize97 // ALIGN: and i64 %[[THISINT5]], 3, !nosanitize98 // NULL: icmp ne ptr %[[THIS5:[a-z0-9]+]], null, !nosanitize99 // NULL: ptrtoint ptr %[[THIS5]] to i64, !nosanitize100 // CHECK: call void @__ubsan_handle_type_mismatch101 // CHECK-NOT: call void @__ubsan_handle_type_mismatch102 foo = 0;103 // CHECK: ret void104 }105 106 // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_2Ev107 void assign_member_2() {108 // ALIGN: %[[THISINT6:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize109 // ALIGN: and i64 %[[THISINT6]], 3, !nosanitize110 // NULL: icmp ne ptr %[[THIS6:[a-z0-9]+]], null, !nosanitize111 // NULL: ptrtoint ptr %[[THIS6]] to i64, !nosanitize112 // CHECK: call void @__ubsan_handle_type_mismatch113 // CHECK-NOT: call void @__ubsan_handle_type_mismatch114 (__extension__ (this))->foo = 0;115 // CHECK: ret void116 }117 118 // CHECK-LABEL: define linkonce_odr void @_ZNK1A15assign_member_3Ev119 void assign_member_3() const {120 // ALIGN: %[[THISINT7:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize121 // ALIGN: and i64 %[[THISINT7]], 3, !nosanitize122 // NULL: icmp ne ptr %[[THIS7:[a-z0-9]+]], null, !nosanitize123 // NULL: ptrtoint ptr %[[THIS7]] to i64, !nosanitize124 // CHECK: call void @__ubsan_handle_type_mismatch125 // CHECK-NOT: call void @__ubsan_handle_type_mismatch126 const_cast<A *>(this)->foo = 0;127 // CHECK: ret void128 }129 130 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN1A22call_through_referenceERS_131 static int call_through_reference(A &a) {132 // ALIGN: %[[OBJINT:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize133 // ALIGN: and i64 %[[OBJINT]], 3, !nosanitize134 // ALIGN: call void @__ubsan_handle_type_mismatch135 // NULL-NOT: call void @__ubsan_handle_type_mismatch136 return a.load_member();137 // CHECK: ret i32138 }139 140 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN1A20call_through_pointerEPS_141 static int call_through_pointer(A *a) {142 // CHECK: call void @__ubsan_handle_type_mismatch143 return a->load_member();144 // CHECK: ret i32145 }146};147 148struct B {149 operator A*() const { return nullptr; }150 151 // CHECK-LABEL: define linkonce_odr noundef 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_mismatch155 //156 // Check the result of the conversion before using it.157 // NULL: call void @__ubsan_handle_type_mismatch158 //159 // CHECK-NOT: call void @__ubsan_handle_type_mismatch160 return static_cast<A *>(*bp)->load_member();161 // CHECK: ret i32162 }163};164 165struct Base {166 int foo;167 168 virtual int load_member_1() = 0;169};170 171struct Derived : public Base {172 int bar;173 174 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7Derived13load_member_2Ev175 int load_member_2() {176 // ALIGN: %[[THISINT8:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize177 // ALIGN: and i64 %[[THISINT8]], 7, !nosanitize178 // ALIGN: call void @__ubsan_handle_type_mismatch179 // NULL: icmp ne ptr %[[THIS8:[a-z0-9]+]], null, !nosanitize180 // NULL: ptrtoint ptr %[[THIS8]] to i64, !nosanitize181 // CHECK: call void @__ubsan_handle_type_mismatch182 //183 // Check the result of the cast before using it.184 // CHECK: call void @__ubsan_handle_type_mismatch185 //186 // CHECK-NOT: call void @__ubsan_handle_type_mismatch187 return dynamic_cast<Base *>(this)->load_member_1();188 // CHECK: ret i32189 }190 191 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7Derived13load_member_3Ev192 int load_member_3() {193 // ALIGN: %[[THISINT9:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize194 // ALIGN: and i64 %[[THISINT9]], 7, !nosanitize195 // ALIGN: call void @__ubsan_handle_type_mismatch196 // ALIGN: call void @__ubsan_handle_type_mismatch197 // NULL: icmp ne ptr %[[THIS9:[a-z0-9]+]], null, !nosanitize198 // NULL: ptrtoint ptr %[[THIS9]] to i64, !nosanitize199 // CHECK: call void @__ubsan_handle_type_mismatch200 // CHECK-NOT: call void @__ubsan_handle_type_mismatch201 return reinterpret_cast<Derived *>(static_cast<Base *>(this))->foo;202 // CHECK: ret i32203 }204 205 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7Derived13load_member_1Ev206 int load_member_1() override {207 // ALIGN: %[[THISINT10:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize208 // ALIGN: and i64 %[[THISINT10]], 7, !nosanitize209 // ALIGN: call void @__ubsan_handle_type_mismatch210 // NULL: icmp ne ptr %[[THIS10:[a-z0-9]+]], null, !nosanitize211 // NULL: ptrtoint ptr %[[THIS10]] to i64, !nosanitize212 // CHECK: call void @__ubsan_handle_type_mismatch213 // CHECK-NOT: call void @__ubsan_handle_type_mismatch214 return foo + bar;215 // CHECK: ret i32216 }217};218 219void force_irgen() {220 A *a;221 a->do_nothing();222#ifdef CHECK_LAMBDA223 a->do_nothing_with_lambda();224#endif225 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