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
|