mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-28 08:10:25 +08:00
duplicate member
Check duplicate struct/union member names tcc.h: Add cnt field in TokenSym tccgen.c: New function check_fields to find duplicate member names. This avoids quadratic behavior and can be used for large structs.
This commit is contained in:
parent
6f2659c230
commit
170be79a42
1
tcc.h
1
tcc.h
@ -432,6 +432,7 @@ typedef struct TokenSym {
|
||||
struct Sym *sym_struct; /* direct pointer to structure */
|
||||
struct Sym *sym_identifier; /* direct pointer to identifier */
|
||||
int tok; /* token number */
|
||||
int cnt;
|
||||
int len;
|
||||
char str[1];
|
||||
} TokenSym;
|
||||
|
38
tccgen.c
38
tccgen.c
@ -4321,6 +4321,41 @@ static Sym * find_field (CType *type, int v, int *cumofs)
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* c = 0: reset symbol counter
|
||||
* c = 1: increment symbol counter
|
||||
* c = 2: check symbol counter
|
||||
*/
|
||||
|
||||
static void check_fields (CType *type, int c)
|
||||
{
|
||||
Sym *s = type->ref;
|
||||
int v;
|
||||
|
||||
while ((s = s->next) != NULL) {
|
||||
if ((s->v & SYM_FIELD) &&
|
||||
(s->type.t & VT_BTYPE) == VT_STRUCT &&
|
||||
(s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
|
||||
check_fields (&s->type, c);
|
||||
}
|
||||
v = s->v & ~SYM_FIELD;
|
||||
if (v < tok_ident)
|
||||
switch (c) {
|
||||
case 0:
|
||||
table_ident[v - TOK_IDENT]->cnt = 0;
|
||||
break;
|
||||
case 1:
|
||||
table_ident[v - TOK_IDENT]->cnt++;
|
||||
break;
|
||||
case 2:
|
||||
if (table_ident[v - TOK_IDENT]->cnt != 1)
|
||||
tcc_error("duplicate member '%s'",
|
||||
get_tok_str(v, NULL));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void struct_layout(CType *type, AttributeDef *ad)
|
||||
{
|
||||
int size, align, maxalign, offset, c, bit_pos, bit_size;
|
||||
@ -4774,6 +4809,9 @@ do_decl:
|
||||
if (ad.cleanup_func) {
|
||||
tcc_warning("attribute '__cleanup__' ignored on type");
|
||||
}
|
||||
check_fields(type, 0);
|
||||
check_fields(type, 1);
|
||||
check_fields(type, 2);
|
||||
struct_layout(type, &ad);
|
||||
}
|
||||
}
|
||||
|
@ -366,4 +366,21 @@ n[sizeof({3;})]; // crashed in block() due to missing local scope
|
||||
f(){"12"3;} // second const token killed the value of the first
|
||||
|
||||
/******************************************************************/
|
||||
#elif defined test_duplicate_member
|
||||
struct S {
|
||||
int a, a;
|
||||
};
|
||||
#elif defined test_duplicate_member_anon
|
||||
struct S1 {
|
||||
int b;
|
||||
struct {
|
||||
int b;
|
||||
} c;
|
||||
};
|
||||
struct S2 {
|
||||
int d;
|
||||
struct {
|
||||
int d;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
@ -174,3 +174,9 @@ bar : 3 ; 3
|
||||
|
||||
[test_invalid_tokckill]
|
||||
60_errors_and_warnings.c:366: error: ';' expected (got "3")
|
||||
|
||||
[test_duplicate_member]
|
||||
60_errors_and_warnings.c:372: error: duplicate member 'a'
|
||||
|
||||
[test_duplicate_member_anon]
|
||||
60_errors_and_warnings.c:385: error: duplicate member 'd'
|
||||
|
Loading…
Reference in New Issue
Block a user