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
432432 struct Sym *sym_struct; /* direct pointer to structure */
433433 struct Sym *sym_identifier; /* direct pointer to identifier */
434434 int tok; /* token number */
435+ int cnt;
435436 int len;
436437 char str[1];
437438 } TokenSym;
tccgen.c+38−0
@@ -4321,6 +4321,41 @@ static Sym * find_field (CType *type, int v, int *cumofs) · 4320 unmodified lines
43214321 return s;
43224322 }
43234323
4324+/*
4325+ * c = 0: reset symbol counter
4326+ * c = 1: increment symbol counter
4327+ * c = 2: check symbol counter
4328+ */
4329+
4330+static 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+
43244359 static void struct_layout(CType *type, AttributeDef *ad)
43254360 {
43264361 int size, align, maxalign, offset, c, bit_pos, bit_size;
@@ -4774,6 +4809,9 @@ do_decl: · 447 unmodified lines
47744809 if (ad.cleanup_func) {
47754810 tcc_warning("attribute '__cleanup__' ignored on type");
47764811 }
4812+ check_fields(type, 0);
4813+ check_fields(type, 1);
4814+ check_fields(type, 2);
47774815 struct_layout(type, &ad);
47784816 }
47794817 }
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
366366 f(){"12"3;} // second const token killed the value of the first
367367
368368 /******************************************************************/
369+#elif defined test_duplicate_member
370+struct S {
371+ int a, a;
372+};
373+#elif defined test_duplicate_member_anon
374+struct S1 {
375+ int b;
376+ struct {
377+ int b;
378+ } c;
379+};
380+struct S2 {
381+ int d;
382+ struct {
383+ int d;
384+ };
385+};
369386 #endif
tests/tests2/60_errors_and_warnings.expect+6−0
@@ -174,3 +174,9 @@ bar : 3 ; 3 · 173 unmodified lines
174174
175175 [test_invalid_tokckill]
176176 60_errors_and_warnings.c:366: error: ';' expected (got "3")
177+
178+[test_duplicate_member]
179+60_errors_and_warnings.c:372: error: duplicate member 'a'
180+
181+[test_duplicate_member_anon]
182+60_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