1 // RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage -fcxx-exceptions -fsafe-buffer-usage-suggestions -verify %s 2 // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fcxx-exceptions -fdiagnostics-parseable-fixits -fsafe-buffer-usage-suggestions %s 2>&1 | FileCheck %s 3 4 typedef int * TYPEDEF_PTR; 5 #define MACRO_PTR int* 6 7 // We CANNOT fix a pointer whose type is defined in a typedef or a 8 // macro. Because if the typedef is changed after the fix, the fix 9 // becomes incorrect and may not be noticed. 10 11 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE+1]] 12 void typedefPointer(TYPEDEF_PTR p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} 13 if (++p) { // expected-note{{used in pointer arithmetic here}} 14 } 15 } 16 17 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE+1]] 18 void macroPointer(MACRO_PTR p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} 19 if (++p) { // expected-note{{used in pointer arithmetic here}} 20 } 21 } 22 23 // The analysis requires accurate source location informations from 24 // `TypeLoc`s of types of variable (parameter) declarations in order 25 // to generate fix-its for them. But those information is not always 26 // available (probably due to some bugs in clang but it is irrelevant 27 // to the safe-buffer project). The following is an example. When 28 // `_Atomic` is used, we cannot get valid source locations of the 29 // pointee type of `unsigned *`. The analysis gives up in such a 30 // case. 31 // CHECK-NOT: fix-it: 32 void typeLocSourceLocationInvalid(_Atomic unsigned *map) { // expected-warning{{'map' is an unsafe pointer used for buffer access}} 33 map[5] = 5; // expected-note{{used in buffer access here}} 34 } 35 36 // CHECK: fix-it:"{{.*}}":{[[@LINE+1]]:33-[[@LINE+1]]:46}:"std::span<unsigned> map" 37 void typeLocSourceLocationValid(unsigned *map) { // expected-warning{{'map' is an unsafe pointer used for buffer access}} \ 38 expected-note{{change type of 'map' to 'std::span' to preserve bounds information}} 39 map[5] = 5; // expected-note{{used in buffer access here}} 40 } 41 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:2-[[@LINE-1]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void typeLocSourceLocationValid(unsigned *map) {return typeLocSourceLocationValid(std::span<unsigned>(map, <# size #>));}\n" 42 43 // We do not fix parameters participating unsafe operations for the 44 // following functions/methods or function-like expressions: 45 46 // CHECK-NOT: fix-it: 47 class A { 48 // constructor & descructor 49 A(int * p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} 50 int tmp; 51 tmp = p[5]; // expected-note{{used in buffer access here}} 52 } 53 54 // class member methods 55 void foo(int *p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} 56 int tmp; 57 tmp = p[5]; // expected-note{{used in buffer access here}} 58 } 59 60 // overload operator 61 int operator+(int * p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} 62 int tmp; 63 tmp = p[5]; // expected-note{{used in buffer access here}} 64 return tmp; 65 } 66 }; 67 68 // lambdas 69 void foo() { 70 auto Lamb = [&](int *p) // expected-warning{{'p' is an unsafe pointer used for buffer access}} 71 -> int { 72 int tmp; 73 tmp = p[5]; // expected-note{{used in buffer access here}} 74 return tmp; 75 }; 76 } 77 78 // template 79 template<typename T> 80 void template_foo(T * p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} 81 T tmp; 82 tmp = p[5]; // expected-note{{used in buffer access here}} 83 } 84 85 void instantiate_template_foo() { 86 int * p; 87 template_foo(p); // FIXME expected note {{in instantiation of function template specialization 'template_foo<int>' requested here}} 88 } 89 90 // variadic function 91 void vararg_foo(int * p...) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} 92 int tmp; 93 tmp = p[5]; // expected-note{{used in buffer access here}} 94 } 95 96 // constexpr functions 97 constexpr int constexpr_foo(int * p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} 98 return p[5]; // expected-note{{used in buffer access here}} 99 } 100 101 // function body is a try-block 102 void fn_with_try_block(int* p) // expected-warning{{'p' is an unsafe pointer used for buffer access}} 103 try { 104 int tmp; 105 106 if (p == nullptr) 107 throw 42; 108 tmp = p[5]; // expected-note{{used in buffer access here}} 109 } 110 catch (int) { 111 *p = 0; 112 } 113 114 // The following two unsupported cases are not specific to 115 // parm-fixits. Adding them here in case they get forgotten. 116 void isArrayDecayToPointerUPC(int a[][10], int (*b)[10]) { 117 // expected-warning@-1{{'a' is an unsafe pointer used for buffer access}} 118 // expected-warning@-2{{'b' is an unsafe pointer used for buffer access}} 119 int tmp; 120 121 tmp = a[5][5] + b[5][5]; // expected-note2{{used in buffer access here}} 122 } 123 124 // parameter having default values: 125 void parmWithDefaultValue(int * x = 0) { 126 // expected-warning@-1{{'x' is an unsafe pointer used for buffer access}} 127 int tmp; 128 tmp = x[5]; // expected-note{{used in buffer access here}} 129 } 130 131 void parmWithDefaultValueDecl(int * x = 0); 132 133 void parmWithDefaultValueDecl(int * x) { 134 // expected-warning@-1{{'x' is an unsafe pointer used for buffer access}} 135 int tmp; 136 tmp = x[5]; // expected-note{{used in buffer access here}} 137 } 138 139 #define MACRO_NAME MyName 140 141 // The fix-it ends with a macro. It will be discarded due to overlap with macros. 142 // CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]] 143 void macroIdentifier(int * MACRO_NAME) { // expected-warning{{'MyName' is an unsafe pointer used for buffer access}} 144 if (++MyName){} // expected-note{{used in pointer arithmetic here}} 145 } 146 147 // CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]] 148 void parmHasNoName(int *p, int *) { // cannot fix the function because there is one parameter has no name. \ 149 expected-warning{{'p' is an unsafe pointer used for buffer access}} 150 p[5] = 5; // expected-note{{used in buffer access here}} 151 } 152