1 // RUN: %clang_cc1 -x c -triple x86_64-apple-darwin10 -w -emit-llvm -o - %s -fsanitize=pointer-overflow | FileCheck %s 2 // RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -w -emit-llvm -o - %s -fsanitize=pointer-overflow | FileCheck %s 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 // CHECK-LABEL: define{{.*}} void @fixed_len_array 9 void 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]]), !nosanitize 12 // CHECK-NEXT: [[SMULOFLOW:%.*]] = extractvalue { i64, i1 } [[SMUL]], 1, !nosanitize 13 // CHECK-NEXT: [[OR:%.+]] = or i1 [[SMULOFLOW]], false, !nosanitize 14 // CHECK-NEXT: [[SMULVAL:%.*]] = extractvalue { i64, i1 } [[SMUL]], 0, !nosanitize 15 // CHECK-NEXT: [[BASE:%.*]] = ptrtoint ptr [[ARR]] to i64, !nosanitize 16 // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], [[SMULVAL]], !nosanitize 17 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}, i64 [[BASE]], i64 [[COMPGEP]]){{.*}}, !nosanitize 18 19 // CHECK: getelementptr inbounds [10 x i32], ptr {{.*}}, i64 0, i64 [[IDXPROM1:%.*]] 20 // CHECK-NEXT: @llvm.smul.with.overflow.i64(i64 4, i64 [[IDXPROM1]]), !nosanitize 21 // 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_array 28 void 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]]), !nosanitize 31 // 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]]), !nosanitize 35 // 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_array 42 void pointer_array(int **arr, int k) { 43 // CHECK: @llvm.smul.with.overflow.i64(i64 8, i64 {{.*}}), !nosanitize 44 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} 45 46 // CHECK: @llvm.smul.with.overflow.i64(i64 4, i64 {{.*}}), !nosanitize 47 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} 48 49 arr[k][k]; 50 } 51 52 // CHECK-LABEL: define{{.*}} void @pointer_array_unsigned_indices 53 void pointer_array_unsigned_indices(int **arr, unsigned k) { 54 // CHECK: icmp uge 55 // CHECK-NOT: select 56 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} 57 // CHECK: icmp uge 58 // CHECK-NOT: select 59 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} 60 arr[k][k]; 61 } 62 63 // CHECK-LABEL: define{{.*}} void @pointer_array_mixed_indices 64 void pointer_array_mixed_indices(int **arr, int i, unsigned j) { 65 // CHECK: select 66 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} 67 // CHECK-NOT: select 68 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} 69 arr[i][j]; 70 } 71 72 struct 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 several 82 // potentially unsafe GEPs here which we don't instrument. 83 // 84 // CHECK-LABEL: define{{.*}} void @struct_index 85 void struct_index(struct S1 *p) { 86 // CHECK: getelementptr inbounds %struct.S1, ptr [[P:%.*]], i64 10 87 // CHECK-NEXT: [[BASE:%.*]] = ptrtoint ptr [[P]] to i64, !nosanitize 88 // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], 240, !nosanitize 89 // CHECK: select 90 // CHECK: @__ubsan_handle_pointer_overflow{{.*}} i64 [[BASE]], i64 [[COMPGEP]]) {{.*}}, !nosanitize 91 92 // CHECK-NOT: @__ubsan_handle_pointer_overflow 93 94 p->arr[10].u.link->u.leaf; 95 } 96 97 typedef void (*funcptr_t)(void); 98 99 // CHECK-LABEL: define{{.*}} void @function_pointer_arith 100 void function_pointer_arith(funcptr_t *p, int k) { 101 // CHECK: add i64 {{.*}}, 8, !nosanitize 102 // CHECK-NOT: select 103 // CHECK: @__ubsan_handle_pointer_overflow{{.*}} 104 ++p; 105 106 // CHECK: @llvm.smul.with.overflow.i64(i64 8, i64 {{.*}}), !nosanitize 107 // CHECK: select 108 // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} 109 p + k; 110 } 111 112 // CHECK-LABEL: define{{.*}} void @dont_emit_checks_for_no_op_GEPs 113 // CHECK-NOT: __ubsan_handle_pointer_overflow 114 void 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 __cplusplus 122 } 123 #endif 124