You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[-Wunsafe-buffer-usage] Relax passing to __counted_by_or_null()
Relax restrictions when passing to
__counted_by_or_null()/__sized_by_or_null() parameters:
- Allow the dependent count var to be anything.
- Allow passing from non-null variant to *_or_null(), but do warn for
passing *_or_null() to non-null variant.
rdar://156006635
(cherry picked from commit c86fc87)
Conflicts:
clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions-interop-annotated.cpp
// expected-note@+1 3{{consider using 'std::span' and passing '.first(...).data()' to the parameter 's'}}
70
70
voidcb_cchar_42(constchar *__counted_by(42) s);
71
71
72
-
// expected-note@+1 31{{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
+
// expected-note@+1 +{{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'}}
// expected-note@+1 34{{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'}}
@@ -81,6 +81,9 @@ void cb_cint_42(const int *__counted_by(42) p);
81
81
// expected-note@+1 6{{consider using 'std::span' and passing '.first(...).data()' to the parameter 'p'}}
82
82
voidcb_cint_multi(constint *__counted_by((a + b) * (c - d)) p, int a, int b, int c, int d);
83
83
84
+
// expected-note@+1 3{{consider using a safe container and passing '.data()' to the parameter 'p' and '.size()' to its dependent parameter 'size' or 'std::span' and passing '.first(...).data()' to the parameter 'p'}}
// expected-note@+1 13{{consider using a safe container and passing '.data()' to the parameter 'p' and '.size()' to its dependent parameter 'size' or 'std::span' and passing '.first(...).data()' to the parameter 'p'}}
// expected-note@+1 +{{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'}}
// expected-note@+1 +{{consider using a safe container and passing '.data()' to the parameter 'p' and '.size()' to its dependent parameter 'size' or 'std::span' and passing '.first(...).data()' to the parameter 'p'}}
@@ -389,9 +398,22 @@ void from_cb_int_multi(int *__counted_by((a + b) * (c - d)) p, int a, int b, int
389
398
cb_int(p, 42); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
390
399
}
391
400
392
-
voidnullptr_as_arg(void * __sized_by(size) p, unsigned size) { //expected-note{{consider using a safe container and passing '.data()' to the parameter 'p' and '.size()' to its dependent parameter 'size' or 'std::span' and passing '.first(...).data()' to the parameter 'p'}}
393
-
nullptr_as_arg(nullptr, 0);
394
-
nullptr_as_arg(nullptr, size); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
401
+
voidnullptr_as_arg(size_t n) {
402
+
cb_int(nullptr, 0);
403
+
cb_int(nullptr, 42); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
404
+
cb_int(nullptr, n); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
405
+
406
+
sb_void(nullptr, 0);
407
+
sb_void(nullptr, 42); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
408
+
sb_void(nullptr, n); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
409
+
410
+
cbn_int(nullptr, 0);
411
+
cbn_int(nullptr, 42);
412
+
cbn_int(nullptr, n);
413
+
414
+
sbn_void(nullptr, 0);
415
+
sbn_void(nullptr, 42);
416
+
sbn_void(nullptr, n);
395
417
}
396
418
397
419
voidsingle_variable() {
@@ -708,6 +730,42 @@ static void previous_infinite_loop3(int * __counted_by(n + n * m) p, size_t n,
708
730
previous_infinite_loop3(p, n, q, r, m, o + 1); // expected-warning 2{{unsafe assignment to function parameter of count-attributed type}}
709
731
}
710
732
733
+
// Check nullable variants.
734
+
735
+
voidnullable(std::span<int> sp, size_t n) {
736
+
cbn_int(sp.data(), sp.size());
737
+
cbn_int(sp.data(), sp.size_bytes()); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
738
+
cbn_int(sp.first(42).data(), 42);
739
+
cbn_int(sp.first(n).data(), n);
740
+
cbn_int(sp.first(42).data(), n); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
741
+
742
+
sbn_void(sp.data(), sp.size_bytes());
743
+
sbn_void(sp.data(), sp.size()); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
744
+
sbn_void(sp.first(42).data(), n); // expected-warning{{unsafe assignment to function parameter of count-attributed type}}
745
+
}
746
+
747
+
voidnonnull_tofrom_nullable(size_t n,
748
+
int *__counted_by(n) cb,
749
+
int *__counted_by_or_null(n) cbn,
750
+
void *__sized_by(n) sb,
751
+
void *__sized_by_or_null(n) sbn) {
752
+
cb_int(cb, n);
753
+
// expected-note@+2{{passing '__counted_by_or_null()' to '__counted_by()' while '__counted_by_or_null()' can be null with an arbirary count}}
754
+
// expected-warning@+1{{unsafe assignment to function parameter of count-attributed type}}
755
+
cb_int(cbn, n);
756
+
757
+
cbn_int(cb, n);
758
+
cbn_int(cbn, n);
759
+
760
+
sb_void(sb, n);
761
+
// expected-note@+2{{passing '__sized_by_or_null()' to '__sized_by()' while '__sized_by_or_null()' can be null with an arbirary size}}
762
+
// expected-warning@+1{{unsafe assignment to function parameter of count-attributed type}}
763
+
sb_void(sbn, n);
764
+
765
+
sbn_void(sb, n);
766
+
sbn_void(sbn, n);
767
+
}
768
+
711
769
// Check default args.
712
770
713
771
voidcb_def_arg_null_0(int *__counted_by(count) p = nullptr, size_t count = 0);
// __counted_by_or_null(count) pointer can be null with an arbitrary count.
183
+
// We rely here on the dynamic check performed by std::span constructor, and
184
+
// allow those patterns.
185
+
std::span<int>{cbn_p, count};
186
+
std::span<char>{sbn_p, size};
187
+
188
+
std::span<int>{cbn_p, 42}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
189
+
std::span<char>{sbn_p, 42}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
0 commit comments