blob: 1970cd658c42737f4e88bb138e6d4ca963243220 [file] [log] [blame]
Dominic Chen184c6242017-03-03 18:02:02 +00001// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,alpha.security.ArrayBoundV2,debug.ExprInspection -verify %s
Gabor Horvath855ad822016-08-22 10:07:32 +00002
3void clang_analyzer_eval(int);
Ted Kremeneke73571b2010-12-23 02:42:43 +00004
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
8void test1(int x) {
9 int buf[100];
10 buf[100] = 1; // expected-warning{{Out of bound memory access}}
11}
12
13void test1_ok(int x) {
14 int buf[100];
15 buf[99] = 1; // no-warning
16}
17
Ted Kremenekbd5fcdf2010-12-23 02:42:49 +000018const 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
23const 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
28const char test1_strings_ok(int x) {
29 const char *mystr = "mary had a little lamb";
30 return mystr[5]; // no-warning
31}
32
Ted Kremeneke73571b2010-12-23 02:42:43 +000033// 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
37void 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
43void test1_ptr_ok(int x) {
44 int buf[100];
45 int *p = buf;
Ted Kremenekbd5fcdf2010-12-23 02:42:49 +000046 p[99] = 1; // no-warning
Ted Kremeneke73571b2010-12-23 02:42:43 +000047}
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
53void test1_ptr_arith(int x) {
54 int buf[100];
55 int *p = buf;
56 p = p + 100;
Ted Kremenek5614c462010-12-24 08:39:33 +000057 p[0] = 1; // expected-warning{{Out of bound memory access}}
Ted Kremeneke73571b2010-12-23 02:42:43 +000058}
59
60void 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
67void test1_ptr_arith_bad(int x) {
68 int buf[100];
69 int *p = buf;
70 p = p + 99;
Ted Kremenek5614c462010-12-24 08:39:33 +000071 p[1] = 1; // expected-warning{{Out of bound memory access}}
Ted Kremeneke73571b2010-12-23 02:42:43 +000072}
73
74void test1_ptr_arith_ok2(int x) {
75 int buf[100];
76 int *p = buf;
Ted Kremenekbd5fcdf2010-12-23 02:42:49 +000077 p = p + 99;
Ted Kremenek5614c462010-12-24 08:39:33 +000078 p[-1] = 1; // no-warning
Ted Kremeneke73571b2010-12-23 02:42:43 +000079}
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
84void 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
93void 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
103void test2_ptr_arith(int x) {
104 int buf[100];
105 int *p = buf;
106 --p;
Ted Kremeneke9fda1e2011-07-28 23:07:59 +0000107 p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
Ted Kremeneke73571b2010-12-23 02:42:43 +0000108}
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
114void 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
123void test2_multi_b(int x) {
124 int buf[100][100];
125 buf[-1][0] = 1; // expected-warning{{Out of bound memory access}}
126}
127
128void test2_multi_ok(int x) {
129 int buf[100][100];
130 buf[0][0] = 1; // no-warning
131}
132
Ted Kremeneke73571b2010-12-23 02:42:43 +0000133void test3(int x) {
134 int buf[100];
135 if (x < 0)
Gabor Horvath855ad822016-08-22 10:07:32 +0000136 buf[x] = 1; // expected-warning{{Out of bound memory access}}
Ted Kremeneke73571b2010-12-23 02:42:43 +0000137}
138
Ted Kremeneke73571b2010-12-23 02:42:43 +0000139void test4(int x) {
140 int buf[100];
141 if (x > 99)
Gabor Horvath855ad822016-08-22 10:07:32 +0000142 buf[x] = 1; // expected-warning{{Out of bound memory access}}
143}
144
145void test_assume_after_access(unsigned long x) {
146 int buf[100];
147 buf[x] = 1;
148 clang_analyzer_eval(x <= 99); // expected-warning{{TRUE}}
Ted Kremeneke73571b2010-12-23 02:42:43 +0000149}
Ted Kremenek8a4c7602011-04-12 17:21:33 +0000150
151// Don't warn when indexing below the start of a symbolic region's whose
152// base extent we don't know.
153int *get_symbolic();
154void test_index_below_symboloc() {
155 int *buf = get_symbolic();
156 buf[-1] = 0; // no-warning;
157}
158
Jordan Rose1bd19272013-05-29 20:50:34 +0000159void test_incomplete_struct() {
160 extern struct incomplete incomplete;
161 int *p = (int *)&incomplete;
162 p[1] = 42; // no-warning
163}
164
165void test_extern_void() {
166 extern void v;
167 int *p = (int *)&v;
168 p[1] = 42; // no-warning
169}
170
Gabor Horvath855ad822016-08-22 10:07:32 +0000171void 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