1 | // RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-store=region -verify %s \ |
2 | // RUN: -analyzer-checker=core \ |
3 | // RUN: -analyzer-checker=unix \ |
4 | // RUN: -analyzer-checker=alpha.security.ArrayBound \ |
5 | // RUN: -analyzer-config unix.DynamicMemoryModeling:Optimistic=true |
6 | |
7 | typedef __typeof(sizeof(int)) size_t; |
8 | void *malloc(size_t); |
9 | void *calloc(size_t, size_t); |
10 | |
11 | char f1() { |
12 | char* s = "abcd"; |
13 | char c = s[4]; // no-warning |
14 | return s[5] + c; // expected-warning{{Access out-of-bound array element (buffer overflow)}} |
15 | } |
16 | |
17 | void f2() { |
18 | int *p = malloc(12); |
19 | p[3] = 4; // expected-warning{{Access out-of-bound array element (buffer overflow)}} |
20 | } |
21 | |
22 | struct three_words { |
23 | int c[3]; |
24 | }; |
25 | |
26 | struct seven_words { |
27 | int c[7]; |
28 | }; |
29 | |
30 | void f3() { |
31 | struct three_words a, *p; |
32 | p = &a; |
33 | p[0] = a; // no-warning |
34 | p[1] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}} |
35 | } |
36 | |
37 | void f4() { |
38 | struct seven_words c; |
39 | struct three_words a, *p = (struct three_words *)&c; |
40 | p[0] = a; // no-warning |
41 | p[1] = a; // no-warning |
42 | p[2] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}} |
43 | } |
44 | |
45 | void f5() { |
46 | char *p = calloc(2,2); |
47 | p[3] = '.'; // no-warning |
48 | p[4] = '!'; // expected-warning{{out-of-bound}} |
49 | } |
50 | |
51 | void f6() { |
52 | char a[2]; |
53 | int *b = (int*)a; |
54 | b[1] = 3; // expected-warning{{out-of-bound}} |
55 | } |
56 | |
57 | void f7() { |
58 | struct three_words a; |
59 | a.c[3] = 1; // expected-warning{{out-of-bound}} |
60 | } |
61 | |
62 | void vla(int a) { |
63 | if (a == 5) { |
64 | int x[a]; |
65 | x[4] = 4; // no-warning |
66 | x[5] = 5; // expected-warning{{out-of-bound}} |
67 | } |
68 | } |
69 | |
70 | void alloca_region(int a) { |
71 | if (a == 5) { |
72 | char *x = __builtin_alloca(a); |
73 | x[4] = 4; // no-warning |
74 | x[5] = 5; // expected-warning{{out-of-bound}} |
75 | } |
76 | } |
77 | |
78 | int symbolic_index(int a) { |
79 | int x[2] = {1, 2}; |
80 | if (a == 2) { |
81 | return x[a]; // expected-warning{{out-of-bound}} |
82 | } |
83 | return 0; |
84 | } |
85 | |
86 | int symbolic_index2(int a) { |
87 | int x[2] = {1, 2}; |
88 | if (a < 0) { |
89 | return x[a]; // expected-warning{{out-of-bound}} |
90 | } |
91 | return 0; |
92 | } |
93 | |
94 | int overflow_binary_search(double in) { |
95 | int eee = 16; |
96 | if (in < 1e-8 || in > 1e23) { |
97 | return 0; |
98 | } else { |
99 | static const double ins[] = {1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, |
100 | 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, |
101 | 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, |
102 | 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; |
103 | if (in < ins[eee]) { |
104 | eee -= 8; |
105 | } else { |
106 | eee += 8; |
107 | } |
108 | if (in < ins[eee]) { |
109 | eee -= 4; |
110 | } else { |
111 | eee += 4; |
112 | } |
113 | if (in < ins[eee]) { |
114 | eee -= 2; |
115 | } else { |
116 | eee += 2; |
117 | } |
118 | if (in < ins[eee]) { |
119 | eee -= 1; |
120 | } else { |
121 | eee += 1; |
122 | } |
123 | if (in < ins[eee]) { // expected-warning {{Access out-of-bound array element (buffer overflow)}} |
124 | eee -= 1; |
125 | } |
126 | } |
127 | return eee; |
128 | } |
129 | |