xref: /llvm-project/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-pointer-access.cpp (revision fde4b80cb772897a8cf0b3d022f3041e10b6e816)
1 // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \
2 // RUN:            -fsafe-buffer-usage-suggestions \
3 // RUN:            -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
4 
foo(int * v)5 void foo(int* v) {
6 }
7 
m1(int * v1,int * v2,int)8 void m1(int* v1, int* v2, int) {
9 
10 }
11 
condition_check_nullptr()12 void condition_check_nullptr() {
13   int* p = new int[10];
14   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:7}:"std::span<int>"
15   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
16   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
17 
18   int tmp = p[5];
19   if(p != nullptr) {}
20   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
21 }
22 
condition_check()23 void condition_check() {
24   int* p = new int[10];
25   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:7}:"std::span<int>"
26   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
27   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
28 
29   auto q = new int[10];
30 
31   int tmp = p[5];
32   if(p == q) {}
33   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
34 
35   if(q != p){}
36   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:12-[[@LINE-1]]:12}:".data()"
37 
38   if(p < q) {}
39   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
40 
41   if(p <= q) {}
42   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
43 
44   if(p > q) {}
45   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
46 
47   if(p >= q) {}
48   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
49 
50   if( p == q && p != nullptr) {}
51   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:8-[[@LINE-1]]:8}:".data()"
52   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:18-[[@LINE-2]]:18}:".data()"
53 }
54 
condition_check_two_usafe_buffers()55 void condition_check_two_usafe_buffers() {
56   int* p = new int[10];
57   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:7}:"std::span<int>"
58   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
59   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
60 
61   int* q = new int[10];
62   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:7}:"std::span<int>"
63   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
64   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
65 
66   int tmp = p[5];
67   tmp = q[5];
68 
69   if(p == q) {}
70   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
71   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:".data()"
72 }
73 
unsafe_method_invocation_single_param()74 void unsafe_method_invocation_single_param() {
75   int* p = new int[10];
76   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:7}:"std::span<int>"
77   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
78   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
79 
80   int tmp = p[5];
81   foo(p);
82   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:8-[[@LINE-1]]:8}:".data()"
83 
84 }
85 
unsafe_method_invocation_single_param_array(int idx)86 void unsafe_method_invocation_single_param_array(int idx) {
87   int p[32];
88   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::array<int, 32> p"
89 
90   int tmp = p[idx];
91   foo(p);
92   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:8-[[@LINE-1]]:8}:".data()"
93 }
94 
safe_method_invocation_single_param()95 void safe_method_invocation_single_param() {
96   int* p = new int[10];
97   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:{{.*}}-[[@LINE-1]]:{{.*}}}
98   foo(p);
99 }
100 
safe_method_invocation_single_param_array()101 void safe_method_invocation_single_param_array() {
102   int p[10];
103   foo(p);
104   // CHECK-NO: fix-it:"{{.*}}":{[[@LINE-1]]:{{.*}}-[[@LINE-1]]:{{.*}}}:".data()"
105 }
106 
unsafe_method_invocation_double_param()107 void unsafe_method_invocation_double_param() {
108   int* p = new int[10];
109   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:7}:"std::span<int>"
110   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
111   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
112 
113   int tmp = p[5];
114   m1(p, p, 10);
115   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
116   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:".data()"
117 
118   auto q = new int[10];
119 
120   m1(p, q, 4);
121   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
122 
123   m1(q, p, 9);
124   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:10}:".data()"
125 
126   m1(q, q, 8);
127 }
128 
unsafe_method_invocation_double_param_array(int idx)129 void unsafe_method_invocation_double_param_array(int idx) {
130   int p[14];
131   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::array<int, 14> p"
132 
133   int q[40];
134   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::array<int, 40> q"
135 
136   q[idx] = p[idx];
137 
138   m1(p, p, 10);
139   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:".data()"
140   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:".data()"
141 }
142 
unsafe_access_in_lamda()143 void unsafe_access_in_lamda() {
144   int* p = new int[10];
145   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:7}:"std::span<int>"
146   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
147   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
148 
149   auto my_lambda = [&](){
150     p[5] = 10;
151   };
152 
153   foo(p);
154   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:8-[[@LINE-1]]:8}:".data()"
155 }
156 
fixits_in_lamda()157 void fixits_in_lamda() {
158   int* p = new int[10];
159   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:7}:"std::span<int>"
160   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
161   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
162 
163   auto my_lambda = [&](){
164     foo(p);
165     // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:10}:".data()"
166   };
167 
168   p[5] = 10;
169 }
170 
171 // FIXME: Emit fixits for lambda captured variables
fixits_in_lambda_capture()172 void fixits_in_lambda_capture() {
173   auto p = new int[10];
174   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
175   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
176   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
177 
178   auto my_lambda = [p](){ // No fixits emitted here.
179     foo(p);
180   };
181 
182   p[5] = 10;
183 }
184 
fixits_in_lambda_capture_reference()185 void fixits_in_lambda_capture_reference() {
186   auto p = new int[10];
187   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
188   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
189   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
190 
191   auto my_lambda = [&p](){ // No fixits emitted here.
192     foo(p);
193   };
194 
195   p[5] = 10;
196 }
197 
fixits_in_lambda_capture_rename()198 void fixits_in_lambda_capture_rename() {
199   auto p = new int[10];
200   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
201   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
202   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
203 
204   auto my_lambda = [x = p](){ // No fixits emitted here.
205     foo(x);
206   };
207 
208   p[5] = 10;
209 }
210 
ptr_comparison(int * ptr,unsigned idx)211 bool ptr_comparison(int* ptr, unsigned idx) {
212   int arr[10];
213   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:14}:"std::array<int, 10> arr"
214   arr[idx] = idx;
215 
216   return arr > ptr;
217   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:".data()"
218 }
219 
ptr_distance(int * ptr,unsigned idx)220 int long long ptr_distance(int* ptr, unsigned idx) {
221   int arr[10];
222   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:14}:"std::array<int, 10> arr"
223   arr[idx] = idx;
224 
225   int long long dist = arr - ptr;
226   // CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:".data()"
227   return dist;
228 }
229