brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · 00daa28 Raw
209 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -Wno-everything -Wunsafe-buffer-usage \2// RUN:            -fsafe-buffer-usage-suggestions \3// RUN:            -verify %s4 5// CHECK-NOT: [-Wunsafe-buffer-usage]6 7 8void foo(unsigned idx) {9  int buffer[10];         // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}10                          // expected-note@-1{{change type of 'buffer' to 'std::array' to label it for hardening}}11  buffer[idx] = 0;        // expected-note{{used in buffer access here}}12}13 14int global_buffer[10];    // expected-warning{{'global_buffer' is an unsafe buffer that does not perform bounds checks}}15void foo2(unsigned idx) {16  global_buffer[idx] = 0;        // expected-note{{used in buffer access here}}17}18 19struct Foo {20  int member_buffer[10];21  int x;22};23 24void foo2(Foo& f, unsigned idx) {25  f.member_buffer[idx] = 0; // expected-warning{{unsafe buffer access}}26}27 28void constant_idx_safe(unsigned idx) {29  int buffer[10];30  buffer[9] = 0;31}32 33void constant_idx_safe0(unsigned idx) {34  int buffer[10];35  buffer[0] = 0;36}37 38int array[10]; // expected-warning 3{{'array' is an unsafe buffer that does not perform bounds checks}}39 40void circular_access_unsigned(unsigned idx) {41  array[idx % 10];42  array[idx % 11]; // expected-note {{used in buffer access here}}43  array[(idx + 3) % 10];44  array[(--idx) % 8];45  array[idx & 9 % 10];46  array[9 & idx % 11];47  array [12 % 10];48}49 50void circular_access_signed(int idx) {51  array[idx % 10]; // expected-note {{used in buffer access here}}52}53 54void masked_idx1(unsigned long long idx, Foo f) {55  // Bitwise and operation56  array[idx & 5] = 10; // no-warning57  array[5 &idx] = 12; // no-warning58  array[idx & 11 & 5] = 3; // no warning59  array[idx & 11] = 20; // expected-note{{used in buffer access here}}60  array[idx &=5]; // expected-note{{used in buffer access here}}61  array[f.x & 5]; // no-warning62  array[5 & f.x]; // no-warning63  array[f.x & (-5)]; // expected-note{{used in buffer access here}}64}65 66typedef unsigned long long uint64_t;67typedef unsigned int uint32_t;68typedef unsigned char uint8_t;69 70void type_conversions(uint64_t idx1, uint32_t idx2, uint8_t idx3) {71  array[(uint32_t)idx1 & 3];72  array[idx2 & 3];73  array[idx3 & 3];74}75 76int array2[5]; // expected-warning {{'array2' is an unsafe buffer that does not perform bounds checks}}77 78void masked_idx_safe(unsigned long long idx) {79  array2[6 & 5]; // no warning80  array2[6 & idx & (idx + 1) & 5]; // expected-note{{used in buffer access here}}81}82 83void constant_idx_unsafe(unsigned idx) {84  int buffer[10];       // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}85                        // expected-note@-1{{change type of 'buffer' to 'std::array' to label it for hardening}}86  buffer[10] = 0;       // expected-note{{used in buffer access here}}87}88 89void constant_id_string(unsigned idx) {90  char safe_char = "abc"[1]; // no-warning91  safe_char = ""[0];92  safe_char = "\0"[0];93 94  char abcd[5] = "abc";95  abcd[2]; // no-warning96 97  char unsafe_char = "abc"[3];98  unsafe_char = "abc"[-1]; //expected-warning{{unsafe buffer access}}99  unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}} 100  unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}}101}102 103typedef float Float4x4[4][4];104 105// expected-warning@+1 {{'matrix' is an unsafe buffer that does not perform bounds checks}}106float two_dimension_array(Float4x4& matrix, unsigned idx) {107  // expected-warning@+1{{unsafe buffer access}}108  float a = matrix[0][4];109 110  a = matrix[0][3];111 112  // expected-note@+1{{used in buffer access here}}113  a = matrix[4][0];114 115  a = matrix[idx][0]; // expected-note{{used in buffer access here}}116 117  a = matrix[0][idx]; //expected-warning{{unsafe buffer access}}118 119  a = matrix[idx][idx]; //expected-warning{{unsafe buffer access}} // expected-note{{used in buffer access here}}120 121  return matrix[1][1];122}123 124typedef float Float2x3x4[2][3][4];125float multi_dimension_array(Float2x3x4& matrix) {126  float *f = matrix[0][2];127  return matrix[1][2][3];128}129 130char array_strings[][11] = {131  "Apple", "Banana", "Cherry", "Date", "Elderberry"132};133 134char array_string[] = "123456";135 136char access_strings() {137  char c = array_strings[0][4];138  c = array_strings[3][10];139  c = array_string[5];140  return c;141}142 143struct T {144  int array[10];145};146 147const int index = 1;148 149constexpr int get_const(int x) {150  if(x < 3)151    return ++x;152  else153    return x + 5;154};155 156void array_indexed_const_expr(unsigned idx) {157  // expected-note@+2 {{change type of 'arr' to 'std::array' to label it for hardening}}158  // expected-warning@+1{{'arr' is an unsafe buffer that does not perform bounds checks}}159  int arr[10];160  arr[sizeof(int)] = 5;161 162  int array[sizeof(T)];163  array[sizeof(int)] = 5;164  array[sizeof(T) -1 ] = 3;165 166  int k = arr[6 & 5];167  k = arr[2 << index];168  k = arr[8 << index]; // expected-note {{used in buffer access here}}169  k = arr[16 >> 1];170  k = arr[get_const(index)];171  k = arr[get_const(5)]; // expected-note {{used in buffer access here}}172  k = arr[get_const(4)];173}174 175template<unsigned length>176consteval bool isNullTerminated(const char (&literal)[length])177{178  return literal[length - 1] == '\0';179}180 181template <typename T, unsigned M, unsigned N>182T access2DArray(const T (&arr)[M][N]) {183  return arr[M-1][N-1];184}185 186template<unsigned idx>187constexpr int access_elements() {188  int arr[idx + 20];189  return arr[idx + 1];190}191 192// Test array accesses where const sized arrays are accessed safely with indices193// that evaluate to a const values and depend on template arguments.194void test_template_methods()195{196  constexpr char arr[] = "Good Morning!"; // = {'a', 'b', 'c', 'd', 'e'};197  isNullTerminated(arr);198  isNullTerminated("");199  auto _ = isNullTerminated("hello world\n");200  access_elements<5>();201 202  int arr1[3][4] = {203        {1, 2, 3, 4},204        {5, 6, 7, 8},205        {9, 10, 11, 12}206    };207  access2DArray(arr1);208}209