1 // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \
2 // RUN: -fsafe-buffer-usage-suggestions -verify %s
4 using size_t = __typeof(sizeof(int));
11 template <typename T
> class span
{
20 constexpr T
* data() const noexcept
{
24 constexpr size_t size() const noexcept
{
32 [[clang::unsafe_buffer_usage
]]
41 [[clang::unsafe_buffer_usage
]]
46 [[clang::unsafe_buffer_usage
]]
49 [[clang::unsafe_buffer_usage
]]
58 void foo_safe(std::span
<int> sp
);
60 int* test_atribute_struct(A a
) {
61 int b
= *(a
.ptr
); //expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}
63 // expected-warning@+1{{unsafe pointer arithmetic}}
64 return a
.ptr
++; //expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}
67 void test_attribute_field_deref_chain(B b
) {
68 int *ptr
= b
.a
.ptr
;//expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}
69 foo(b
.buf
); //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}
72 void test_writes_from_span(std::span
<int> sp
) {
74 a
.ptr
= sp
.data(); //expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}
77 a
.ptr
= nullptr; // expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}
80 void test_reads_to_span(A a
, A b
) {
81 //expected-warning@+1{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
82 std::span
<int> sp
{a
.ptr
, a
.sz
}; //expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}
84 // expected-warning@+1 3{{field 'ptr' prone to unsafe buffer manipulation}}
85 if(a
.ptr
!= nullptr && a
.ptr
!= b
.ptr
) {
91 void test_attribute_multiple_fields (D d
) {
92 int *p
=d
.ptr
; //expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}
93 p
= d
.ptr2
; //expected-warning{{field 'ptr2' prone to unsafe buffer manipulation}}
95 p
= d
.buf
; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}
97 int v
= d
.buf
[0]; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}
99 //expected-warning@+1{{unsafe buffer access}}
100 v
= d
.buf
[5]; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}
103 template <typename T
>
104 struct TemplateArray
{
105 [[clang::unsafe_buffer_usage
]]
108 [[clang::unsafe_buffer_usage
]]
113 void test_struct_template (TemplateArray
<int> t
) {
114 int *p
= t
.buf
; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}
115 size_t s
= t
.sz
; //expected-warning{{field 'sz' prone to unsafe buffer manipulation}}
119 [[clang::unsafe_buffer_usage
]]
124 return array
; //expected-warning{{field 'array' prone to unsafe buffer manipulation}}
127 void setArray(int *arr
) {
128 array
= arr
; //expected-warning{{field 'array' prone to unsafe buffer manipulation}}
134 [[clang::unsafe_buffer_usage
]]
139 return array
; //expected-warning{{field 'array' prone to unsafe buffer manipulation}}
142 void setArray(P
*arr
) {
143 array
= arr
; //expected-warning{{field 'array' prone to unsafe buffer manipulation}}
147 void test_class_template(Q
<R
> q
) {
154 [[clang::unsafe_buffer_usage
]]
159 void test_anon_struct_fields(AnonSFields anon
) {
160 int val
= anon
.a
; //expected-warning{{field 'a' prone to unsafe buffer manipulation}}
164 [[clang::unsafe_buffer_usage
]]
174 void test_attribute_union(C c
) {
175 int *p
= c
.ptr
.ptr1
; //expected-warning{{field 'ptr1' prone to unsafe buffer manipulation}}
177 int address
= c
.ptr
.ptr2
;
181 [[clang::unsafe_buffer_usage
]]
187 void test_anon_struct(AnonFields2 af
) {
188 int val
= af
.a
; // No warning here, as the attribute is not explicitly attached to field 'a'