tccgen.c: In parse_btype, handle type qualifiers applied to arrays.

Also add some test cases in tests/tests2/39_typedef.c.
This commit is contained in:
Edmund Grimley Evans 2016-01-11 07:51:58 +00:00
parent 541b33591c
commit f75f89fc8f
2 changed files with 41 additions and 14 deletions

View File

@ -3134,6 +3134,17 @@ ST_FUNC int is_btype_size(int bt)
return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG; return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
} }
/* 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)
{
while (type->t & VT_ARRAY) {
type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
type = &type->ref->type;
}
type->t |= qualifiers;
}
/* return 0 if no type declaration. otherwise, return the basic type /* return 0 if no type declaration. otherwise, return the basic type
and skip it. and skip it.
*/ */
@ -3232,13 +3243,17 @@ static int parse_btype(CType *type, AttributeDef *ad)
case TOK_CONST1: case TOK_CONST1:
case TOK_CONST2: case TOK_CONST2:
case TOK_CONST3: case TOK_CONST3:
t |= VT_CONSTANT; type->t = t;
parse_btype_qualify(type, VT_CONSTANT);
t = type->t;
next(); next();
break; break;
case TOK_VOLATILE1: case TOK_VOLATILE1:
case TOK_VOLATILE2: case TOK_VOLATILE2:
case TOK_VOLATILE3: case TOK_VOLATILE3:
t |= VT_VOLATILE; type->t = t;
parse_btype_qualify(type, VT_VOLATILE);
t = type->t;
next(); next();
break; break;
case TOK_SIGNED1: case TOK_SIGNED1:
@ -3309,18 +3324,14 @@ static int parse_btype(CType *type, AttributeDef *ad)
s = sym_find(tok); s = sym_find(tok);
if (!s || !(s->type.t & VT_TYPEDEF)) if (!s || !(s->type.t & VT_TYPEDEF))
goto the_end; goto the_end;
t |= (s->type.t & ~VT_TYPEDEF);
if ((t & VT_ARRAY) && type->t = ((s->type.t & ~VT_TYPEDEF) |
t & (VT_CONSTANT | VT_VOLATILE) & ~s->type.ref->type.t) { (t & ~(VT_CONSTANT | VT_VOLATILE)));
/* This is a case like "typedef int T[1]; const T x;" type->ref = s->type.ref;
in which which we must make a copy of the typedef if (t & (VT_CONSTANT | VT_VOLATILE))
type so that we can add the type qualifiers to it. */ parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE));
type->ref = sym_push(SYM_FIELD, &s->type.ref->type, t = type->t;
0, s->type.ref->c);
type->ref->type.t |= t & (VT_CONSTANT | VT_VOLATILE);
}
else
type->ref = s->type.ref;
if (s->r) { if (s->r) {
/* get attributes from typedef */ /* get attributes from typedef */
if (0 == ad->a.aligned) if (0 == ad->a.aligned)

View File

@ -28,4 +28,20 @@ int main()
return 0; return 0;
} }
/* "If the specification of an array type includes any type qualifiers,
the element type is so-qualified, not the array type." */
typedef int A[3];
extern A const ca;
extern const A ca;
extern const int ca[3];
typedef A B[1][2];
extern B const cb;
extern const B cb;
extern const int cb[1][2][3];
extern B b;
extern int b[1][2][3];
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ /* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/