sometimes abstract decls in parameter lists left the returned name uninitialized potentially leading to segfaults, like in int f(int ()) { return 0; } Deal with this.
Unified · Split
| @@ -4591,12 +4591,14 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) · 4590 unmodified lines | ||
| 4591 | 4591 | parse_attribute(ad); |
| 4592 | 4592 | post = type_decl(type, ad, v, td); |
| 4593 | 4593 | skip(')'); |
| 4594 | − } | |
| 4594 | + } else | |
| 4595 | + goto abstract; | |
| 4595 | 4596 | } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { |
| 4596 | 4597 | /* type identifier */ |
| 4597 | 4598 | *v = tok; |
| 4598 | 4599 | next(); |
| 4599 | 4600 | } else { |
| 4601 | + abstract: | |
| 4600 | 4602 | if (!(td & TYPE_ABSTRACT)) |
| 4601 | 4603 | expect("identifier"); |
| 4602 | 4604 | *v = 0; |
| @@ -130,4 +130,15 @@ static enum myenum { L = -1 } L; · 129 unmodified lines | ||
| 130 | 130 | void foo(void) { |
| 131 | 131 | static enum myenum { L = -1 } L; |
| 132 | 132 | } |
| 133 | +#elif defined test_abstract_decls | |
| 134 | +int bar(const char *()); // abstract declarator here is okay | |
| 135 | +int bar (const char *(*g)()) // should match this 'g' argument | |
| 136 | +{ | |
| 137 | + g(); | |
| 138 | + return 42; | |
| 139 | +} | |
| 140 | +int foo(int ()) // abstract decl is wrong in definitions | |
| 141 | +{ | |
| 142 | + return 0; | |
| 143 | +} | |
| 133 | 144 | #endif |
| @@ -59,3 +59,6 @@ · 58 unmodified lines | ||
| 59 | 59 | |
| 60 | 60 | [test_duplicate_def_2] |
| 61 | 61 | 60_errors_and_warnings.c:131: error: redeclaration of 'L' |
| 62 | + | |
| 63 | +[test_abstract_decls] | |
| 64 | +60_errors_and_warnings.c:141: error: identifier expected | |