Fixes potential writes past the allocated space with mostly illegal flex array initializers. (60_errors_and_warnings.c :test_var_array) In exchange suspicious precautions such as section_reserve or checks with sec->data_allocated were removed. (There is an hard check 'init_assert()' for now but it's meant to be just temporary) Also, instead of filling holes, always memset(0) structures & arrays on stack. Sometimes more efficient, sometimes isn't. At least we can omit putting null initializers. About array range inititializers: Reparsing tokens has a small problem with sideeffects, for example int c = 0, dd[] = { [0 ... 1] = ++c, [2 ... 3] = ++c }; Also, instead of 'squeeze_multi_relocs()', delete pre-existing relocations in advance. This works even if secondary initializers don't even have relocations, as with [0 ... 7] = &stuff, [4] = NULL Also, in tcc.h: new macro "tcc_internal_error()"
Showing the changes to tests/tests2 (4 of 9 files). Show all
Unified · Split
| @@ -346,4 +346,13 @@ static struct var_len { int i; const char str[]; } var_array[] = · 345 unmodified lines | ||
| 346 | 346 | { 2, "longlonglonglonglong" }, |
| 347 | 347 | { 3, "tst3" } }; |
| 348 | 348 | |
| 349 | +#elif defined test_var_array2 | |
| 350 | + | |
| 351 | +struct c1 { int a; int b[]; }; | |
| 352 | +struct c1 c1 = { 1, { 2, 3, 4 } }; | |
| 353 | + | |
| 354 | +struct c2 { int c; struct c1 c1; }; | |
| 355 | +struct c2 c2 = { 1, { 2, { 3, 4, 5 }}}; | |
| 356 | + | |
| 357 | +/******************************************************************/ | |
| 349 | 358 | #endif |
| @@ -161,4 +161,7 @@ bar : 3 ; 3 · 160 unmodified lines | ||
| 161 | 161 | \n |
| 162 | 162 | |
| 163 | 163 | [test_var_array] |
| 164 | −60_errors_and_warnings.c:345: warning: initializer-string for array is too long | |
| 164 | +60_errors_and_warnings.c:345: error: flexible array has zero size in this context | |
| 165 | + | |
| 166 | +[test_var_array2] | |
| 167 | +60_errors_and_warnings.c:355: error: flexible array has zero size in this context | |
| @@ -221,19 +221,66 @@ void sys_ni(void) { printf("ni\n"); } · 220 unmodified lines | ||
| 221 | 221 | void sys_one(void) { printf("one\n"); } |
| 222 | 222 | void sys_two(void) { printf("two\n"); } |
| 223 | 223 | void sys_three(void) { printf("three\n"); } |
| 224 | +void sys_four(void) { printf("four\n"); } | |
| 224 | 225 | typedef void (*fptr)(void); |
| 225 | −const fptr table[3] = { | |
| 226 | − [0 ... 2] = &sys_ni, | |
| 227 | − [0] = sys_one, | |
| 228 | − [1] = sys_two, | |
| 229 | − [2] = sys_three, | |
| 230 | −}; | |
| 226 | + | |
| 227 | +#define array_size(a) (sizeof a / sizeof a[0]) | |
| 231 | 228 | |
| 232 | 229 | void test_multi_relocs(void) |
| 233 | 230 | { |
| 234 | 231 | int i; |
| 235 | − for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) | |
| 236 | − table[i](); | |
| 232 | + | |
| 233 | + static const fptr tabl1[4] = { | |
| 234 | + [0 ... 3] = &sys_ni, | |
| 235 | + [0] = sys_one, | |
| 236 | + [1] = sys_two, | |
| 237 | + [2] = sys_three, | |
| 238 | + sys_four, | |
| 239 | + [1 ... 2] = &sys_ni, | |
| 240 | + [1] = 0, | |
| 241 | + }; | |
| 242 | + for (i = 0; i < array_size(tabl1); i++) | |
| 243 | + if (tabl1[i]) | |
| 244 | + tabl1[i](); | |
| 245 | + else | |
| 246 | + printf("(0)\n"); | |
| 247 | + | |
| 248 | + const fptr tabl2[4] = { | |
| 249 | + [0 ... 3] = &sys_ni, | |
| 250 | + [0] = sys_one, | |
| 251 | + [1] = sys_two, | |
| 252 | + [2] = sys_three, | |
| 253 | + sys_four, | |
| 254 | + [1 ... 2] = &sys_ni, | |
| 255 | + [1] = 0, | |
| 256 | + }; | |
| 257 | + for (i = 0; i < array_size(tabl2); i++) | |
| 258 | + if (tabl2[i]) | |
| 259 | + tabl2[i](); | |
| 260 | + else | |
| 261 | + printf("(0)\n"); | |
| 262 | + | |
| 263 | + int c = 0; | |
| 264 | + int dd[] = { | |
| 265 | + [0 ... 1] = ++c, | |
| 266 | + [2 ... 3] = ++c | |
| 267 | + }; | |
| 268 | + for (i = 0; i < array_size(dd); i++) | |
| 269 | + printf(" %d", dd[i]); | |
| 270 | + printf("\n"); | |
| 271 | + | |
| 272 | + /* multi-dimensional flex array with range initializers */ | |
| 273 | + static char m1[][2][3] = {[0 ... 2]={{3,4,5},{6,7,8}},{{9},10},"abc"}; | |
| 274 | + char m2[][2][3] = {[0 ... 2]={{3,4,5},{6,7,8}},{{9},10},"abc"}; | |
| 275 | + int g, j, k; | |
| 276 | + for (g = 2; g-- > 0;) { | |
| 277 | + printf("mdfa %s: %d -", "locl\0glob" + g * 5, sizeof m1); | |
| 278 | + for (i = 0; i < array_size(m1); i++) | |
| 279 | + for (j = 0; j < array_size(m1[0]); j++) | |
| 280 | + for (k = 0; k < array_size(m1[0][0]); k++) | |
| 281 | + printf(" %d", (g ? m1:m2)[i][j][k]); | |
| 282 | + printf("\n"); | |
| 283 | + } | |
| 237 | 284 | } |
| 238 | 285 | |
| 239 | 286 | void test_init_ranges(void) { |
| @@ -41,8 +41,16 @@ lssu2: 5 0 0 0 3 0 0 0 · 40 unmodified lines | ||
| 41 | 41 | flow: 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 |
| 42 | 42 | ls4: 1 2 3 4 |
| 43 | 43 | one |
| 44 | −two | |
| 45 | −three | |
| 44 | +(0) | |
| 45 | +ni | |
| 46 | +four | |
| 47 | +one | |
| 48 | +(0) | |
| 49 | +ni | |
| 50 | +four | |
| 51 | + 1 1 2 2 | |
| 52 | +mdfa glob: 30 - 3 4 5 6 7 8 3 4 5 6 7 8 3 4 5 6 7 8 9 0 0 10 0 0 97 98 99 0 0 0 | |
| 53 | +mdfa locl: 30 - 3 4 5 6 7 8 3 4 5 6 7 8 3 4 5 6 7 8 9 0 0 10 0 0 97 98 99 0 0 0 | |
| 46 | 54 | sea_fill0: okay |
| 47 | 55 | sea_fill1: okay |
| 48 | 56 | sea_fill2: okay |