[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / return-ptr-range.cpp
blob507720a47ea7d5353bcad2bf2e188f47a51bc2b6
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.security.ReturnPtrRange -analyzer-output text -verify %s
3 int conjure_index();
5 namespace test_element_index_lifetime {
7 int arr[10]; // expected-note{{Original object declared here}} expected-note{{Original object declared here}}
8 int *ptr;
10 int *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-warning
17 } 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}}
23 int *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-warning
31 } 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}}
39 template <typename T, int N>
40 T* 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.
44 void get_end_of_array() {
45 static int arr[10];
46 end(arr);
49 template <int N>
50 class Iterable {
51 int buffer[N];
52 int *start, *finish;
54 public:
55 Iterable() : start(buffer), finish(buffer + N) {}
57 int* begin() { return start; }
58 int* end() { return finish; }
61 void use_iterable_object() {
62 Iterable<20> iter;
63 iter.end();
66 template <int N>
67 class BadIterable {
68 int buffer[N]; // expected-note{{Original object declared here}}
69 int *start, *finish;
71 public:
72 BadIterable() : start(buffer), finish(buffer + N) {} // expected-note{{Value assigned to 'iter.finish'}}
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}}
80 void 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'}}
86 int *test_idx_sym(int I) {
87 static int arr[10]; // expected-note{{Original object declared here}} expected-note{{'arr' initialized here}}
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}}
97 namespace test_array_of_struct {
99 struct Data {
100 int A;
101 char *B;
104 Data DataArr[10]; // expected-note{{Original object declared here}}
106 Data *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}}
118 namespace std {
119 // A builtin function with the body generated on the fly.
120 template <typename T> T&& move(T &&) noexcept;
121 } // namespace std
123 char buf[2];
125 void top() {
126 // see https://github.com/llvm/llvm-project/issues/55347
127 (void)std::move(*(buf + 3)); // no-crash