enums: Accept GNU extension

See testcase.  Happens e.g. in the linux kernel.
master
Michael Matz 2017-07-10 22:20:34 +02:00
parent a9e502cc3b
commit 2240422da9
3 changed files with 46 additions and 2 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -1,3 +1,4 @@
0 1 2 3 54 73 74 75
12
54
enum to int: 1