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