Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / SemaCXX / warn-unsafe-buffer-usage-pragma-fixit.cpp
blob74ec70b630486f93c55134f162f53d8f32522b73
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
5 void basic(int * x) {
6 int tmp;
7 int *p1 = new int[10]; // no fix
8 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
9 int *p2 = new int[10];
10 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::span<int> p2"
11 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
12 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
13 #pragma clang unsafe_buffer_usage begin
14 tmp = p1[5];
15 #pragma clang unsafe_buffer_usage end
16 tmp = p2[5];
19 void withDiagnosticWarning() {
20 int tmp;
21 int *p1 = new int[10]; // no fix
22 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
23 int *p2 = new int[10];
24 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::span<int> p2"
25 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
26 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
28 // diagnostics in opt-out region
29 #pragma clang unsafe_buffer_usage begin
30 tmp = p1[5]; // not to warn
31 tmp = p2[5]; // not to warn
32 #pragma clang diagnostic push
33 #pragma clang diagnostic warning "-Wunsafe-buffer-usage"
34 tmp = p1[5]; // not to warn
35 tmp = p2[5]; // not to warn
36 #pragma clang diagnostic warning "-Weverything"
37 tmp = p1[5]; // not to warn
38 tmp = p2[5]; // not to warn
39 #pragma clang diagnostic pop
40 #pragma clang unsafe_buffer_usage end
42 // opt-out region under diagnostic warning
43 #pragma clang diagnostic push
44 #pragma clang diagnostic warning "-Wunsafe-buffer-usage"
45 #pragma clang unsafe_buffer_usage begin
46 tmp = p1[5]; // not to warn
47 tmp = p2[5]; // not to warn
48 #pragma clang unsafe_buffer_usage end
49 #pragma clang diagnostic pop
51 tmp = p2[5];
55 void withDiagnosticIgnore() {
56 int tmp;
57 int *p1 = new int[10];
58 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
59 int *p2 = new int[10];
60 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::span<int> p2"
61 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
62 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
63 int *p3 = new int[10];
64 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::span<int> p3"
65 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
66 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
68 #pragma clang unsafe_buffer_usage begin
69 tmp = p1[5]; // not to warn
70 tmp = p2[5]; // not to warn
71 #pragma clang diagnostic push
72 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
73 tmp = p1[5]; // not to warn
74 tmp = p2[5]; // not to warn
75 #pragma clang diagnostic ignored "-Weverything"
76 tmp = p1[5]; // not to warn
77 tmp = p2[5]; // not to warn
78 #pragma clang diagnostic pop
79 #pragma clang unsafe_buffer_usage end
81 #pragma clang diagnostic push
82 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
83 #pragma clang unsafe_buffer_usage begin
84 tmp = p1[5]; // not to warn
85 tmp = p2[5]; // not to warn
86 #pragma clang unsafe_buffer_usage end
87 #pragma clang diagnostic pop
89 tmp = p2[5];
91 #pragma clang diagnostic push
92 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
93 #pragma clang unsafe_buffer_usage begin
94 tmp = p1[5]; // not to warn
95 tmp = p2[5]; // not to warn
96 #pragma clang unsafe_buffer_usage end
97 tmp = p3[5]; // expected-note{{used in buffer access here}}
98 #pragma clang diagnostic pop
101 void noteGoesWithVarDeclWarning() {
102 #pragma clang diagnostic push
103 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
104 int *p = new int[10]; // not to warn
105 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
106 #pragma clang diagnostic pop
108 p[5]; // not to note since the associated warning is suppressed
112 // Test suppressing interacts with variable grouping:
114 // The implication edges are: `a` -> `b` -> `c`.
115 // If the unsafe operation on `a` is supressed, none of the variables
116 // will be fixed.
117 void suppressedVarInGroup() {
118 int * a;
119 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
120 int * b;
121 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
122 int * c;
123 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
125 #pragma clang unsafe_buffer_usage begin
126 a[5] = 5;
127 #pragma clang unsafe_buffer_usage end
128 a = b;
129 b = c;
132 // To show that if `a[5]` is not suppressed in the
133 // `suppressedVarInGroup` function above, all variables will be fixed.
134 void suppressedVarInGroup_control() {
135 int * a;
136 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> a"
137 int * b;
138 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> b"
139 int * c;
140 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> c"
142 a[5] = 5;
143 a = b;
144 b = c;
147 // The implication edges are: `a` -> `b` -> `c`.
148 // The unsafe operation on `b` is supressed, while the unsafe
149 // operation on `a` is not suppressed. Variable `b` will still be
150 // fixed when fixing `a`.
151 void suppressedVarInGroup2() {
152 int * a;
153 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> a"
154 int * b;
155 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> b"
156 int * c;
157 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> c"
159 a[5] = 5;
160 #pragma clang unsafe_buffer_usage begin
161 b[5] = 5;
162 #pragma clang unsafe_buffer_usage end
163 a = b;
164 b = c;
167 // The implication edges are: `a` -> `b` -> `c`.
168 // The unsafe operation on `b` is supressed, while the unsafe
169 // operation on `c` is not suppressed. Only variable `c` will be fixed
170 // then.
171 void suppressedVarInGroup3() {
172 int * a;
173 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
174 int * b;
175 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
176 int * c;
177 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
179 c[5] = 5;
180 #pragma clang unsafe_buffer_usage begin
181 b[5] = 5;
182 #pragma clang unsafe_buffer_usage end
183 a = b;
184 b = c;
185 // FIXME: we do not fix `a = b` and `b = c` because the `.data()` fix-it is not generally correct.
188 // The implication edges are: `a` -> `b` -> `c` -> `a`.
189 // The unsafe operation on `b` is supressed, while the unsafe
190 // operation on `c` is not suppressed. Since the implication graph
191 // forms a cycle, all variables will be fixed.
192 void suppressedVarInGroup4() {
193 int * a;
194 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> a"
195 int * b;
196 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> b"
197 int * c;
198 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> c"
200 c[5] = 5;
201 #pragma clang unsafe_buffer_usage begin
202 b[5] = 5;
203 #pragma clang unsafe_buffer_usage end
204 a = b;
205 b = c;
206 c = a;
209 // There are two groups: `a` -> `b` -> `c` and `d` -> `e` -> `f`.
210 // Suppressing unsafe operations on variables in one group does not
211 // affect other groups.
212 void suppressedVarInGroup5() {
213 int * a;
214 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
215 int * b;
216 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
217 int * c;
218 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
219 int * d;
220 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> d"
221 int * e;
222 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> e"
223 int * f;
224 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> f"
226 #pragma clang unsafe_buffer_usage begin
227 a[5] = 5;
228 #pragma clang unsafe_buffer_usage end
229 a = b;
230 b = c;
232 d[5] = 5;
233 d = e;
234 e = f;