1
0
Fork 0

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:
herman ten brugge 2020-12-03 07:53:44 +01:00
parent 6f2659c230
commit 170be79a42
4 changed files with 62 additions and 0 deletions

1
tcc.h
View File

@ -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;

View File

@ -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);
}
}

View File

@ -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

View File

@ -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'