150
|
1 // RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,alpha.security.ArrayBoundV2,debug.ExprInspection -verify %s
|
|
2
|
|
3 void clang_analyzer_eval(int);
|
|
4
|
|
5 // Tests doing an out-of-bounds access after the end of an array using:
|
|
6 // - constant integer index
|
|
7 // - constant integer size for buffer
|
|
8 void test1(int x) {
|
|
9 int buf[100];
|
|
10 buf[100] = 1; // expected-warning{{Out of bound memory access}}
|
|
11 }
|
|
12
|
|
13 void test1_ok(int x) {
|
|
14 int buf[100];
|
|
15 buf[99] = 1; // no-warning
|
|
16 }
|
|
17
|
|
18 const char test1_strings_underrun(int x) {
|
|
19 const char *mystr = "mary had a little lamb";
|
|
20 return mystr[-1]; // expected-warning{{Out of bound memory access}}
|
|
21 }
|
|
22
|
|
23 const char test1_strings_overrun(int x) {
|
|
24 const char *mystr = "mary had a little lamb";
|
|
25 return mystr[1000]; // expected-warning{{Out of bound memory access}}
|
|
26 }
|
|
27
|
|
28 const char test1_strings_ok(int x) {
|
|
29 const char *mystr = "mary had a little lamb";
|
|
30 return mystr[5]; // no-warning
|
|
31 }
|
|
32
|
|
33 // Tests doing an out-of-bounds access after the end of an array using:
|
|
34 // - indirect pointer to buffer
|
|
35 // - constant integer index
|
|
36 // - constant integer size for buffer
|
|
37 void test1_ptr(int x) {
|
|
38 int buf[100];
|
|
39 int *p = buf;
|
|
40 p[101] = 1; // expected-warning{{Out of bound memory access}}
|
|
41 }
|
|
42
|
|
43 void test1_ptr_ok(int x) {
|
|
44 int buf[100];
|
|
45 int *p = buf;
|
|
46 p[99] = 1; // no-warning
|
|
47 }
|
|
48
|
|
49 // Tests doing an out-of-bounds access before the start of an array using:
|
|
50 // - indirect pointer to buffer, manipulated using simple pointer arithmetic
|
|
51 // - constant integer index
|
|
52 // - constant integer size for buffer
|
|
53 void test1_ptr_arith(int x) {
|
|
54 int buf[100];
|
|
55 int *p = buf;
|
|
56 p = p + 100;
|
|
57 p[0] = 1; // expected-warning{{Out of bound memory access}}
|
|
58 }
|
|
59
|
|
60 void test1_ptr_arith_ok(int x) {
|
|
61 int buf[100];
|
|
62 int *p = buf;
|
|
63 p = p + 99;
|
|
64 p[0] = 1; // no-warning
|
|
65 }
|
|
66
|
|
67 void test1_ptr_arith_bad(int x) {
|
|
68 int buf[100];
|
|
69 int *p = buf;
|
|
70 p = p + 99;
|
|
71 p[1] = 1; // expected-warning{{Out of bound memory access}}
|
|
72 }
|
|
73
|
|
74 void test1_ptr_arith_ok2(int x) {
|
|
75 int buf[100];
|
|
76 int *p = buf;
|
|
77 p = p + 99;
|
|
78 p[-1] = 1; // no-warning
|
|
79 }
|
|
80
|
|
81 // Tests doing an out-of-bounds access before the start of an array using:
|
|
82 // - constant integer index
|
|
83 // - constant integer size for buffer
|
|
84 void test2(int x) {
|
|
85 int buf[100];
|
|
86 buf[-1] = 1; // expected-warning{{Out of bound memory access}}
|
|
87 }
|
|
88
|
|
89 // Tests doing an out-of-bounds access before the start of an array using:
|
|
90 // - indirect pointer to buffer
|
|
91 // - constant integer index
|
|
92 // - constant integer size for buffer
|
|
93 void test2_ptr(int x) {
|
|
94 int buf[100];
|
|
95 int *p = buf;
|
|
96 p[-1] = 1; // expected-warning{{Out of bound memory access}}
|
|
97 }
|
|
98
|
|
99 // Tests doing an out-of-bounds access before the start of an array using:
|
|
100 // - indirect pointer to buffer, manipulated using simple pointer arithmetic
|
|
101 // - constant integer index
|
|
102 // - constant integer size for buffer
|
|
103 void test2_ptr_arith(int x) {
|
|
104 int buf[100];
|
|
105 int *p = buf;
|
|
106 --p;
|
|
107 p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
|
|
108 }
|
|
109
|
|
110 // Tests doing an out-of-bounds access before the start of a multi-dimensional
|
|
111 // array using:
|
|
112 // - constant integer indices
|
|
113 // - constant integer sizes for the array
|
|
114 void test2_multi(int x) {
|
|
115 int buf[100][100];
|
|
116 buf[0][-1] = 1; // expected-warning{{Out of bound memory access}}
|
|
117 }
|
|
118
|
|
119 // Tests doing an out-of-bounds access before the start of a multi-dimensional
|
|
120 // array using:
|
|
121 // - constant integer indices
|
|
122 // - constant integer sizes for the array
|
|
123 void test2_multi_b(int x) {
|
|
124 int buf[100][100];
|
|
125 buf[-1][0] = 1; // expected-warning{{Out of bound memory access}}
|
|
126 }
|
|
127
|
|
128 void test2_multi_ok(int x) {
|
|
129 int buf[100][100];
|
|
130 buf[0][0] = 1; // no-warning
|
|
131 }
|
|
132
|
|
133 void test3(int x) {
|
|
134 int buf[100];
|
|
135 if (x < 0)
|
|
136 buf[x] = 1; // expected-warning{{Out of bound memory access}}
|
|
137 }
|
|
138
|
|
139 void test4(int x) {
|
|
140 int buf[100];
|
|
141 if (x > 99)
|
|
142 buf[x] = 1; // expected-warning{{Out of bound memory access}}
|
|
143 }
|
|
144
|
|
145 void test_assume_after_access(unsigned long x) {
|
|
146 int buf[100];
|
|
147 buf[x] = 1;
|
|
148 clang_analyzer_eval(x <= 99); // expected-warning{{TRUE}}
|
|
149 }
|
|
150
|
|
151 // Don't warn when indexing below the start of a symbolic region's whose
|
|
152 // base extent we don't know.
|
|
153 int *get_symbolic();
|
|
154 void test_index_below_symboloc() {
|
|
155 int *buf = get_symbolic();
|
|
156 buf[-1] = 0; // no-warning;
|
|
157 }
|
|
158
|
|
159 void test_incomplete_struct() {
|
|
160 extern struct incomplete incomplete;
|
|
161 int *p = (int *)&incomplete;
|
|
162 p[1] = 42; // no-warning
|
|
163 }
|
|
164
|
|
165 void test_extern_void() {
|
|
166 extern void v;
|
|
167 int *p = (int *)&v;
|
|
168 p[1] = 42; // no-warning
|
|
169 }
|
|
170
|
|
171 void test_assume_after_access2(unsigned long x) {
|
|
172 char buf[100];
|
|
173 buf[x] = 1;
|
|
174 clang_analyzer_eval(x <= 99); // expected-warning{{TRUE}}
|
|
175 }
|
|
176
|