The type within the cast (int (__attribute__((foo)) *)(void)) was misparsed because of the presence of the attribute (parse_btype prematurely concluded that (__attribute__() *) is a type. Also see testcase. This construct is used in sqlite it seems.
Unified · Split
| @@ -4180,7 +4180,7 @@ static int parse_btype(CType *type, AttributeDef *ad) · 4179 unmodified lines | |||
| 4180 | u = ad->attr_mode -1; | 4180 | u = ad->attr_mode -1; |
| 4181 | t = (t & ~(VT_BTYPE|VT_LONG)) | u; | 4181 | t = (t & ~(VT_BTYPE|VT_LONG)) | u; |
| 4182 | } | 4182 | } |
| 4183 | break; | 4183 | continue; |
| 4184 | /* GNUC typeof */ | 4184 | /* GNUC typeof */ |
| 4185 | case TOK_TYPEOF1: | 4185 | case TOK_TYPEOF1: |
| 4186 | case TOK_TYPEOF2: | 4186 | case TOK_TYPEOF2: |
| @@ -16,4 +16,25 @@ void __attribute__((stdcall)) foo (void) · 15 unmodified lines | |||
| 16 | { | 16 | { |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | int main () { return 0; } | 19 | /* The actual attribute isn't important, must just be |
| 20 | parsable. */ | ||
| 21 | #define ATTR __attribute__((__noinline__)) | ||
| 22 | int ATTR actual_function() { | ||
| 23 | return 42; | ||
| 24 | } | ||
| 25 | |||
| 26 | extern int printf (const char *, ...); | ||
| 27 | int main() | ||
| 28 | { | ||
| 29 | void *function_pointer = &actual_function; | ||
| 30 | |||
| 31 | int a = ((ATTR int(*) (void)) function_pointer)(); | ||
| 32 | printf("%i\n", a); | ||
| 33 | |||
| 34 | /* In the following we once misparsed 'ATTR *' is a btype | ||
| 35 | and hence the whole type was garbled. */ | ||
| 36 | int b = ( (int(ATTR *)(void)) function_pointer)(); | ||
| 37 | printf("%i\n", b); | ||
| 38 | |||
| 39 | return 0; | ||
| 40 | } | ||
| @@ -0,0 +1,2 @@ | |||
| 1 | 42 | ||
| 2 | 42 | ||