|
1 |
| -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.ReturnPtrRange -verify %s |
2 |
| - |
3 |
| -int arr[10]; |
4 |
| -int *ptr; |
| 1 | +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.security.ReturnPtrRange -analyzer-output text -verify %s |
5 | 2 |
|
6 | 3 | int conjure_index();
|
7 | 4 |
|
8 |
| -int *test_element_index_lifetime() { |
9 |
| - do { |
| 5 | +namespace test_element_index_lifetime { |
| 6 | + |
| 7 | +int arr[10]; // expected-note{{Original object declared here}} expected-note{{Original object declared here}} |
| 8 | +int *ptr; |
| 9 | + |
| 10 | +int *test_global_ptr() { |
| 11 | + do { // expected-note{{Loop condition is false. Exiting loop}} |
10 | 12 | int x = conjure_index();
|
11 |
| - ptr = arr + x; |
12 |
| - if (x != 20) |
| 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}} |
13 | 16 | return arr; // no-warning
|
14 |
| - } while (0); |
15 |
| - return ptr; // expected-warning{{Returned pointer value points outside the original object (potential buffer overflow)}} |
| 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}} |
16 | 21 | }
|
17 | 22 |
|
18 |
| -int *test_element_index_lifetime_with_local_ptr() { |
| 23 | +int *test_local_ptr() { |
19 | 24 | int *local_ptr;
|
20 |
| - do { |
| 25 | + do { // expected-note{{Loop condition is false. Exiting loop}} |
21 | 26 | int x = conjure_index();
|
22 |
| - local_ptr = arr + x; |
23 |
| - if (x != 20) |
| 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}} |
24 | 30 | return arr; // no-warning
|
25 |
| - } while (0); |
26 |
| - return local_ptr; // expected-warning{{Returned pointer value points outside the original object (potential buffer overflow)}} |
| 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}} |
| 35 | +} |
| 36 | + |
27 | 37 | }
|
28 | 38 |
|
29 | 39 | template <typename T, int N>
|
@@ -55,17 +65,53 @@ void use_iterable_object() {
|
55 | 65 |
|
56 | 66 | template <int N>
|
57 | 67 | class BadIterable {
|
58 |
| - int buffer[N]; |
| 68 | + int buffer[N]; // expected-note{{Original object declared here}} |
59 | 69 | int *start, *finish;
|
60 | 70 |
|
61 | 71 | public:
|
62 |
| - BadIterable() : start(buffer), finish(buffer + N) {} |
| 72 | + BadIterable() : start(buffer), finish(buffer + N) {} // expected-note{{Value assigned to 'iter.finish'}} |
63 | 73 |
|
64 | 74 | int* begin() { return start; }
|
65 |
| - int* end() { return finish + 1; } // expected-warning{{Returned pointer value points outside the original object (potential buffer overflow)}} |
| 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}} |
66 | 78 | };
|
67 | 79 |
|
68 | 80 | void use_bad_iterable_object() {
|
69 |
| - BadIterable<20> iter; |
70 |
| - iter.end(); |
| 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'}} |
71 | 84 | }
|
| 85 | + |
| 86 | +int *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 | + |
| 97 | +namespace test_array_of_struct { |
| 98 | + |
| 99 | +struct Data { |
| 100 | + int A; |
| 101 | + char *B; |
| 102 | +}; |
| 103 | + |
| 104 | +Data DataArr[10]; // expected-note{{Original object declared here}} |
| 105 | + |
| 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}} |
| 114 | +} |
| 115 | + |
| 116 | +} |
| 117 | + |
0 commit comments