diff --git a/tccgen.c b/tccgen.c index 0866281..ccc5c00 100644 --- a/tccgen.c +++ b/tccgen.c @@ -3134,6 +3134,19 @@ ST_FUNC int is_btype_size(int bt) return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG; } +static int parse_btype_modify(int t, CType *type, int mod) +{ + if (!(t & VT_ARRAY)) + return t | mod; + if (type->ref->type.t & mod) + return t; + /* We have a case like "typedef int T[1]; T const x;". + We copy the referenced type so that we can safely modify it. */ + type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); + type->ref->type.t |= mod; + return t; +} + /* return 0 if no type declaration. otherwise, return the basic type and skip it. */ @@ -3232,13 +3245,13 @@ static int parse_btype(CType *type, AttributeDef *ad) case TOK_CONST1: case TOK_CONST2: case TOK_CONST3: - t |= VT_CONSTANT; + t = parse_btype_modify(t, type, VT_CONSTANT); next(); break; case TOK_VOLATILE1: case TOK_VOLATILE2: case TOK_VOLATILE3: - t |= VT_VOLATILE; + t = parse_btype_modify(t, type, VT_VOLATILE); next(); break; case TOK_SIGNED1: @@ -3309,18 +3322,22 @@ static int parse_btype(CType *type, AttributeDef *ad) s = sym_find(tok); if (!s || !(s->type.t & VT_TYPEDEF)) goto the_end; - t |= (s->type.t & ~VT_TYPEDEF); - if ((t & VT_ARRAY) && - t & (VT_CONSTANT | VT_VOLATILE) & ~s->type.ref->type.t) { - /* This is a case like "typedef int T[1]; const T x;" - in which which we must make a copy of the typedef - type so that we can add the type qualifiers to it. */ - type->ref = sym_push(SYM_FIELD, &s->type.ref->type, - 0, s->type.ref->c); - type->ref->type.t |= t & (VT_CONSTANT | VT_VOLATILE); - } - else + if (!(s->type.t & VT_ARRAY)) { + t |= (s->type.t & ~VT_TYPEDEF); type->ref = s->type.ref; + } else { + if (t & (VT_CONSTANT | VT_VOLATILE) & ~s->type.ref->type.t) { + /* This is a case like "typedef int T[1]; const T x;" + in which which we must make a copy of the typedef + type so that we can add the type qualifiers to it. */ + type->ref = sym_push(SYM_FIELD, &s->type.ref->type, + 0, s->type.ref->c); + type->ref->type.t |= t & (VT_CONSTANT | VT_VOLATILE); + } else + type->ref = s->type.ref; + t &= ~(VT_CONSTANT | VT_VOLATILE); + t |= (s->type.t & ~VT_TYPEDEF); + } if (s->r) { /* get attributes from typedef */ if (0 == ad->a.aligned)