vla.c
3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-checker=debug.ExprInspection -verify %s
typedef unsigned long size_t;
size_t clang_analyzer_getExtent(void *);
void clang_analyzer_eval(int);
// Zero-sized VLAs.
void check_zero_sized_VLA(int x) {
if (x)
return;
int vla[x]; // expected-warning{{Declared variable-length array (VLA) has zero size}}
}
void check_uninit_sized_VLA() {
int x;
int vla[x]; // expected-warning{{Declared variable-length array (VLA) uses a garbage value as its size}}
}
// Negative VLAs.
static void vla_allocate_signed(short x) {
int vla[x]; // expected-warning{{Declared variable-length array (VLA) has negative size}}
}
static void vla_allocate_unsigned(unsigned short x) {
int vla[x]; // no-warning
}
void check_negative_sized_VLA_1() {
vla_allocate_signed(-1);
}
void check_negative_sized_VLA_2() {
vla_allocate_unsigned(-1);
}
void check_negative_sized_VLA_3() {
short x = -1;
int vla[x]; // expected-warning{{Declared variable-length array (VLA) has negative size}}
}
void check_negative_sized_VLA_4() {
unsigned short x = -1;
int vla[x]; // no-warning
}
void check_negative_sized_VLA_5() {
signed char x = -1;
int vla[x]; // expected-warning{{Declared variable-length array (VLA) has negative size}}
}
void check_negative_sized_VLA_6() {
unsigned char x = -1;
int vla[x]; // no-warning
}
void check_negative_sized_VLA_7() {
signed char x = -1;
int vla[x + 2]; // no-warning
}
void check_negative_sized_VLA_8() {
signed char x = 1;
int vla[x - 2]; // expected-warning{{Declared variable-length array (VLA) has negative size}}
}
void check_negative_sized_VLA_9() {
int x = 1;
int vla[x]; // no-warning
}
static void check_negative_sized_VLA_10_sub(int x)
{
int vla[x]; // expected-warning{{Declared variable-length array (VLA) has negative size}}
}
void check_negative_sized_VLA_10(int x) {
if (x < 0)
check_negative_sized_VLA_10_sub(x);
}
static void check_negative_sized_VLA_11_sub(short x)
{
int vla[x]; // no-warning
}
void check_negative_sized_VLA_11(short x) {
if (x > 0)
check_negative_sized_VLA_11_sub(x);
}
void check_VLA_typedef() {
int x = -1;
typedef int VLA[x]; // expected-warning{{Declared variable-length array (VLA) has negative size}}
}
size_t check_VLA_sizeof() {
int x = -1;
size_t s = sizeof(int[x]); // expected-warning{{Declared variable-length array (VLA) has negative size}}
return s;
}
// Multi-dimensional arrays.
void check_zero_sized_VLA_multi1(int x) {
if (x)
return;
int vla[10][x]; // expected-warning{{Declared variable-length array (VLA) has zero size}}
}
void check_zero_sized_VLA_multi2(int x, int y) {
if (x)
return;
int vla[y][x]; // expected-warning{{Declared variable-length array (VLA) has zero size}}
}
// Check the extent.
void check_VLA_extent() {
int x = 3;
int vla1[x];
clang_analyzer_eval(clang_analyzer_getExtent(&vla1) == x * sizeof(int));
// expected-warning@-1{{TRUE}}
int vla2[x][2];
clang_analyzer_eval(clang_analyzer_getExtent(&vla2) == x * 2 * sizeof(int));
// expected-warning@-1{{TRUE}}
int vla2m[2][x];
clang_analyzer_eval(clang_analyzer_getExtent(&vla2m) == 2 * x * sizeof(int));
// expected-warning@-1{{TRUE}}
int vla3m[2][x][4];
clang_analyzer_eval(clang_analyzer_getExtent(&vla3m) == 2 * x * 4 * sizeof(int));
// expected-warning@-1{{TRUE}}
}
// https://bugs.llvm.org/show_bug.cgi?id=46128
// analyzer doesn't handle more than simple symbolic expressions.
// Just don't crash.
extern void foo(void);
int a;
void b() {
int c = a + 1;
for (;;) {
int d[c];
for (; 0 < c;)
foo();
}
} // no-crash