346 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions -verify %s2 3namespace std {4 class type_info { };5}6 7void local_assign_both_span() {8 int tmp;9 int* p = new int[10]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' to 'std::span' to propagate bounds information between them}}10 tmp = p[4]; // expected-note{{used in buffer access here}}11 12 int* q = new int[10]; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p' to 'std::span' to propagate bounds information between them}}13 tmp = q[4]; // expected-note{{used in buffer access here}}14 15 q = p;16}17 18void local_assign_rhs_span() {19 int tmp;20 int* p = new int[10];21 int* q = new int[10]; // expected-warning{{'q' is an unsafe pointer used for buffer access}}22 tmp = q[4]; // expected-note{{used in buffer access here}}23 p = q; // FIXME: we do not fix `p = q` here as the `.data()` fix-it is not generally correct24}25 26void local_assign_no_span() {27 int tmp;28 int* p = new int[10];29 int* q = new int[10];30 p = q;31}32 33void local_assign_lhs_span() {34 int tmp;35 int* p = new int[10]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' to 'std::span' to propagate bounds information between them}}36 tmp = p[4]; // expected-note{{used in buffer access here}}37 int* q = new int[10];38 39 p = q;40}41 42void lhs_span_multi_assign() {43 int *a = new int[2];44 int *b = a;45 int *c = b;46 int *d = c; // expected-warning{{'d' is an unsafe pointer used for buffer access}} expected-note{{change type of 'd' to 'std::span' to preserve bounds information, and change 'c', 'b', and 'a' to 'std::span' to propagate bounds information between them}}47 int tmp = d[2]; // expected-note{{used in buffer access here}}48}49 50void rhs_span() {51 int *x = new int[3];52 int *y; // expected-warning{{'y' is an unsafe pointer used for buffer access}}53 y[5] = 10; // expected-note{{used in buffer access here}}54 55 x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct56}57 58void rhs_span1() {59 int *q = new int[12];60 int *p = q; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}61 p[5] = 10; // expected-note{{used in buffer access here}}62 int *r = q; // expected-warning{{'r' is an unsafe pointer used for buffer access}} expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p' and 'q' to 'std::span' to propagate bounds information between them}}63 r[10] = 5; // expected-note{{used in buffer access here}}64}65 66void rhs_span2() {67 int *q = new int[6];68 int *p = q; // expected-warning{{'p' is an unsafe pointer used for buffer access}}69 p[5] = 10; // expected-note{{used in buffer access here}}70 int *r = q; // FIXME: we do not fix `int *r = q` here as the `.data()` fix-it is not generally correct71}72 73void test_grouping() {74 int *z = new int[8];75 int tmp;76 int *y = new int[10]; // expected-warning{{'y' is an unsafe pointer used for buffer access}}77 tmp = y[5]; // expected-note{{used in buffer access here}}78 79 int *x = new int[10];80 x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct81 82 int *w = z;83}84 85void test_grouping1() {86 int tmp;87 int *y = new int[10]; // expected-warning{{'y' is an unsafe pointer used for buffer access}}88 tmp = y[5]; // expected-note{{used in buffer access here}}89 int *x = new int[10];90 x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct91 92 int *w = new int[10]; // expected-warning{{'w' is an unsafe pointer used for buffer access}}93 tmp = w[5]; // expected-note{{used in buffer access here}}94 int *z = new int[10];95 z = w; // FIXME: we do not fix `z = w` here as the `.data()` fix-it is not generally correct96}97 98void foo1a() {99 int *r = new int[7];100 int *p = new int[4]; // expected-warning{{'p' is an unsafe pointer used for buffer access}}101 p = r;102 int tmp = p[9]; // expected-note{{used in buffer access here}}103 int *q;104 q = r; // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct105}106 107void foo1b() {108 int *r = new int[7];109 int *p = new int[4]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'r' and 'q' to 'std::span' to propagate bounds information between them}}110 p = r;111 int tmp = p[9]; // expected-note{{used in buffer access here}}112 int *q; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p' and 'r' to 'std::span' to propagate bounds information between them}}113 q = r;114 tmp = q[9]; // expected-note{{used in buffer access here}}115}116 117void foo1c() {118 int *r = new int[7]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}119 int *p = new int[4];120 p = r; // FIXME: we do not fix `p = r` here as the `.data()` fix-it is not generally correct121 int tmp = r[9]; // expected-note{{used in buffer access here}}122 int *q; // expected-warning{{'q' is an unsafe pointer used for buffer access}}123 q = r; // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct124 tmp = q[9]; // expected-note{{used in buffer access here}}125}126 127void foo2a() {128 int *r = new int[7];129 int *p = new int[5]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}130 int *q = new int[4];131 p = q;132 int tmp = p[8]; // expected-note{{used in buffer access here}}133 q = r;134}135 136void foo2b() {137 int *r = new int[7];138 int *p = new int[5];139 int *q = new int[4]; // expected-warning{{'q' is an unsafe pointer used for buffer access}}140 p = q; // FIXME: we do not fix `p = q` here as the `.data()` fix-it is not generally correct141 int tmp = q[8]; // expected-note{{used in buffer access here}}142 q = r;143}144 145void foo2c() {146 int *r = new int[7];147 int *p = new int[5]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}148 int *q = new int[4]; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p' and 'r' to 'std::span' to propagate bounds information between them}}149 p = q;150 int tmp = p[8]; // expected-note{{used in buffer access here}}151 q = r;152 tmp = q[8]; // expected-note{{used in buffer access here}}153}154 155void foo3a() {156 int *r = new int[7];157 int *p = new int[5]; // expected-warning{{'p' is an unsafe pointer used for buffer access}}158 int *q = new int[4];159 q = p; // FIXME: we do not fix `q = p` here as the `.data()` fix-it is not generally correct160 int tmp = p[8]; // expected-note{{used in buffer access here}}161 q = r;162}163 164void foo3b() {165 int *r = new int[7];166 int *p = new int[5];167 int *q = new int[4]; // expected-warning{{'q' is an unsafe pointer used for buffer access}} //expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' and 'p' to 'std::span' to propagate bounds information between them}}168 q = p;169 int tmp = q[8]; // expected-note{{used in buffer access here}}170 q = r;171}172 173void test_crash() {174 int *r = new int[8];175 int *q = r;176 int *p; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}177 p = q;178 int tmp = p[9]; // expected-note{{used in buffer access here}}179}180 181void foo_uuc() {182 int *ptr;183 int *local; // expected-warning{{'local' is an unsafe pointer used for buffer access}}184 local = ptr;185 local++; // expected-note{{used in pointer arithmetic here}}186 187 (local = ptr) += 5; // expected-warning{{unsafe pointer arithmetic}}188}189 190void check_rhs_fix() {191 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}} // expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'x' to 'std::span' to propagate bounds information between them}}192 int *x;193 r[7] = 9; // expected-note{{used in buffer access here}}194 r = x;195}196 197void check_rhs_nofix() {198 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}199 int *x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}200 r[7] = 9; // expected-note{{used in buffer access here}}201 r = x;202 x++; // expected-note{{used in pointer arithmetic here}}203}204 205void check_rhs_nofix_order() {206 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}207 int *x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}208 x++; // expected-note{{used in pointer arithmetic here}}209 r[7] = 9; // expected-note{{used in buffer access here}}210 r = x;211}212 213void check_rhs_nofix_order1() {214 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}215 r[7] = 9; // expected-note{{used in buffer access here}}216 int *x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}217 x++; // expected-note{{used in pointer arithmetic here}}218 r = x;219}220 221void check_rhs_nofix_order2() {222 int *x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}223 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}224 r[7] = 9; // expected-note{{used in buffer access here}}225 x++; // expected-note{{used in pointer arithmetic here}}226 r = x;227}228 229void check_rhs_nofix_order3() {230 int *x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}231 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}232 r = x;233 r[7] = 9; // expected-note{{used in buffer access here}}234 x++; // expected-note{{used in pointer arithmetic here}}235}236 237void check_rhs_nofix_order4() {238 int *x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}239 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}240 r[7] = 9; // expected-note{{used in buffer access here}}241 r = x;242 x++; // expected-note{{used in pointer arithmetic here}}243}244 245void no_unhandled_lhs() {246 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}} // expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'x' to 'std::span' to propagate bounds information between them}}247 r[7] = 9; // expected-note{{used in buffer access here}}248 int *x;249 r = x;250}251 252const std::type_info unhandled_lhs() {253 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}254 r[7] = 9; // expected-note{{used in buffer access here}}255 int *x;256 r = x;257 return typeid(*r);258}259 260const std::type_info unhandled_rhs() {261 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}262 r[7] = 9; // expected-note{{used in buffer access here}}263 int *x;264 r = x;265 return typeid(*x);266}267 268void test_negative_index() {269 int *x = new int[4]; // expected-warning{{'x' is an unsafe pointer used for buffer access}}270 int *p; // expected-warning{{'p' is an unsafe pointer used for buffer access}}271 p = &x[1]; // expected-note{{used in buffer access here}}272 p[-1] = 9; // expected-note{{used in buffer access here}}273}274 275void test_unfixable() {276 int *r = new int[8]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}277 int *x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}278 x[7] = 9; // expected-note{{used in buffer access here}}279 r = x;280 r++; // expected-note{{used in pointer arithmetic here}}281}282 283void test_cyclic_deps() {284 int *r = new int[10]; // expected-warning{{'r' is an unsafe pointer used for buffer access}} expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p' and 'q' to 'std::span' to propagate bounds information between them}}285 int *q;286 q = r;287 int *p;288 p = q;289 r[3] = 9; // expected-note{{used in buffer access here}}290 r = p;291}292 293void test_cyclic_deps_a() {294 int *r = new int[10]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}295 int *q;296 q = r;297 int *p; // expected-warning{{'p' is an unsafe pointer used for buffer access}}298 p = q;299 r[3] = 9; // expected-note{{used in buffer access here}}300 r = p;301 p++; // expected-note{{used in pointer arithmetic here}}302}303 304void test_cyclic_deps1() {305 int *r = new int[10];306 int *q;307 q = r;308 int *p; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}309 p = q;310 p[3] = 9; // expected-note{{used in buffer access here}}311 r = p;312}313 314void test_cyclic_deps2() {315 int *r = new int[10];316 int *q; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' and 'p' to 'std::span' to propagate bounds information between them}}317 q = r;318 int *p;319 p = q;320 q[3] = 9; // expected-note{{used in buffer access here}}321 r = p;322}323 324void test_cyclic_deps3() {325 int *r = new int[10];326 int *q; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' and 'p' to 'std::span' to propagate bounds information between them}}327 q = r;328 int *p; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}329 p = q;330 q[3] = 9; // expected-note{{used in buffer access here}}331 p[4] = 7; // expected-note{{used in buffer access here}}332 r = p;333}334 335void test_cyclic_deps4() {336 int *r = new int[10]; // expected-warning{{'r' is an unsafe pointer used for buffer access}} expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p' and 'q' to 'std::span' to propagate bounds information between them}}337 int *q; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' and 'p' to 'std::span' to propagate bounds information between them}}338 q = r;339 int *p; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'r' and 'q' to 'std::span' to propagate bounds information between them}}340 p = q;341 q[3] = 9; // expected-note{{used in buffer access here}}342 p[4] = 7; // expected-note{{used in buffer access here}}343 r[1] = 5; // expected-note{{used in buffer access here}}344 r = p;345}346