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