[X86] Move getGFNICtrlMask before CTLZ/CTTZ lowering. NFC.
[llvm-project.git] / clang / test / SemaCXX / warn-unsafe-buffer-usage-field-attr.cpp
blob0ba605475925b9c665721c6e297f191d1034a7d5
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));
6 namespace std {
7 class type_info;
8 class bad_cast;
9 class bad_typeid;
11 template <typename T> class span {
13 private:
14 T *elements;
15 size_t size_;
17 public:
18 span(T *, size_t){}
20 constexpr T* data() const noexcept {
21 return elements;
24 constexpr size_t size() const noexcept {
25 return size_;
31 struct A {
32 [[clang::unsafe_buffer_usage]]
33 int *ptr;
35 size_t sz;
38 struct B {
39 A a;
41 [[clang::unsafe_buffer_usage]]
42 int buf[];
45 struct D {
46 [[clang::unsafe_buffer_usage]]
47 int *ptr, *ptr2;
49 [[clang::unsafe_buffer_usage]]
50 int buf[10];
52 size_t sz;
56 void foo(int *ptr);
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}}
62 a.sz++;
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) {
73 A a;
74 a.ptr = sp.data(); //expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}
75 a.sz = sp.size();
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) {
86 foo_safe(sp);
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]]
106 T *buf;
108 [[clang::unsafe_buffer_usage]]
109 size_t sz;
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}}
118 class R {
119 [[clang::unsafe_buffer_usage]]
120 int *array;
122 public:
123 int* getArray() {
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}}
132 template<class P>
133 class Q {
134 [[clang::unsafe_buffer_usage]]
135 P *array;
137 public:
138 P* getArray() {
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) {
148 q.getArray();
149 q.setArray(nullptr);
152 struct AnonSFields {
153 struct {
154 [[clang::unsafe_buffer_usage]]
155 int a;
159 void test_anon_struct_fields(AnonSFields anon) {
160 int val = anon.a; //expected-warning{{field 'a' prone to unsafe buffer manipulation}}
163 union Union {
164 [[clang::unsafe_buffer_usage]]
165 int *ptr1;
167 int ptr2;
170 struct C {
171 Union ptr;
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;
180 struct AnonFields2 {
181 [[clang::unsafe_buffer_usage]]
182 struct {
183 int a;
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'
189 val++;