brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · 507720a Raw
129 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.security.ReturnPtrRange -analyzer-output text -verify %s2 3int conjure_index();4 5namespace test_element_index_lifetime {6 7int arr[10]; // expected-note{{Original object declared here}} expected-note{{Original object declared here}}8int *ptr;9 10int *test_global_ptr() {11  do { // expected-note{{Loop condition is false.  Exiting loop}}12    int x = conjure_index();13    ptr = arr + x; // expected-note{{Value assigned to 'ptr'}}14    if (x != 20) // expected-note{{Assuming 'x' is equal to 20}}15                 // expected-note@-1{{Taking false branch}}16      return arr; // no-warning17  } while(0);18  return ptr; // expected-warning{{Returned pointer value points outside the original object (potential buffer overflow) [alpha.security.ReturnPtrRange]}}19              // expected-note@-1{{Returned pointer value points outside the original object (potential buffer overflow)}}20              // expected-note@-2{{Original object 'arr' is an array of 10 'int' objects}}21}22 23int *test_local_ptr() {24  int *local_ptr;25  do { // expected-note{{Loop condition is false.  Exiting loop}}26    int x = conjure_index();27    local_ptr = arr + x; // expected-note{{Value assigned to 'local_ptr'}}28    if (x != 20) // expected-note{{Assuming 'x' is equal to 20}}29                 // expected-note@-1{{Taking false branch}}30      return arr; // no-warning31  } while(0);32  return local_ptr; // expected-warning{{Returned pointer value points outside the original object (potential buffer overflow) [alpha.security.ReturnPtrRange]}}33                    // expected-note@-1{{Returned pointer value points outside the original object (potential buffer overflow)}}34                    // expected-note@-2{{Original object 'arr' is an array of 10 'int' objects}}35}36 37}38 39template <typename T, int N>40T* end(T (&arr)[N]) {41  return arr + N; // no-warning, because we want to avoid false positives on returning the end() iterator of a container.42}43 44void get_end_of_array() {45  static int arr[10];46  end(arr);47}48 49template <int N>50class Iterable {51  int buffer[N];52  int *start, *finish;53 54public:55  Iterable() : start(buffer), finish(buffer + N) {}56 57  int* begin() { return start; }58  int* end() { return finish; }59};60 61void use_iterable_object() {62  Iterable<20> iter;63  iter.end();64}65 66template <int N>67class BadIterable {68  int buffer[N]; // expected-note{{Original object declared here}}69  int *start, *finish;70 71public:72  BadIterable() : start(buffer), finish(buffer + N) {} // expected-note{{Value assigned to 'iter.finish'}}73 74  int* begin() { return start; }75  int* end() { return finish + 1; } // expected-warning{{Returned pointer value points outside the original object}}76                                    // expected-note@-1{{Returned pointer value points outside the original object}}77                                    // expected-note@-2{{Original object 'buffer' is an array of 20 'int' objects, returned pointer points at index 21}}78};79 80void use_bad_iterable_object() {81  BadIterable<20> iter; // expected-note{{Calling default constructor for 'BadIterable<20>'}}82                        // expected-note@-1{{Returning from default constructor for 'BadIterable<20>'}}83  iter.end(); // expected-note{{Calling 'BadIterable::end'}}84}85 86int *test_idx_sym(int I) {87  static int arr[10]; // expected-note{{Original object declared here}} expected-note{{'arr' initialized here}}88 89  if (I != 11) // expected-note{{Assuming 'I' is equal to 11}}90               // expected-note@-1{{Taking false branch}}91    return arr;92  return arr + I; // expected-warning{{Returned pointer value points outside the original object}}93                  // expected-note@-1{{Returned pointer value points outside the original object}}94                  // expected-note@-2{{Original object 'arr' is an array of 10 'int' objects, returned pointer points at index 11}}95}96 97namespace test_array_of_struct {98 99struct Data {100  int A;101  char *B;102};103 104Data DataArr[10]; // expected-note{{Original object declared here}}105 106Data *test_struct_array() {107  int I = conjure_index();108  if (I != 11) // expected-note{{Assuming 'I' is equal to 11}}109               // expected-note@-1{{Taking false branch}}110    return DataArr;111  return DataArr + I; // expected-warning{{Returned pointer value points outside the original object}}112                      // expected-note@-1{{Returned pointer value points outside the original object}}113                      // expected-note@-2{{Original object 'DataArr' is an array of 10 'test_array_of_struct::Data' objects, returned pointer points at index 11}}114}115 116}117 118namespace std {119// A builtin function with the body generated on the fly.120template <typename T> T&& move(T &&) noexcept;121} // namespace std122 123char buf[2];124 125void top() {126  // see https://github.com/llvm/llvm-project/issues/55347127  (void)std::move(*(buf + 3)); // no-crash128}129