History

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.

herman ten brugge committed 5 years ago

Commit 170be791 parent 6f2659c4 files · +62 −0Browse files

Unified · Split

4 files
  1. tcc.h +1 −0
  2. tccgen.c +38 −0
  3. tests/tests2/60_errors_and_warnings.c +17 −0
  4. tests/tests2/60_errors_and_warnings.expect +6 −0
tcc.h+1−0
@@ -432,6 +432,7 @@ typedef struct TokenSym { · 431 unmodified lines
432 struct Sym *sym_struct; /* direct pointer to structure */432 struct Sym *sym_struct; /* direct pointer to structure */
433 struct Sym *sym_identifier; /* direct pointer to identifier */433 struct Sym *sym_identifier; /* direct pointer to identifier */
434 int tok; /* token number */434 int tok; /* token number */
435 int cnt;
435 int len;436 int len;
436 char str[1];437 char str[1];
437} TokenSym;438} TokenSym;
tccgen.c+38−0
@@ -4321,6 +4321,41 @@ static Sym * find_field (CType *type, int v, int *cumofs) · 4320 unmodified lines
4321 return s;4321 return s;
4322}4322}
4323 4323
4324/*
4325 * c = 0: reset symbol counter
4326 * c = 1: increment symbol counter
4327 * c = 2: check symbol counter
4328 */
4329
4330static void check_fields (CType *type, int c)
4331{
4332 Sym *s = type->ref;
4333 int v;
4334
4335 while ((s = s->next) != NULL) {
4336 if ((s->v & SYM_FIELD) &&
4337 (s->type.t & VT_BTYPE) == VT_STRUCT &&
4338 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
4339 check_fields (&s->type, c);
4340 }
4341 v = s->v & ~SYM_FIELD;
4342 if (v < tok_ident)
4343 switch (c) {
4344 case 0:
4345 table_ident[v - TOK_IDENT]->cnt = 0;
4346 break;
4347 case 1:
4348 table_ident[v - TOK_IDENT]->cnt++;
4349 break;
4350 case 2:
4351 if (table_ident[v - TOK_IDENT]->cnt != 1)
4352 tcc_error("duplicate member '%s'",
4353 get_tok_str(v, NULL));
4354 break;
4355 }
4356 }
4357}
4358
4324static void struct_layout(CType *type, AttributeDef *ad)4359static void struct_layout(CType *type, AttributeDef *ad)
4325{4360{
4326 int size, align, maxalign, offset, c, bit_pos, bit_size;4361 int size, align, maxalign, offset, c, bit_pos, bit_size;
@@ -4774,6 +4809,9 @@ do_decl: · 447 unmodified lines
4774 if (ad.cleanup_func) {4809 if (ad.cleanup_func) {
4775 tcc_warning("attribute '__cleanup__' ignored on type");4810 tcc_warning("attribute '__cleanup__' ignored on type");
4776 }4811 }
4812 check_fields(type, 0);
4813 check_fields(type, 1);
4814 check_fields(type, 2);
4777 struct_layout(type, &ad);4815 struct_layout(type, &ad);
4778 }4816 }
4779 }4817 }
tests/tests2/60_errors_and_warnings.c+17−0
@@ -366,4 +366,21 @@ n[sizeof({3;})]; // crashed in block() due to missing local scope · 365 unmodified lines
366f(){"12"3;} // second const token killed the value of the first366f(){"12"3;} // second const token killed the value of the first
367 367
368/******************************************************************/368/******************************************************************/
369#elif defined test_duplicate_member
370struct S {
371 int a, a;
372};
373#elif defined test_duplicate_member_anon
374struct S1 {
375 int b;
376 struct {
377 int b;
378 } c;
379};
380struct S2 {
381 int d;
382 struct {
383 int d;
384 };
385};
369#endif386#endif
tests/tests2/60_errors_and_warnings.expect+6−0
@@ -174,3 +174,9 @@ bar : 3 ; 3 · 173 unmodified lines
174 174
175[test_invalid_tokckill]175[test_invalid_tokckill]
17660_errors_and_warnings.c:366: error: ';' expected (got "3")17660_errors_and_warnings.c:366: error: ';' expected (got "3")
177
178[test_duplicate_member]
17960_errors_and_warnings.c:372: error: duplicate member 'a'
180
181[test_duplicate_member_anon]
18260_errors_and_warnings.c:385: error: duplicate member 'd'

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t