1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.security.ReturnPtrRange -analyzer-output text -verify %s
5 namespace test_element_index_lifetime
{
7 int arr
[10]; // expected-note{{Original object declared here}} expected-note{{Original object declared here}}
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
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() {
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
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
>
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() {
55 Iterable() : start(buffer
), finish(buffer
+ N
) {}
57 int* begin() { return start
; }
58 int* end() { return finish
; }
61 void use_iterable_object() {
68 int buffer
[N
]; // expected-note{{Original object declared here}}
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}}
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
{
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}}
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}}
119 // A builtin function with the body generated on the fly.
120 template <typename T
> T
&& move(T
&&) noexcept
;
126 // see https://github.com/llvm/llvm-project/issues/55347
127 (void)std::move(*(buf
+ 3)); // no-crash