out-of-bounds.c revision 76462f00854171d2aa3ebc34f9aac1c60021b0ea
1// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,experimental.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
6void test1(int x) {
7  int buf[100];
8  buf[100] = 1; // expected-warning{{Out of bound memory access}}
9}
10
11void test1_ok(int x) {
12  int buf[100];
13  buf[99] = 1; // no-warning
14}
15
16const char test1_strings_underrun(int x) {
17  const char *mystr = "mary had a little lamb";
18  return mystr[-1]; // expected-warning{{Out of bound memory access}}
19}
20
21const char test1_strings_overrun(int x) {
22  const char *mystr = "mary had a little lamb";
23  return mystr[1000];  // expected-warning{{Out of bound memory access}}
24}
25
26const char test1_strings_ok(int x) {
27  const char *mystr = "mary had a little lamb";
28  return mystr[5]; // no-warning
29}
30
31// Tests doing an out-of-bounds access after the end of an array using:
32// - indirect pointer to buffer
33// - constant integer index
34// - constant integer size for buffer
35void test1_ptr(int x) {
36  int buf[100];
37  int *p = buf;
38  p[101] = 1; // expected-warning{{Out of bound memory access}}
39}
40
41void test1_ptr_ok(int x) {
42  int buf[100];
43  int *p = buf;
44  p[99] = 1; // no-warning
45}
46
47// Tests doing an out-of-bounds access before the start of an array using:
48// - indirect pointer to buffer, manipulated using simple pointer arithmetic
49// - constant integer index
50// - constant integer size for buffer
51void test1_ptr_arith(int x) {
52  int buf[100];
53  int *p = buf;
54  p = p + 100;
55  p[0] = 1; // expected-warning{{Out of bound memory access}}
56}
57
58void test1_ptr_arith_ok(int x) {
59  int buf[100];
60  int *p = buf;
61  p = p + 99;
62  p[0] = 1; // no-warning
63}
64
65void test1_ptr_arith_bad(int x) {
66  int buf[100];
67  int *p = buf;
68  p = p + 99;
69  p[1] = 1; // expected-warning{{Out of bound memory access}}
70}
71
72void test1_ptr_arith_ok2(int x) {
73  int buf[100];
74  int *p = buf;
75  p = p + 99;
76  p[-1] = 1; // no-warning
77}
78
79// Tests doing an out-of-bounds access before the start of an array using:
80// - constant integer index
81// - constant integer size for buffer
82void test2(int x) {
83  int buf[100];
84  buf[-1] = 1; // expected-warning{{Out of bound memory access}}
85}
86
87// Tests doing an out-of-bounds access before the start of an array using:
88// - indirect pointer to buffer
89// - constant integer index
90// - constant integer size for buffer
91void test2_ptr(int x) {
92  int buf[100];
93  int *p = buf;
94  p[-1] = 1; // expected-warning{{Out of bound memory access}}
95}
96
97// Tests doing an out-of-bounds access before the start of an array using:
98// - indirect pointer to buffer, manipulated using simple pointer arithmetic
99// - constant integer index
100// - constant integer size for buffer
101void test2_ptr_arith(int x) {
102  int buf[100];
103  int *p = buf;
104  --p;
105  p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
106}
107
108// Tests doing an out-of-bounds access before the start of a multi-dimensional
109// array using:
110// - constant integer indices
111// - constant integer sizes for the array
112void test2_multi(int x) {
113  int buf[100][100];
114  buf[0][-1] = 1; // expected-warning{{Out of bound memory access}}
115}
116
117// Tests doing an out-of-bounds access before the start of a multi-dimensional
118// array using:
119// - constant integer indices
120// - constant integer sizes for the array
121void test2_multi_b(int x) {
122  int buf[100][100];
123  buf[-1][0] = 1; // expected-warning{{Out of bound memory access}}
124}
125
126void test2_multi_ok(int x) {
127  int buf[100][100];
128  buf[0][0] = 1; // no-warning
129}
130
131// Testing if solver handles (symbol * constant) < constant
132void test3(int x) {
133  int buf[100];
134  if (x < 0)
135    buf[x] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
136}
137
138// *** FIXME ***
139// We don't get a warning here yet because our symbolic constraint solving
140// doesn't handle:  (symbol * constant) < constant
141void test4(int x) {
142  int buf[100];
143  if (x > 99)
144    buf[x] = 1;
145}
146
147// Don't warn when indexing below the start of a symbolic region's whose
148// base extent we don't know.
149int *get_symbolic();
150void test_index_below_symboloc() {
151  int *buf = get_symbolic();
152  buf[-1] = 0; // no-warning;
153}
154
155