Fix function types

various cases of function type uses were broken by recent
attribute refactoring, this fixes and adds testcases for them.
master
Michael Matz 2017-07-14 17:42:48 +02:00
parent 2acb04f7f2
commit 04418c7add
3 changed files with 42 additions and 11 deletions

View File

@ -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 /* 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. */ are added to the element type, copied because it could be a typedef. */
static void parse_btype_qualify(CType *type, int qualifiers) 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); parse_expr_type(&type1);
/* remove all storage modifiers except typedef */ /* remove all storage modifiers except typedef */
type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
if (type1.ref)
sym_to_attr(ad, type1.ref);
goto basic_type2; goto basic_type2;
default: default:
if (typespec_found) if (typespec_found)
@ -4075,12 +4089,7 @@ static int parse_btype(CType *type, AttributeDef *ad)
parse_btype_qualify(type, t); parse_btype_qualify(type, t);
t = type->t; t = type->t;
/* get attributes from typedef */ /* get attributes from typedef */
if (s->a.aligned && 0 == ad->a.aligned) sym_to_attr(ad, s);
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;
next(); next();
typespec_found = 1; typespec_found = 1;
st = bt = -2; st = bt = -2;
@ -6978,7 +6987,7 @@ static void gen_inline_functions(TCCState *s)
ln = file->line_num; ln = file->line_num;
/* iterate while inline function are referenced */ /* iterate while inline function are referenced */
for(;;) { do {
inline_generated = 0; inline_generated = 0;
for (i = 0; i < s->nb_inline_fns; ++i) { for (i = 0; i < s->nb_inline_fns; ++i) {
fn = s->inline_fns[i]; fn = s->inline_fns[i];
@ -7000,9 +7009,7 @@ static void gen_inline_functions(TCCState *s)
inline_generated = 1; inline_generated = 1;
} }
} }
if (!inline_generated) } while (inline_generated);
break;
}
file->line_num = ln; file->line_num = ln;
} }
@ -7229,12 +7236,13 @@ found:
sym = sym_push(v, &type, 0, 0); sym = sym_push(v, &type, 0, 0);
} }
sym->a = ad.a; sym->a = ad.a;
sym->f = ad.f;
} else { } else {
r = 0; r = 0;
if ((type.t & VT_BTYPE) == VT_FUNC) { if ((type.t & VT_BTYPE) == VT_FUNC) {
/* external function definition */ /* external function definition */
/* specific case for func_call attribute */ /* specific case for func_call attribute */
type.ref->a = ad.a; type.ref->f = ad.f;
} else if (!(type.t & VT_ARRAY)) { } else if (!(type.t & VT_ARRAY)) {
/* not lvalue if array */ /* not lvalue if array */
r |= lvalue_type(type.t); r |= lvalue_type(type.t);

View File

@ -44,4 +44,22 @@ extern const int cb[1][2][3];
extern B b; extern B b;
extern int b[1][2][3]; 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 :*/ /* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/

View File

@ -11,4 +11,9 @@ typedef union __attribute__((packed)) Unaligned16b {
uint8_t b[2]; uint8_t b[2];
} Unaligned16b; } Unaligned16b;
extern void foo (void) __attribute__((stdcall));
void __attribute__((stdcall)) foo (void)
{
}
int main () { return 0; } int main () { return 0; }