Fix unnamed bitfield struct members

they look similar to labels 'foobar : 32' (when foobar is a typedef),
but cannot be handled as such in parse_btype, the context is important
(labels can only happen when called from within 'block', aka decl0 in
VT_LOCAL context).  This got broken back in 2019 (1b57560).
This commit is contained in:
Michael Matz 2022-07-04 15:24:46 +02:00
parent 47dc6e6d7b
commit 154c3e7450
2 changed files with 19 additions and 17 deletions

View file

@ -44,7 +44,6 @@ static int nb_sym_pools;
static Sym *all_cleanups, *pending_gotos; static Sym *all_cleanups, *pending_gotos;
static int local_scope; static int local_scope;
static int in_sizeof; static int in_sizeof;
static int in_generic;
ST_DATA char debug_modes; ST_DATA char debug_modes;
ST_DATA SValue *vtop; ST_DATA SValue *vtop;
@ -138,7 +137,7 @@ static void gen_cast(CType *type);
static void gen_cast_s(int t); static void gen_cast_s(int t);
static inline CType *pointed_type(CType *type); static inline CType *pointed_type(CType *type);
static int is_compatible_types(CType *type1, CType *type2); static int is_compatible_types(CType *type1, CType *type2);
static int parse_btype(CType *type, AttributeDef *ad); static int parse_btype(CType *type, AttributeDef *ad, int ignore_label);
static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td); static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
static void parse_expr_type(CType *type); static void parse_expr_type(CType *type);
static void init_putv(init_params *p, CType *type, unsigned long c); static void init_putv(init_params *p, CType *type, unsigned long c);
@ -4282,7 +4281,7 @@ do_decl:
c = 0; c = 0;
flexible = 0; flexible = 0;
while (tok != '}') { while (tok != '}') {
if (!parse_btype(&btype, &ad1)) { if (!parse_btype(&btype, &ad1, 0)) {
skip(';'); skip(';');
continue; continue;
} }
@ -4415,7 +4414,7 @@ static void parse_btype_qualify(CType *type, int 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.
*/ */
static int parse_btype(CType *type, AttributeDef *ad) static int parse_btype(CType *type, AttributeDef *ad, int ignore_label)
{ {
int t, u, bt, st, type_found, typespec_found, g, n; int t, u, bt, st, type_found, typespec_found, g, n;
Sym *s; Sym *s;
@ -4469,7 +4468,7 @@ static int parse_btype(CType *type, AttributeDef *ad)
next(); next();
skip('('); skip('(');
memset(&ad1, 0, sizeof(AttributeDef)); memset(&ad1, 0, sizeof(AttributeDef));
if (parse_btype(&type1, &ad1)) { if (parse_btype(&type1, &ad1, 0)) {
type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
if (ad1.a.aligned) if (ad1.a.aligned)
n = 1 << (ad1.a.aligned - 1); n = 1 << (ad1.a.aligned - 1);
@ -4639,7 +4638,7 @@ static int parse_btype(CType *type, AttributeDef *ad)
goto the_end; goto the_end;
n = tok, next(); n = tok, next();
if (tok == ':' && !in_generic) { if (tok == ':' && ignore_label) {
/* ignore if it's a label */ /* ignore if it's a label */
unget_tok(n); unget_tok(n);
goto the_end; goto the_end;
@ -4730,7 +4729,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
return 0; return 0;
if (tok == ')') if (tok == ')')
l = 0; l = 0;
else if (parse_btype(&pt, &ad1)) else if (parse_btype(&pt, &ad1, 0))
l = FUNC_NEW; l = FUNC_NEW;
else if (td & (TYPE_DIRECT|TYPE_ABSTRACT)) { else if (td & (TYPE_DIRECT|TYPE_ABSTRACT)) {
merge_attr (ad, &ad1); merge_attr (ad, &ad1);
@ -4774,7 +4773,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
next(); next();
break; break;
} }
if (l == FUNC_NEW && !parse_btype(&pt, &ad1)) if (l == FUNC_NEW && !parse_btype(&pt, &ad1, 0))
tcc_error("invalid type"); tcc_error("invalid type");
} }
} else } else
@ -5081,7 +5080,7 @@ static void parse_expr_type(CType *type)
AttributeDef ad; AttributeDef ad;
skip('('); skip('(');
if (parse_btype(type, &ad)) { if (parse_btype(type, &ad, 0)) {
type_decl(type, &ad, &n, TYPE_ABSTRACT); type_decl(type, &ad, &n, TYPE_ABSTRACT);
} else { } else {
expr_type(type, gexpr); expr_type(type, gexpr);
@ -5094,7 +5093,7 @@ static void parse_type(CType *type)
AttributeDef ad; AttributeDef ad;
int n; int n;
if (!parse_btype(type, &ad)) { if (!parse_btype(type, &ad, 0)) {
expect("type"); expect("type");
} }
type_decl(type, &ad, &n, TYPE_ABSTRACT); type_decl(type, &ad, &n, TYPE_ABSTRACT);
@ -5362,7 +5361,7 @@ ST_FUNC void unary(void)
case '(': case '(':
next(); next();
/* cast ? */ /* cast ? */
if (parse_btype(&type, &ad)) { if (parse_btype(&type, &ad, 0)) {
type_decl(&type, &ad, &n, TYPE_ABSTRACT); type_decl(&type, &ad, &n, TYPE_ABSTRACT);
skip(')'); skip(')');
/* check ISOC99 compound literal */ /* check ISOC99 compound literal */
@ -5719,10 +5718,7 @@ ST_FUNC void unary(void)
int itmp; int itmp;
CType cur_type; CType cur_type;
in_generic++; parse_btype(&cur_type, &ad_tmp, 0);
parse_btype(&cur_type, &ad_tmp);
in_generic--;
type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
if (compare_types(&controlling_type, &cur_type, 0)) { if (compare_types(&controlling_type, &cur_type, 0)) {
if (has_match) { if (has_match) {
@ -8206,7 +8202,7 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym)
} }
oldint = 0; oldint = 0;
if (!parse_btype(&btype, &adbase)) { if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) {
if (is_for_loop_init) if (is_for_loop_init)
return 0; return 0;
/* skip redundant ';' if not in old parameter decl scope */ /* skip redundant ';' if not in old parameter decl scope */

View file

@ -557,11 +557,17 @@ void goto_test()
{ {
int i; int i;
static void *label_table[3] = { &&label1, &&label2, &&label3 }; static void *label_table[3] = { &&label1, &&label2, &&label3 };
struct {
int bla;
/* This needs to parse as typedef, not as label. */
typedef_and_label : 32;
} y = {1};
printf("\ngoto:\n"); printf("\ngoto:\n");
i = 0; i = 0;
/* This needs to parse as label, not as start of decl. */ /* This is a normal decl. */
typedef_and_label x; typedef_and_label x;
/* This needs to parse as label, not as start of decl. */
typedef_and_label: typedef_and_label:
s_loop: s_loop:
if (i >= 10) if (i >= 10)