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