Unified · Split
| @@ -7996,6 +7996,11 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 7995 unmodified lines | ||
| 7996 | 7996 | toplevel array or the last member of the toplevel struct */ |
| 7997 | 7997 | |
| 7998 | 7998 | if (size < 0) { |
| 7999 | + // error out except for top-level incomplete arrays | |
| 8000 | + // (arrays of incomplete types are handled in array parsing) | |
| 8001 | + if (!(type->t & VT_ARRAY)) | |
| 8002 | + tcc_error("initialization of incomplete type"); | |
| 8003 | + | |
| 7999 | 8004 | /* If the base type itself was an array type of unspecified size |
| 8000 | 8005 | (like in 'typedef int arr[]; arr x = {1};') then we will |
| 8001 | 8006 | overwrite the unknown size by the real one for this decl. |
| @@ -463,4 +463,17 @@ int main() { · 462 unmodified lines | ||
| 463 | 463 | #error \123\\ |
| 464 | 464 | 456 |
| 465 | 465 | |
| 466 | +#elif defined test_error_incomplete_type | |
| 467 | +struct A; | |
| 468 | +void f(struct A *); | |
| 469 | + | |
| 470 | +int main() | |
| 471 | +{ | |
| 472 | + f(&(struct A){}); | |
| 473 | +} | |
| 474 | + | |
| 475 | +struct A { | |
| 476 | + int x; | |
| 477 | +}; | |
| 478 | + | |
| 466 | 479 | #endif |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | [returns 1] |
| 24 | 24 | |
| 25 | 25 | [test_61_undefined_enum] |
| 26 | −60_errors_and_warnings.c:46: error: unknown type size | |
| 26 | +60_errors_and_warnings.c:46: error: initialization of incomplete type | |
| 27 | 27 | |
| 28 | 28 | [test_74_non_const_init] |
| 29 | 29 | 60_errors_and_warnings.c:49: error: initializer element is not constant |
| @@ -228,3 +228,6 @@ arg[1] = "Y" · 198 unmodified lines | ||
| 228 | 228 | |
| 229 | 229 | [test_error_string] |
| 230 | 230 | 60_errors_and_warnings.c:464: error: #error \123\456 |
| 231 | + | |
| 232 | +[test_error_incomplete_type] | |
| 233 | +60_errors_and_warnings.c:472: error: initialization of incomplete type | |