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
7 int *p1
= new int[10]; // no fix
8 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
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
15 #pragma clang unsafe_buffer_usage end
19 void withDiagnosticWarning() {
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
55 void withDiagnosticIgnore() {
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
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
117 void suppressedVarInGroup() {
119 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
121 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
123 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
125 #pragma clang unsafe_buffer_usage begin
127 #pragma clang unsafe_buffer_usage end
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() {
136 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> a"
138 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> b"
140 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> 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() {
153 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> a"
155 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> b"
157 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> c"
160 #pragma clang unsafe_buffer_usage begin
162 #pragma clang unsafe_buffer_usage end
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
171 void suppressedVarInGroup3() {
173 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
175 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
177 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
180 #pragma clang unsafe_buffer_usage begin
182 #pragma clang unsafe_buffer_usage end
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() {
194 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> a"
196 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> b"
198 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> c"
201 #pragma clang unsafe_buffer_usage begin
203 #pragma clang unsafe_buffer_usage end
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() {
214 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
216 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
218 // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
220 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> d"
222 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> e"
224 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> f"
226 #pragma clang unsafe_buffer_usage begin
228 #pragma clang unsafe_buffer_usage end