aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2017-07-14 17:42:48 +0200
committerMichael Matz <matz@suse.de>2017-07-14 17:42:48 +0200
commit04418c7addb757e80b09c94eb3553b131bcf4de8 (patch)
tree6ce677b8e0f40ca982fd7a98e3344bf0da09dae2
parent2acb04f7f2077a4cff103421d79ceee48441918a (diff)
downloadtinycc-04418c7addb757e80b09c94eb3553b131bcf4de8.tar.gz
tinycc-04418c7addb757e80b09c94eb3553b131bcf4de8.tar.bz2
Fix function types
various cases of function type uses were broken by recent attribute refactoring, this fixes and adds testcases for them.
-rw-r--r--tccgen.c30
-rw-r--r--tests/tests2/39_typedef.c18
-rw-r--r--tests/tests2/82_attribs_position.c5
3 files changed, 42 insertions, 11 deletions
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; }