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
4 changed files with 62 additions and 0 deletions
1
tcc.h
1
tcc.h
|
|
@ -432,6 +432,7 @@ typedef struct TokenSym {
|
||||||
struct Sym *sym_struct; /* direct pointer to structure */
|
struct Sym *sym_struct; /* direct pointer to structure */
|
||||||
struct Sym *sym_identifier; /* direct pointer to identifier */
|
struct Sym *sym_identifier; /* direct pointer to identifier */
|
||||||
int tok; /* token number */
|
int tok; /* token number */
|
||||||
|
int cnt;
|
||||||
int len;
|
int len;
|
||||||
char str[1];
|
char str[1];
|
||||||
} TokenSym;
|
} TokenSym;
|
||||||
|
|
|
||||||
38
tccgen.c
38
tccgen.c
|
|
@ -4321,6 +4321,41 @@ static Sym * find_field (CType *type, int v, int *cumofs)
|
||||||
return s;
|
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)
|
static void struct_layout(CType *type, AttributeDef *ad)
|
||||||
{
|
{
|
||||||
int size, align, maxalign, offset, c, bit_pos, bit_size;
|
int size, align, maxalign, offset, c, bit_pos, bit_size;
|
||||||
|
|
@ -4774,6 +4809,9 @@ do_decl:
|
||||||
if (ad.cleanup_func) {
|
if (ad.cleanup_func) {
|
||||||
tcc_warning("attribute '__cleanup__' ignored on type");
|
tcc_warning("attribute '__cleanup__' ignored on type");
|
||||||
}
|
}
|
||||||
|
check_fields(type, 0);
|
||||||
|
check_fields(type, 1);
|
||||||
|
check_fields(type, 2);
|
||||||
struct_layout(type, &ad);
|
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
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -174,3 +174,9 @@ bar : 3 ; 3
|
||||||
|
|
||||||
[test_invalid_tokckill]
|
[test_invalid_tokckill]
|
||||||
60_errors_and_warnings.c:366: error: ';' expected (got "3")
|
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…
Add table
Reference in a new issue