brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 1636c94 Raw
190 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \2// RUN:            -fsafe-buffer-usage-suggestions -verify %s3 4using size_t = __typeof(sizeof(int));5 6namespace std {7  class type_info;8  class bad_cast;9  class bad_typeid;10 11  template <typename T> class span {12 13  private:14    T *elements;15    size_t size_;16 17  public:18    span(T *, size_t){}19 20    constexpr T* data() const noexcept {21      return elements;22    }23 24    constexpr size_t size() const noexcept {25      return size_;26    }27 28  };29}30 31struct A {32    [[clang::unsafe_buffer_usage]]33    int *ptr;34 35    size_t sz;36};37 38struct B {39   A a;40 41   [[clang::unsafe_buffer_usage]]42   int buf[];43};44 45struct D { 46  [[clang::unsafe_buffer_usage]]47  int *ptr, *ptr2;48 49  [[clang::unsafe_buffer_usage]]50  int buf[10];51 52  size_t sz;53  54};55 56void foo(int *ptr);57 58void foo_safe(std::span<int> sp);59 60int* 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}}65}66 67void 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}}70}71 72void 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();76 77  a.ptr = nullptr; // expected-warning{{field 'ptr' prone to unsafe buffer manipulation}}78}79 80void 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}}83 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);87  }88 89}90 91void 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}}94 95   p = d.buf; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}96 97   int v = d.buf[0]; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}98 99   v = d.buf[5]; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}100}101 102template <typename T>103struct TemplateArray {104  [[clang::unsafe_buffer_usage]]105  T *buf;106 107  [[clang::unsafe_buffer_usage]]108  size_t sz;109};110 111 112void test_struct_template (TemplateArray<int> t) {113  int *p = t.buf; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}114  size_t s = t.sz; //expected-warning{{field 'sz' prone to unsafe buffer manipulation}}115}116 117class R {118  [[clang::unsafe_buffer_usage]]119  int *array;120 121  public:122   int* getArray() {123     return array; //expected-warning{{field 'array' prone to unsafe buffer manipulation}}124   }125 126   void setArray(int *arr) {127     array = arr; //expected-warning{{field 'array' prone to unsafe buffer manipulation}}128   }129};130 131template<class P>132class Q {133  [[clang::unsafe_buffer_usage]]134  P *array;135 136  public:137   P* getArray() {138     return array; //expected-warning{{field 'array' prone to unsafe buffer manipulation}}139   }140 141   void setArray(P *arr) {142     array = arr; //expected-warning{{field 'array' prone to unsafe buffer manipulation}}143   }144};145 146void test_class_template(Q<R> q) {147   q.getArray();148   q.setArray(nullptr);149}150 151struct AnonSFields {152 struct {153  [[clang::unsafe_buffer_usage]]154  int a;155 };156};157 158void test_anon_struct_fields(AnonSFields anon) {159  int val = anon.a; //expected-warning{{field 'a' prone to unsafe buffer manipulation}}160}161 162union Union {163  [[clang::unsafe_buffer_usage]]164  int *ptr1;165 166  int ptr2;167};168 169struct C {170  Union ptr;171};172 173void test_attribute_union(C c) {174  int *p = c.ptr.ptr1; //expected-warning{{field 'ptr1' prone to unsafe buffer manipulation}}175 176  int address = c.ptr.ptr2;177}178 179struct AnonFields2 { 180  [[clang::unsafe_buffer_usage]] 181  struct { 182    int a; 183  }; 184};185 186void test_anon_struct(AnonFields2 af) {187  int val = af.a; // No warning here, as the attribute is not explicitly attached to field 'a'188  val++;189}190