From 2240422da9b55b71cfb32220bb0246ec92bfc432 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Mon, 10 Jul 2017 22:20:34 +0200 Subject: [PATCH] enums: Accept GNU extension See testcase. Happens e.g. in the linux kernel. --- tccgen.c | 4 ++-- tests/tests2/17_enum.c | 43 +++++++++++++++++++++++++++++++++++++ tests/tests2/17_enum.expect | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/tccgen.c b/tccgen.c index d8676a4..c3185ca 100644 --- a/tccgen.c +++ b/tccgen.c @@ -3683,7 +3683,7 @@ static void struct_decl(CType *type, int u) v = anon_sym++; } /* Record the original enum/struct/union token. */ - type1.t = u; + type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u; type1.ref = NULL; /* we put an undefined size for struct/union */ s = sym_push(v | SYM_STRUCT, &type1, 0, -1); @@ -3736,7 +3736,7 @@ do_decl: skip('}'); /* set integral type of the enum */ t.t = VT_INT; - if (nl == 0) { + if (nl >= 0) { if (pl != (unsigned)pl) t.t = VT_LLONG; t.t |= VT_UNSIGNED; diff --git a/tests/tests2/17_enum.c b/tests/tests2/17_enum.c index 0853c42..e2bc736 100644 --- a/tests/tests2/17_enum.c +++ b/tests/tests2/17_enum.c @@ -12,9 +12,49 @@ enum fred h }; +/* All following uses of enum efoo should compile + without warning. While forward enums aren't ISO C, + it's accepted by GCC also in strict mode, and only warned + about with -pedantic. This happens in the real world. */ +/* Strict ISO C doesn't allow this kind of forward declaration of + enums, but GCC accepts it (and gives only pedantic warning), and + it occurs in the wild. */ +enum efoo; +struct Sforward_use { + int (*fmember) (enum efoo x); +}; + +extern enum efoo it_real_fn(void); +enum efoo { + ONE, + TWO, +}; +struct S2 { + enum efoo (*f2) (void); +}; +void should_compile(struct S2 *s) +{ + s->f2 = it_real_fn; +} + +enum efoo it_real_fn(void) +{ + return TWO; +} + +static unsigned int deref_uintptr(unsigned int *p) +{ + return *p; +} + +enum Epositive { + epos_one, epos_two +}; + int main() { enum fred frod; + enum Epositive epos = epos_two; printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h); /* printf("%d\n", frod); */ @@ -23,6 +63,9 @@ int main() frod = e; printf("%d\n", frod); + /* Following should compile without warning. */ + printf ("enum to int: %u\n", deref_uintptr(&epos)); + return 0; } diff --git a/tests/tests2/17_enum.expect b/tests/tests2/17_enum.expect index 0c4e153..d453a61 100644 --- a/tests/tests2/17_enum.expect +++ b/tests/tests2/17_enum.expect @@ -1,3 +1,4 @@ 0 1 2 3 54 73 74 75 12 54 +enum to int: 1