diff --git a/tccgen.c b/tccgen.c index 19909f9..5a503c3 100644 --- a/tccgen.c +++ b/tccgen.c @@ -3865,6 +3865,18 @@ do_decl: } } +static void sym_to_attr(AttributeDef *ad, Sym *s) +{ + if (s->a.aligned && 0 == ad->a.aligned) + ad->a.aligned = s->a.aligned; + if (s->f.func_call && 0 == ad->f.func_call) + ad->f.func_call = s->f.func_call; + if (s->f.func_type && 0 == ad->f.func_type) + ad->f.func_type = s->f.func_type; + if (s->a.packed) + ad->a.packed = 1; +} + /* Add type qualifiers to a type. If the type is an array then the qualifiers are added to the element type, copied because it could be a typedef. */ static void parse_btype_qualify(CType *type, int qualifiers) @@ -4060,6 +4072,8 @@ static int parse_btype(CType *type, AttributeDef *ad) parse_expr_type(&type1); /* remove all storage modifiers except typedef */ type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); + if (type1.ref) + sym_to_attr(ad, type1.ref); goto basic_type2; default: if (typespec_found) @@ -4075,12 +4089,7 @@ static int parse_btype(CType *type, AttributeDef *ad) parse_btype_qualify(type, t); t = type->t; /* get attributes from typedef */ - if (s->a.aligned && 0 == ad->a.aligned) - ad->a.aligned = s->a.aligned; - if (s->f.func_call && 0 == ad->f.func_call) - ad->f.func_call = s->f.func_call; - if (s->a.packed) - ad->a.packed = 1; + sym_to_attr(ad, s); next(); typespec_found = 1; st = bt = -2; @@ -6978,7 +6987,7 @@ static void gen_inline_functions(TCCState *s) ln = file->line_num; /* iterate while inline function are referenced */ - for(;;) { + do { inline_generated = 0; for (i = 0; i < s->nb_inline_fns; ++i) { fn = s->inline_fns[i]; @@ -7000,9 +7009,7 @@ static void gen_inline_functions(TCCState *s) inline_generated = 1; } } - if (!inline_generated) - break; - } + } while (inline_generated); file->line_num = ln; } @@ -7229,12 +7236,13 @@ found: sym = sym_push(v, &type, 0, 0); } sym->a = ad.a; + sym->f = ad.f; } else { r = 0; if ((type.t & VT_BTYPE) == VT_FUNC) { /* external function definition */ /* specific case for func_call attribute */ - type.ref->a = ad.a; + type.ref->f = ad.f; } else if (!(type.t & VT_ARRAY)) { /* not lvalue if array */ r |= lvalue_type(type.t); diff --git a/tests/tests2/39_typedef.c b/tests/tests2/39_typedef.c index 3878b9c..da73f71 100644 --- a/tests/tests2/39_typedef.c +++ b/tests/tests2/39_typedef.c @@ -44,4 +44,22 @@ extern const int cb[1][2][3]; extern B b; extern int b[1][2][3]; +/* Funny but valid function declaration. */ +typedef int functype (int); +extern functype func; +int func(int i) +{ + return i + 1; +} + +/* Even funnier function decl and definition using typeof. */ +int set_anon_super(void); +int set_anon_super(void) +{ + return 42; +} +typedef int sas_type (void); +extern typeof(set_anon_super) set_anon_super; +extern sas_type set_anon_super; + /* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tests/tests2/82_attribs_position.c b/tests/tests2/82_attribs_position.c index 45039b3..7c9f987 100644 --- a/tests/tests2/82_attribs_position.c +++ b/tests/tests2/82_attribs_position.c @@ -11,4 +11,9 @@ typedef union __attribute__((packed)) Unaligned16b { uint8_t b[2]; } Unaligned16b; +extern void foo (void) __attribute__((stdcall)); +void __attribute__((stdcall)) foo (void) +{ +} + int main () { return 0; }