1b7bdf199SArtem Dergachev // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \
2b7bdf199SArtem Dergachev // RUN: -fsafe-buffer-usage-suggestions \
3b7bdf199SArtem Dergachev // RUN: -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
4829bcb06SZiqing Luo
basic(int * x)5829bcb06SZiqing Luo void basic(int * x) {
6829bcb06SZiqing Luo int tmp;
7829bcb06SZiqing Luo int *p1 = new int[10]; // no fix
8829bcb06SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
9829bcb06SZiqing Luo int *p2 = new int[10];
10*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int> "
1187b8c85bSRashmi Mudduluru // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
1287b8c85bSRashmi Mudduluru // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
13829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage begin
14829bcb06SZiqing Luo tmp = p1[5];
15829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage end
16829bcb06SZiqing Luo tmp = p2[5];
17829bcb06SZiqing Luo }
18829bcb06SZiqing Luo
withDiagnosticWarning()19829bcb06SZiqing Luo void withDiagnosticWarning() {
20829bcb06SZiqing Luo int tmp;
21829bcb06SZiqing Luo int *p1 = new int[10]; // no fix
22829bcb06SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
23829bcb06SZiqing Luo int *p2 = new int[10];
24*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int> "
2587b8c85bSRashmi Mudduluru // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
2687b8c85bSRashmi Mudduluru // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
27829bcb06SZiqing Luo
28829bcb06SZiqing Luo // diagnostics in opt-out region
29829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage begin
30829bcb06SZiqing Luo tmp = p1[5]; // not to warn
31829bcb06SZiqing Luo tmp = p2[5]; // not to warn
32829bcb06SZiqing Luo #pragma clang diagnostic push
33829bcb06SZiqing Luo #pragma clang diagnostic warning "-Wunsafe-buffer-usage"
34829bcb06SZiqing Luo tmp = p1[5]; // not to warn
35829bcb06SZiqing Luo tmp = p2[5]; // not to warn
36829bcb06SZiqing Luo #pragma clang diagnostic warning "-Weverything"
37829bcb06SZiqing Luo tmp = p1[5]; // not to warn
38829bcb06SZiqing Luo tmp = p2[5]; // not to warn
39829bcb06SZiqing Luo #pragma clang diagnostic pop
40829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage end
41829bcb06SZiqing Luo
42829bcb06SZiqing Luo // opt-out region under diagnostic warning
43829bcb06SZiqing Luo #pragma clang diagnostic push
44829bcb06SZiqing Luo #pragma clang diagnostic warning "-Wunsafe-buffer-usage"
45829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage begin
46829bcb06SZiqing Luo tmp = p1[5]; // not to warn
47829bcb06SZiqing Luo tmp = p2[5]; // not to warn
48829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage end
49829bcb06SZiqing Luo #pragma clang diagnostic pop
50829bcb06SZiqing Luo
51829bcb06SZiqing Luo tmp = p2[5];
52829bcb06SZiqing Luo }
53829bcb06SZiqing Luo
54829bcb06SZiqing Luo
withDiagnosticIgnore()55829bcb06SZiqing Luo void withDiagnosticIgnore() {
56829bcb06SZiqing Luo int tmp;
57829bcb06SZiqing Luo int *p1 = new int[10];
58829bcb06SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
59829bcb06SZiqing Luo int *p2 = new int[10];
60*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int> "
6187b8c85bSRashmi Mudduluru // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
6287b8c85bSRashmi Mudduluru // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
63829bcb06SZiqing Luo int *p3 = new int[10];
64*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int> "
6587b8c85bSRashmi Mudduluru // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
6687b8c85bSRashmi Mudduluru // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
67829bcb06SZiqing Luo
68829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage begin
69829bcb06SZiqing Luo tmp = p1[5]; // not to warn
70829bcb06SZiqing Luo tmp = p2[5]; // not to warn
71829bcb06SZiqing Luo #pragma clang diagnostic push
72829bcb06SZiqing Luo #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
73829bcb06SZiqing Luo tmp = p1[5]; // not to warn
74829bcb06SZiqing Luo tmp = p2[5]; // not to warn
75829bcb06SZiqing Luo #pragma clang diagnostic ignored "-Weverything"
76829bcb06SZiqing Luo tmp = p1[5]; // not to warn
77829bcb06SZiqing Luo tmp = p2[5]; // not to warn
78829bcb06SZiqing Luo #pragma clang diagnostic pop
79829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage end
80829bcb06SZiqing Luo
81829bcb06SZiqing Luo #pragma clang diagnostic push
82829bcb06SZiqing Luo #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
83829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage begin
84829bcb06SZiqing Luo tmp = p1[5]; // not to warn
85829bcb06SZiqing Luo tmp = p2[5]; // not to warn
86829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage end
87829bcb06SZiqing Luo #pragma clang diagnostic pop
88829bcb06SZiqing Luo
89829bcb06SZiqing Luo tmp = p2[5];
90829bcb06SZiqing Luo
91829bcb06SZiqing Luo #pragma clang diagnostic push
92829bcb06SZiqing Luo #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
93829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage begin
94829bcb06SZiqing Luo tmp = p1[5]; // not to warn
95829bcb06SZiqing Luo tmp = p2[5]; // not to warn
96829bcb06SZiqing Luo #pragma clang unsafe_buffer_usage end
97829bcb06SZiqing Luo tmp = p3[5]; // expected-note{{used in buffer access here}}
98829bcb06SZiqing Luo #pragma clang diagnostic pop
99829bcb06SZiqing Luo }
100829bcb06SZiqing Luo
noteGoesWithVarDeclWarning()101829bcb06SZiqing Luo void noteGoesWithVarDeclWarning() {
102829bcb06SZiqing Luo #pragma clang diagnostic push
103829bcb06SZiqing Luo #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
104829bcb06SZiqing Luo int *p = new int[10]; // not to warn
105829bcb06SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
106829bcb06SZiqing Luo #pragma clang diagnostic pop
107829bcb06SZiqing Luo
108829bcb06SZiqing Luo p[5]; // not to note since the associated warning is suppressed
109829bcb06SZiqing Luo }
110cfcf76c6SZiqing Luo
111cfcf76c6SZiqing Luo
112cfcf76c6SZiqing Luo // Test suppressing interacts with variable grouping:
113cfcf76c6SZiqing Luo
114cfcf76c6SZiqing Luo // The implication edges are: `a` -> `b` -> `c`.
115cfcf76c6SZiqing Luo // If the unsafe operation on `a` is supressed, none of the variables
116cfcf76c6SZiqing Luo // will be fixed.
suppressedVarInGroup()117cfcf76c6SZiqing Luo void suppressedVarInGroup() {
118cfcf76c6SZiqing Luo int * a;
119cfcf76c6SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
120cfcf76c6SZiqing Luo int * b;
121cfcf76c6SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
122cfcf76c6SZiqing Luo int * c;
123cfcf76c6SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
124cfcf76c6SZiqing Luo
125cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage begin
126cfcf76c6SZiqing Luo a[5] = 5;
127cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage end
128cfcf76c6SZiqing Luo a = b;
129cfcf76c6SZiqing Luo b = c;
130cfcf76c6SZiqing Luo }
131cfcf76c6SZiqing Luo
132cfcf76c6SZiqing Luo // To show that if `a[5]` is not suppressed in the
133cfcf76c6SZiqing Luo // `suppressedVarInGroup` function above, all variables will be fixed.
suppressedVarInGroup_control()134cfcf76c6SZiqing Luo void suppressedVarInGroup_control() {
135cfcf76c6SZiqing Luo int * a;
136*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
137cfcf76c6SZiqing Luo int * b;
138*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
139cfcf76c6SZiqing Luo int * c;
140*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
141cfcf76c6SZiqing Luo
142cfcf76c6SZiqing Luo a[5] = 5;
143cfcf76c6SZiqing Luo a = b;
144cfcf76c6SZiqing Luo b = c;
145cfcf76c6SZiqing Luo }
146cfcf76c6SZiqing Luo
147cfcf76c6SZiqing Luo // The implication edges are: `a` -> `b` -> `c`.
148cfcf76c6SZiqing Luo // The unsafe operation on `b` is supressed, while the unsafe
149cfcf76c6SZiqing Luo // operation on `a` is not suppressed. Variable `b` will still be
150cfcf76c6SZiqing Luo // fixed when fixing `a`.
suppressedVarInGroup2()151cfcf76c6SZiqing Luo void suppressedVarInGroup2() {
152cfcf76c6SZiqing Luo int * a;
153*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
154cfcf76c6SZiqing Luo int * b;
155*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
156cfcf76c6SZiqing Luo int * c;
157*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
158cfcf76c6SZiqing Luo
159cfcf76c6SZiqing Luo a[5] = 5;
160cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage begin
161cfcf76c6SZiqing Luo b[5] = 5;
162cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage end
163cfcf76c6SZiqing Luo a = b;
164cfcf76c6SZiqing Luo b = c;
165cfcf76c6SZiqing Luo }
166cfcf76c6SZiqing Luo
167cfcf76c6SZiqing Luo // The implication edges are: `a` -> `b` -> `c`.
168cfcf76c6SZiqing Luo // The unsafe operation on `b` is supressed, while the unsafe
169cfcf76c6SZiqing Luo // operation on `c` is not suppressed. Only variable `c` will be fixed
170cfcf76c6SZiqing Luo // then.
suppressedVarInGroup3()171cfcf76c6SZiqing Luo void suppressedVarInGroup3() {
172cfcf76c6SZiqing Luo int * a;
173cfcf76c6SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
174cfcf76c6SZiqing Luo int * b;
175cfcf76c6SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
176cfcf76c6SZiqing Luo int * c;
177700baeb7SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
178cfcf76c6SZiqing Luo
179cfcf76c6SZiqing Luo c[5] = 5;
180cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage begin
181cfcf76c6SZiqing Luo b[5] = 5;
182cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage end
183cfcf76c6SZiqing Luo a = b;
184cfcf76c6SZiqing Luo b = c;
185700baeb7SZiqing Luo // FIXME: we do not fix `a = b` and `b = c` because the `.data()` fix-it is not generally correct.
186cfcf76c6SZiqing Luo }
187cfcf76c6SZiqing Luo
188cfcf76c6SZiqing Luo // The implication edges are: `a` -> `b` -> `c` -> `a`.
189cfcf76c6SZiqing Luo // The unsafe operation on `b` is supressed, while the unsafe
190cfcf76c6SZiqing Luo // operation on `c` is not suppressed. Since the implication graph
191cfcf76c6SZiqing Luo // forms a cycle, all variables will be fixed.
suppressedVarInGroup4()192cfcf76c6SZiqing Luo void suppressedVarInGroup4() {
193cfcf76c6SZiqing Luo int * a;
194*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
195cfcf76c6SZiqing Luo int * b;
196*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
197cfcf76c6SZiqing Luo int * c;
198*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
199cfcf76c6SZiqing Luo
200cfcf76c6SZiqing Luo c[5] = 5;
201cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage begin
202cfcf76c6SZiqing Luo b[5] = 5;
203cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage end
204cfcf76c6SZiqing Luo a = b;
205cfcf76c6SZiqing Luo b = c;
206cfcf76c6SZiqing Luo c = a;
207cfcf76c6SZiqing Luo }
208cfcf76c6SZiqing Luo
209cfcf76c6SZiqing Luo // There are two groups: `a` -> `b` -> `c` and `d` -> `e` -> `f`.
210cfcf76c6SZiqing Luo // Suppressing unsafe operations on variables in one group does not
211cfcf76c6SZiqing Luo // affect other groups.
suppressedVarInGroup5()212cfcf76c6SZiqing Luo void suppressedVarInGroup5() {
213cfcf76c6SZiqing Luo int * a;
214cfcf76c6SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
215cfcf76c6SZiqing Luo int * b;
216cfcf76c6SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
217cfcf76c6SZiqing Luo int * c;
218cfcf76c6SZiqing Luo // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
219cfcf76c6SZiqing Luo int * d;
220*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
221cfcf76c6SZiqing Luo int * e;
222*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
223cfcf76c6SZiqing Luo int * f;
224*fde4b80cSjkorous-apple // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"
225cfcf76c6SZiqing Luo
226cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage begin
227cfcf76c6SZiqing Luo a[5] = 5;
228cfcf76c6SZiqing Luo #pragma clang unsafe_buffer_usage end
229cfcf76c6SZiqing Luo a = b;
230cfcf76c6SZiqing Luo b = c;
231cfcf76c6SZiqing Luo
232cfcf76c6SZiqing Luo d[5] = 5;
233cfcf76c6SZiqing Luo d = e;
234cfcf76c6SZiqing Luo e = f;
235cfcf76c6SZiqing Luo }
236