1 // RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s
2
3 // Tests doing an out-of-bounds access after the end of an array using:
4 // - constant integer index
5 // - constant integer size for buffer
test1(int x)6 void test1(int x) {
7 int *buf = new int[100];
8 buf[100] = 1; // expected-warning{{Out of bound memory access}}
9 }
10
test1_ok(int x)11 void test1_ok(int x) {
12 int *buf = new int[100];
13 buf[99] = 1; // no-warning
14 }
15
16 // Tests doing an out-of-bounds access after the end of an array using:
17 // - indirect pointer to buffer
18 // - constant integer index
19 // - constant integer size for buffer
test1_ptr(int x)20 void test1_ptr(int x) {
21 int *buf = new int[100];
22 int *p = buf;
23 p[101] = 1; // expected-warning{{Out of bound memory access}}
24 }
25
test1_ptr_ok(int x)26 void test1_ptr_ok(int x) {
27 int *buf = new int[100];
28 int *p = buf;
29 p[99] = 1; // no-warning
30 }
31
32 // Tests doing an out-of-bounds access before the start of an array using:
33 // - indirect pointer to buffer, manipulated using simple pointer arithmetic
34 // - constant integer index
35 // - constant integer size for buffer
test1_ptr_arith(int x)36 void test1_ptr_arith(int x) {
37 int *buf = new int[100];
38 int *p = buf;
39 p = p + 100;
40 p[0] = 1; // expected-warning{{Out of bound memory access}}
41 }
42
test1_ptr_arith_ok(int x)43 void test1_ptr_arith_ok(int x) {
44 int *buf = new int[100];
45 int *p = buf;
46 p = p + 99;
47 p[0] = 1; // no-warning
48 }
49
test1_ptr_arith_bad(int x)50 void test1_ptr_arith_bad(int x) {
51 int *buf = new int[100];
52 int *p = buf;
53 p = p + 99;
54 p[1] = 1; // expected-warning{{Out of bound memory access}}
55 }
56
test1_ptr_arith_ok2(int x)57 void test1_ptr_arith_ok2(int x) {
58 int *buf = new int[100];
59 int *p = buf;
60 p = p + 99;
61 p[-1] = 1; // no-warning
62 }
63
64 // Tests doing an out-of-bounds access before the start of an array using:
65 // - constant integer index
66 // - constant integer size for buffer
test2(int x)67 void test2(int x) {
68 int *buf = new int[100];
69 buf[-1] = 1; // expected-warning{{Out of bound memory access}}
70 }
71
72 // Tests doing an out-of-bounds access before the start of an array using:
73 // - indirect pointer to buffer
74 // - constant integer index
75 // - constant integer size for buffer
test2_ptr(int x)76 void test2_ptr(int x) {
77 int *buf = new int[100];
78 int *p = buf;
79 p[-1] = 1; // expected-warning{{Out of bound memory access}}
80 }
81
82 // Tests doing an out-of-bounds access before the start of an array using:
83 // - indirect pointer to buffer, manipulated using simple pointer arithmetic
84 // - constant integer index
85 // - constant integer size for buffer
test2_ptr_arith(int x)86 void test2_ptr_arith(int x) {
87 int *buf = new int[100];
88 int *p = buf;
89 --p;
90 p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
91 }
92
93 // Tests under-indexing
94 // of a multi-dimensional array
test2_multi(int x)95 void test2_multi(int x) {
96 auto buf = new int[100][100];
97 buf[0][-1] = 1; // expected-warning{{Out of bound memory access}}
98 }
99
100 // Tests under-indexing
101 // of a multi-dimensional array
test2_multi_b(int x)102 void test2_multi_b(int x) {
103 auto buf = new int[100][100];
104 buf[-1][0] = 1; // expected-warning{{Out of bound memory access}}
105 }
106
107 // Tests over-indexing
108 // of a multi-dimensional array
test2_multi_c(int x)109 void test2_multi_c(int x) {
110 auto buf = new int[100][100];
111 buf[100][0] = 1; // expected-warning{{Out of bound memory access}}
112 }
113
114 // Tests over-indexing
115 // of a multi-dimensional array
test2_multi_2(int x)116 void test2_multi_2(int x) {
117 auto buf = new int[100][100];
118 buf[99][100] = 1; // expected-warning{{Out of bound memory access}}
119 }
120
121 // Tests normal access of
122 // a multi-dimensional array
test2_multi_ok(int x)123 void test2_multi_ok(int x) {
124 auto buf = new int[100][100];
125 buf[0][0] = 1; // no-warning
126 }
127
128 // Tests over-indexing using different types
129 // array
test_diff_types(int x)130 void test_diff_types(int x) {
131 int *buf = new int[10]; //10*sizeof(int) Bytes allocated
132 char *cptr = (char *)buf;
133 cptr[sizeof(int) * 9] = 1; // no-warning
134 cptr[sizeof(int) * 10] = 1; // expected-warning{{Out of bound memory access}}
135 }
136
137 // Tests over-indexing
138 //if the allocated area is non-array
test_non_array(int x)139 void test_non_array(int x) {
140 int *ip = new int;
141 ip[0] = 1; // no-warning
142 ip[1] = 2; // expected-warning{{Out of bound memory access}}
143 }
144
145 //Tests over-indexing
146 //if the allocated area size is a runtime parameter
test_dynamic_size(int s)147 void test_dynamic_size(int s) {
148 int *buf = new int[s];
149 buf[0] = 1; // no-warning
150 }
151 //Tests complex arithmetic
152 //in new expression
test_dynamic_size2(unsigned m,unsigned n)153 void test_dynamic_size2(unsigned m,unsigned n){
154 unsigned *U = nullptr;
155 U = new unsigned[m + n + 1];
156 }
157