124 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \2// RUN: -fsafe-buffer-usage-suggestions \3// RUN: -triple=arm-apple \4// RUN: -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s5 6int f(unsigned long, void *);7 8[[clang::unsafe_buffer_usage]]9int unsafe_f(unsigned long, void *);10 11void address_to_integer(int x) {12 int * p = new int[10];13 unsigned long n = (unsigned long) &p[5];14 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:37-[[@LINE-1]]:42}:"&p.data()[5]"15 unsigned long m = (unsigned long) &p[x];16 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:37-[[@LINE-1]]:42}:"&p.data()[x]"17}18 19void address_to_bool(int x) {20 int * p = new int[10];21 bool a = (bool) &p[5];22 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:19-[[@LINE-1]]:24}:"&p.data()[5]"23 bool b = (bool) &p[x];24 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:19-[[@LINE-1]]:24}:"&p.data()[x]"25 26 bool a1 = &p[5];27 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:18}:"&p.data()[5]"28 bool b1 = &p[x];29 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:18}:"&p.data()[x]"30 31 if (&p[5]) {32 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:12}:"&p.data()[5]"33 return;34 }35}36 37void call_argument(int x) {38 int * p = new int[10];39 40 f((unsigned long) &p[5], &p[x]);41 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:21-[[@LINE-1]]:26}:"&p.data()[5]"42 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:28-[[@LINE-2]]:33}:"&p.data()[x]"43}44 45void ignore_unsafe_calls(int x) {46 // Cannot fix `&p[x]` for now as it is an argument of an unsafe47 // call. So no fix for variable `p`.48 int * p = new int[10];49 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]50 unsafe_f((unsigned long) &p[5],51 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]52 &p[x]);53 54 int * q = new int[10];55 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"56 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"57 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"58 unsafe_f((unsigned long) &q[5],59 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:28-[[@LINE-1]]:33}:"&q.data()[5]"60 (void*)0);61}62 63void odd_subscript_form() {64 int * p = new int[10];65 unsigned long n = (unsigned long) &5[p];66 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:37-[[@LINE-1]]:42}:"&p.data()[5]"67}68 69void index_is_zero() {70 int * p = new int[10];71 int n = p[5];72 73 f((unsigned long)&p[0],74 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:20-[[@LINE-1]]:25}:"p.data()"75 &p[0]);76 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:5-[[@LINE-1]]:10}:"p.data()"77}78 79void pointer_subtraction(int x) {80 int * p = new int[10];81 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"82 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"83 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"84 85 int n = &p[9] - &p[4];86 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:16}:"&p.data()[9]"87 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:19-[[@LINE-2]]:24}:"&p.data()[4]"88 if (&p[9] - &p[x]) {89 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:12}:"&p.data()[9]"90 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:20}:"&p.data()[x]"91 return;92 }93}94 95// To test multiple function declarations, each of which carries96// different incomplete informations.97// no fix-it in the rest of this test:98 99[[clang::unsafe_buffer_usage]]100void unsafe_g(void*);101 102void unsafe_g(void*);103 104void multiple_unsafe_fundecls() {105 int * p = new int[10];106 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]107 unsafe_g(&p[5]);108 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]109}110 111void unsafe_h(void*);112 113[[clang::unsafe_buffer_usage]]114void unsafe_h(void*);115 116void unsafe_h(void* p) { ((char*)p)[10]; }117 118void multiple_unsafe_fundecls2() {119 int * p = new int[10];120 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]121 unsafe_h(&p[5]);122 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]123}124