|
4 | 4 | #include <stddef.h>
|
5 | 5 |
|
6 | 6 | namespace std {
|
7 |
| - |
8 | 7 | template <typename T, size_t N>
|
9 | 8 | struct array {
|
10 | 9 | const T *data() const noexcept;
|
11 | 10 | T *data() noexcept;
|
12 | 11 | size_t size() const noexcept;
|
| 12 | + const T &operator[](const size_t idx) const; |
13 | 13 | };
|
14 | 14 |
|
15 | 15 | template <typename CharT>
|
@@ -40,6 +40,7 @@ struct span {
|
40 | 40 | span<T> first(size_t count) const noexcept;
|
41 | 41 | span<T> last(size_t count) const noexcept;
|
42 | 42 | span<T> subspan(size_t offset, size_t count) const noexcept;
|
| 43 | + const T &operator[](const size_t idx) const; |
43 | 44 | };
|
44 | 45 |
|
45 | 46 | template <typename T>
|
@@ -71,7 +72,7 @@ void cb_cchar_42(const char *__counted_by(42) s);
|
71 | 72 | // expected-note@+1 19{{consider using a safe container and passing '.data()' to the parameter 'p' and '.size()' to its dependent parameter 'count' or 'std::span' and passing '.first(...).data()' to the parameter 'p'}}
|
72 | 73 | void cb_int(int *__counted_by(count) p, size_t count);
|
73 | 74 |
|
74 |
| -// expected-note@+1 11{{consider using a safe container and passing '.data()' to the parameter 'p' and '.size()' to its dependent parameter 'count' or 'std::span' and passing '.first(...).data()' to the parameter 'p'}} |
| 75 | +// expected-note@+1 33{{consider using a safe container and passing '.data()' to the parameter 'p' and '.size()' to its dependent parameter 'count' or 'std::span' and passing '.first(...).data()' to the parameter 'p'}} |
75 | 76 | void cb_cint(const int *__counted_by(count) p, size_t count);
|
76 | 77 |
|
77 | 78 | // expected-note@+1 10{{consider using 'std::span' and passing '.first(...).data()' to the parameter 'p'}}
|
@@ -367,6 +368,129 @@ void single_variable() {
|
367 | 368 | sb_cvoid(&Arr, sizeof(decltype(Var))); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
|
368 | 369 | }
|
369 | 370 |
|
| 371 | +namespace test_subscript { |
| 372 | + void foo(std::span<int> S) { |
| 373 | + std::array<int, 10> A; |
| 374 | + |
| 375 | + cb_cint(S.first(S[5]).data(), S[5]); |
| 376 | + cb_cint(S.first(A[5]).data(), A[5]); |
| 377 | + cb_cint(S.subspan(0, S[5]).data(), S[5]); |
| 378 | + cb_cint(S.subspan(0, A[5]).data(), A[5]); |
| 379 | + cb_cint(S.subspan(0, S[5]).data(), A[5]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 380 | + cb_cint(S.subspan(0, S[5]).data(), S[6]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 381 | + |
| 382 | + unsigned x; |
| 383 | + |
| 384 | + cb_cint(S.first(S[x]).data(), S[x]); |
| 385 | + cb_cint(S.first(A[x]).data(), A[x]); |
| 386 | + cb_cint(S.subspan(0, S[x]).data(), S[x]); |
| 387 | + cb_cint(S.subspan(0, A[x]).data(), A[x]); |
| 388 | + cb_cint(S.first(S[x + 1]).data(), S[x + 1]); |
| 389 | + cb_cint(S.subspan(0, A[x + 1]).data(), A[x + 1]); |
| 390 | + cb_cint(S.first(A[A[x]]).data(), A[A[x]]); |
| 391 | + cb_cint(S.first(A[A[x] + 1]).data(), A[A[x] + 1]); |
| 392 | + cb_cint(S.first(S[x + 1]).data(), S[x - 1]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 393 | + cb_cint(S.first(A[A[x]]).data(), A[A[x] + 1]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 394 | + |
| 395 | + std::array<std::array<int, 10>, 10> A2d; |
| 396 | + |
| 397 | + cb_cint(S.first(A2d[x][5]).data(), A2d[x][5]); |
| 398 | + cb_cint(S.first(A2d[x][5]).data(), A2d[5][x]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 399 | + } |
| 400 | + |
| 401 | + struct T { |
| 402 | + std::array<int, 10> a; |
| 403 | + } t, *tp; |
| 404 | + |
| 405 | + struct TT { |
| 406 | + struct T t; |
| 407 | + struct T * tp; |
| 408 | + } tt, *ttp; |
| 409 | + |
| 410 | + void bar(std::span<int> S) { |
| 411 | + unsigned x; |
| 412 | + |
| 413 | + cb_cint(S.first(t.a[x]).data(), t.a[x]); |
| 414 | + cb_cint(S.first(tp->a[x]).data(), tp->a[x]); |
| 415 | + cb_cint(S.first(tt.t.a[x]).data(), tt.t.a[x]); |
| 416 | + cb_cint(S.first(ttp->t.a[x]).data(), ttp->t.a[x]); |
| 417 | + cb_cint(S.first(tt.tp->a[x]).data(), tt.tp->a[x]); |
| 418 | + cb_cint(S.first(ttp->tp->a[x]).data(), ttp->tp->a[x]); |
| 419 | + cb_cint(S.first(t.a[x]).data(), tp->a[x]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 420 | + cb_cint(S.first(tt.t.a[x]).data(), tt.tp->a[x]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 421 | + cb_cint(S.first(ttp->t.a[x]).data(), ttp->tp->a[x]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 422 | + |
| 423 | + int cArr[10]; |
| 424 | + |
| 425 | + cb_cint(S.first(cArr[5]).data(), cArr[5]); |
| 426 | + cb_cint(S.first(cArr[1]).data(), cArr[sizeof(char)]); |
| 427 | + cb_cint(S.first(cArr[5]).data(), cArr[6]); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 428 | + cb_cint(S.first(cArr[5]).data(), cArr[sizeof(char)]);// expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 429 | + |
| 430 | + std::array<struct TT, 10> ttA; |
| 431 | + |
| 432 | + cb_cint(S.first(ttA[4].t.a[x]).data(), ttA[4].t.a[x]); |
| 433 | + cb_cint(S.first(ttA[4].tp->a[x]).data(), ttA[4].tp->a[x]); |
| 434 | + cb_cint(S.first(ttA[3].t.a[x]).data(), ttA[4].t.a[x]);// expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 435 | + cb_cint(S.first(ttA[3].tp->a[x]).data(), ttA[4].tp->a[x]);// expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 436 | + } |
| 437 | +} //namespace test_subscript |
| 438 | + |
| 439 | +namespace test_member_fun_call { |
| 440 | + struct T { |
| 441 | + unsigned size() {return 0;} // missing 'const' |
| 442 | + unsigned size(int x) const {return 0;} // has arguments |
| 443 | + unsigned supported_size() const {return 0;} |
| 444 | + } t, *tp; |
| 445 | + |
| 446 | + void foo(std::span<int> S1, std::span<int> S2) { |
| 447 | + cb_cint(S1.first(S2.size()).data(), S2.size()); |
| 448 | + cb_cint(S1.first(S2.size()).data(), S1.size()); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 449 | + |
| 450 | + |
| 451 | + cb_cint(S1.first(t.supported_size()).data(), t.supported_size()); |
| 452 | + cb_cint(S1.first(tp->supported_size()).data(), tp->supported_size()); |
| 453 | + cb_cint(S1.first(t.size()).data(), t.size()); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 454 | + cb_cint(S1.first(t.size(0)).data(), t.size(0)); // expected-warning{{unsafe assignment to function parameter of count-attributed type}} |
| 455 | + cb_cint(S1.first(t.supported_size()).data(), tp->supported_size()); // expected-warning{{unsafe assignment to function parameter of count-attributed}} |
| 456 | + } |
| 457 | + void bar(std::span<int> S) { |
| 458 | + std::array<struct T, 10> Ts; |
| 459 | + std::array<struct T*, 10> Tps; |
| 460 | + unsigned x; |
| 461 | + |
| 462 | + cb_cint(S.first(Ts[5].supported_size()).data(), Ts[5].supported_size()); |
| 463 | + cb_cint(S.first(Ts[x].supported_size()).data(), Ts[x].supported_size()); |
| 464 | + cb_cint(S.first(Tps[5]->supported_size()).data(), Tps[5]->supported_size()); |
| 465 | + cb_cint(S.first(Ts[x].supported_size()).data(), Ts[5].supported_size()); // expected-warning{{unsafe assignment to function parameter of count-attributed}} |
| 466 | + cb_cint(S.first(Ts[x].supported_size()).data(), Tps[x]->supported_size());// expected-warning{{unsafe assignment to function parameter of count-attributed}} |
| 467 | + } |
| 468 | + |
| 469 | + template<typename Ty, size_t N> |
| 470 | + struct GenT { |
| 471 | + unsigned size() {return 0;} // missing 'const' |
| 472 | + unsigned size(int x) const {return 0;} // has arguments |
| 473 | + static unsigned static_size() {return 0;} // static function is not supported |
| 474 | + unsigned supported_size() const {return 0;} |
| 475 | + |
| 476 | + void test(std::span<int> S) { |
| 477 | + cb_cint(S.first(supported_size()).data(), supported_size()); |
| 478 | + cb_cint(S.first(supported_size()).data(), size()); // expected-warning{{unsafe assignment to function parameter of count-attributed}} |
| 479 | + } |
| 480 | + }; |
| 481 | + |
| 482 | + void baz(std::span<int> S) { |
| 483 | + GenT<int, 5> T5; |
| 484 | + GenT<int, 10> T10; |
| 485 | + |
| 486 | + cb_cint(S.first(T5.supported_size()).data(), T5.supported_size()); |
| 487 | + cb_cint(S.first(T5.static_size()).data(), T5.static_size()); // expected-warning{{unsafe assignment to function parameter of count-attributed}} |
| 488 | + cb_cint(S.first(GenT<int, 5>::static_size()).data(), GenT<int, 5>::static_size()); // expected-warning{{unsafe assignment to function parameter of count-attributed}} |
| 489 | + cb_cint(S.first(T5.supported_size()).data(), T10.supported_size()); // expected-warning{{unsafe assignment to function parameter of count-attributed}} |
| 490 | + T5.test(S); |
| 491 | + } |
| 492 | +} // namespace test_member_fun_call |
| 493 | + |
370 | 494 | namespace test_member_access {
|
371 | 495 | class Base {
|
372 | 496 | public:
|
|
0 commit comments