124 lines · c
1// RUN: %clang_cc1 -x c -triple x86_64-apple-darwin10 -w -emit-llvm -o - %s -fsanitize=pointer-overflow | FileCheck %s2// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -w -emit-llvm -o - %s -fsanitize=pointer-overflow | FileCheck %s3 4#ifdef __cplusplus5extern "C" {6#endif7 8// CHECK-LABEL: define{{.*}} void @fixed_len_array9void fixed_len_array(int k) {10 // CHECK: getelementptr inbounds [10 x [10 x i32]], ptr [[ARR:%.*]], i64 0, i64 [[IDXPROM:%.*]]11 // CHECK-NEXT: [[SMUL:%.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 40, i64 [[IDXPROM]]), !nosanitize12 // CHECK-NEXT: [[SMULOFLOW:%.*]] = extractvalue { i64, i1 } [[SMUL]], 1, !nosanitize13 // CHECK-NEXT: [[OR:%.+]] = or i1 [[SMULOFLOW]], false, !nosanitize14 // CHECK-NEXT: [[SMULVAL:%.*]] = extractvalue { i64, i1 } [[SMUL]], 0, !nosanitize15 // CHECK-NEXT: [[BASE:%.*]] = ptrtoint ptr [[ARR]] to i64, !nosanitize16 // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], [[SMULVAL]], !nosanitize17 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}, i64 [[BASE]], i64 [[COMPGEP]]){{.*}}, !nosanitize18 19 // CHECK: getelementptr inbounds [10 x i32], ptr {{.*}}, i64 0, i64 [[IDXPROM1:%.*]]20 // CHECK-NEXT: @llvm.smul.with.overflow.i64(i64 4, i64 [[IDXPROM1]]), !nosanitize21 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}22 23 int arr[10][10];24 arr[k][k];25}26 27// CHECK-LABEL: define{{.*}} void @variable_len_array28void variable_len_array(int n, int k) {29 // CHECK: getelementptr inbounds i32, ptr {{.*}}, i64 [[IDXPROM:%.*]]30 // CHECK-NEXT: @llvm.smul.with.overflow.i64(i64 4, i64 [[IDXPROM]]), !nosanitize31 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}32 33 // CHECK: getelementptr inbounds i32, ptr {{.*}}, i64 [[IDXPROM1:%.*]]34 // CHECK-NEXT: @llvm.smul.with.overflow.i64(i64 4, i64 [[IDXPROM1]]), !nosanitize35 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}36 37 int arr[n][n];38 arr[k][k];39}40 41// CHECK-LABEL: define{{.*}} void @pointer_array42void pointer_array(int **arr, int k) {43 // CHECK: @llvm.smul.with.overflow.i64(i64 8, i64 {{.*}}), !nosanitize44 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}45 46 // CHECK: @llvm.smul.with.overflow.i64(i64 4, i64 {{.*}}), !nosanitize47 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}48 49 arr[k][k];50}51 52// CHECK-LABEL: define{{.*}} void @pointer_array_unsigned_indices53void pointer_array_unsigned_indices(int **arr, unsigned k) {54 // CHECK: icmp uge55 // CHECK-NOT: select56 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}57 // CHECK: icmp uge58 // CHECK-NOT: select59 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}60 arr[k][k];61}62 63// CHECK-LABEL: define{{.*}} void @pointer_array_mixed_indices64void pointer_array_mixed_indices(int **arr, int i, unsigned j) {65 // CHECK: select66 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}67 // CHECK-NOT: select68 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}69 arr[i][j];70}71 72struct S1 {73 int pad1;74 union {75 char leaf;76 struct S1 *link;77 } u;78 struct S1 *arr;79};80 81// TODO: Currently, structure GEPs are not checked, so there are several82// potentially unsafe GEPs here which we don't instrument.83//84// CHECK-LABEL: define{{.*}} void @struct_index85void struct_index(struct S1 *p) {86 // CHECK: getelementptr inbounds %struct.S1, ptr [[P:%.*]], i64 1087 // CHECK-NEXT: [[BASE:%.*]] = ptrtoint ptr [[P]] to i64, !nosanitize88 // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], 240, !nosanitize89 // CHECK: select90 // CHECK: @__ubsan_handle_pointer_overflow{{.*}} i64 [[BASE]], i64 [[COMPGEP]]) {{.*}}, !nosanitize91 92 // CHECK-NOT: @__ubsan_handle_pointer_overflow93 94 p->arr[10].u.link->u.leaf;95}96 97typedef void (*funcptr_t)(void);98 99// CHECK-LABEL: define{{.*}} void @function_pointer_arith100void function_pointer_arith(funcptr_t *p, int k) {101 // CHECK: add i64 {{.*}}, 8, !nosanitize102 // CHECK-NOT: select103 // CHECK: @__ubsan_handle_pointer_overflow{{.*}}104 ++p;105 106 // CHECK: @llvm.smul.with.overflow.i64(i64 8, i64 {{.*}}), !nosanitize107 // CHECK: select108 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}109 p + k;110}111 112// CHECK-LABEL: define{{.*}} void @dont_emit_checks_for_no_op_GEPs113// CHECK-NOT: __ubsan_handle_pointer_overflow114void dont_emit_checks_for_no_op_GEPs(char *p) {115 &p[0];116 117 int arr[10][10];118 &arr[0][0];119}120 121#ifdef __cplusplus122}123#endif124