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 | { 2, "longlonglonglonglong" }, | 346 | { 2, "longlonglonglonglong" }, |
| 347 | { 3, "tst3" } }; | 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 | #endif | 358 | #endif |
| @@ -161,4 +161,7 @@ bar : 3 ; 3 · 160 unmodified lines | |||
| 161 | \n | 161 | \n |
| 162 | 162 | ||
| 163 | [test_var_array] | 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 | void sys_one(void) { printf("one\n"); } | 221 | void sys_one(void) { printf("one\n"); } |
| 222 | void sys_two(void) { printf("two\n"); } | 222 | void sys_two(void) { printf("two\n"); } |
| 223 | void sys_three(void) { printf("three\n"); } | 223 | void sys_three(void) { printf("three\n"); } |
| 224 | void sys_four(void) { printf("four\n"); } | ||
| 224 | typedef void (*fptr)(void); | 225 | typedef void (*fptr)(void); |
| 225 | const fptr table[3] = { | 226 | |
| 226 | [0 ... 2] = &sys_ni, | 227 | #define array_size(a) (sizeof a / sizeof a[0]) |
| 227 | [0] = sys_one, | ||
| 228 | [1] = sys_two, | ||
| 229 | [2] = sys_three, | ||
| 230 | }; | ||
| 231 | 228 | ||
| 232 | void test_multi_relocs(void) | 229 | void test_multi_relocs(void) |
| 233 | { | 230 | { |
| 234 | int i; | 231 | int i; |
| 235 | for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) | 232 | |
| 236 | table[i](); | 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 | void test_init_ranges(void) { | 286 | void test_init_ranges(void) { |
| @@ -41,8 +41,16 @@ lssu2: 5 0 0 0 3 0 0 0 · 40 unmodified lines | |||
| 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 | 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 | ls4: 1 2 3 4 | 42 | ls4: 1 2 3 4 |
| 43 | one | 43 | one |
| 44 | two | 44 | (0) |
| 45 | three | 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 | sea_fill0: okay | 54 | sea_fill0: okay |
| 47 | sea_fill1: okay | 55 | sea_fill1: okay |
| 48 | sea_fill2: okay | 56 | sea_fill2: okay |