History

Fix sym_scope of typedefs

Sym.sym_scope and Sym.f (FuncAttr) share space, so blindly setting one clobbers the other. Right now this only leads to missing errors on incompatible typedefs (see testcase), which this commit fixes. But it points to a larger problem: Generally we can only manipulate Sym.f for anonymous and field symbols, not for anything that has a top-level name (basically any proper decl), because the latter use sym_scope. Luckily the functions type always contains an anonymous symbol (in sym->type.ref), so we can use that. But some of the functions attributes actually _do_ apply to the decl, not the type (e.g. always_inline), so we still have a problem possibly, when we update an pre-existing type that may already be shared with another decl. Would need untangling and perhaps using accessor functions that check that Sym.f and Sym.sym_scope aren't used for the same symbol.

Michael Matz committed 3 years ago

Commit 605538f1 parent bdec3c53 files · +25 −13Browse files

Unified · Split

3 files
  1. tccgen.c +3 −2
  2. tests/tests2/60_errors_and_warnings.c +8 −0
  3. tests/tests2/60_errors_and_warnings.expect +14 −11
tccgen.c+3−2
@@ -8482,7 +8482,8 @@ static int decl(int l) · 8481 unmodified lines
8482 sym = sym_push(v, &type, 0, 0);8482 sym = sym_push(v, &type, 0, 0);
8483 }8483 }
8484 sym->a = ad.a;8484 sym->a = ad.a;
8485 sym->f = ad.f;8485 if ((type.t & VT_BTYPE) == VT_FUNC)
8486 merge_funcattr(&sym->type.ref->f, &ad.f);
8486 if (debug_modes)8487 if (debug_modes)
8487 tcc_debug_typedef (tcc_state, sym);8488 tcc_debug_typedef (tcc_state, sym);
8488 } else if ((type.t & VT_BTYPE) == VT_VOID8489 } else if ((type.t & VT_BTYPE) == VT_VOID
@@ -8493,7 +8494,7 @@ static int decl(int l) · 4 unmodified lines
8493 if ((type.t & VT_BTYPE) == VT_FUNC) {8494 if ((type.t & VT_BTYPE) == VT_FUNC) {
8494 /* external function definition */8495 /* external function definition */
8495 /* specific case for func_call attribute */8496 /* specific case for func_call attribute */
8496 type.ref->f = ad.f;8497 merge_funcattr(&type.ref->f, &ad.f);
8497 } else if (!(type.t & VT_ARRAY)) {8498 } else if (!(type.t & VT_ARRAY)) {
8498 /* not lvalue if array */8499 /* not lvalue if array */
8499 r |= VT_LVAL;8500 r |= VT_LVAL;
tests/tests2/60_errors_and_warnings.c+8−0
@@ -398,6 +398,14 @@ struct S2 { · 397 unmodified lines
398extern int array[2];398extern int array[2];
399int array[] = { 1, 2, 3 };399int array[] = { 1, 2, 3 };
400 400
401#elif defined test_incompatible_local_redef
402void foo (void)
403{
404 typedef int localfunctype (int);
405 extern localfunctype func2;
406 typedef void localfunctype (int, int);
407}
408
401#elif defined test_cast_from_void409#elif defined test_cast_from_void
402void v() {}410void v() {}
403int f() { return v(); }411int f() { return v(); }
tests/tests2/60_errors_and_warnings.expect+14−11
@@ -190,28 +190,31 @@ bar : 3 ; 3 · 189 unmodified lines
190[test_conflicting_array_definition]190[test_conflicting_array_definition]
19160_errors_and_warnings.c:399: error: incompatible types for redefinition of 'array'19160_errors_and_warnings.c:399: error: incompatible types for redefinition of 'array'
192 192
193[test_incompatible_local_redef]
19460_errors_and_warnings.c:406: error: incompatible redefinition of 'localfunctype'
195
193[test_cast_from_void]196[test_cast_from_void]
19460_errors_and_warnings.c:403: error: cannot convert 'void' to 'int'19760_errors_and_warnings.c:411: error: cannot convert 'void' to 'int'
195 198
196[test_switch_W1]199[test_switch_W1]
19760_errors_and_warnings.c:419: warning: implicit declaration of function 'fink'20060_errors_and_warnings.c:427: warning: implicit declaration of function 'fink'
198 201
199[test_switch_W2]202[test_switch_W2]
20060_errors_and_warnings.c:410: warning: unsupported option '-Wstuff'20360_errors_and_warnings.c:418: warning: unsupported option '-Wstuff'
20160_errors_and_warnings.c:421: warning: 'stuff' attribute ignored20460_errors_and_warnings.c:429: warning: 'stuff' attribute ignored
202 205
203[test_switch_W3]206[test_switch_W3]
20460_errors_and_warnings.c:418: error: assignment discards qualifiers from pointer target type20760_errors_and_warnings.c:426: error: assignment discards qualifiers from pointer target type
205 208
206[test_switch_W4]209[test_switch_W4]
20760_errors_and_warnings.c:419: warning: implicit declaration of function 'fink'21060_errors_and_warnings.c:427: warning: implicit declaration of function 'fink'
20860_errors_and_warnings.c:421: error: 'stuff' attribute ignored21160_errors_and_warnings.c:429: error: 'stuff' attribute ignored
209 212
210[test_invalid_funcparam_1]213[test_invalid_funcparam_1]
21160_errors_and_warnings.c:424: error: redeclaration of 'a'21460_errors_and_warnings.c:432: error: redeclaration of 'a'
212 215
213[test_invalid_funcparam_2]216[test_invalid_funcparam_2]
21460_errors_and_warnings.c:427: error: identifier expected21760_errors_and_warnings.c:435: error: identifier expected
215 218
216[test_array_funcparam]219[test_array_funcparam]
217arg[0] = "X"220arg[0] = "X"
@@ -221,7 +224,7 @@ arg[1] = "Y" · 3 unmodified lines
221[returns 78]224[returns 78]
222 225
223[test_illegal_unicode]226[test_illegal_unicode]
22460_errors_and_warnings.c:451: error: 0xffffffff is not a valid universal character22760_errors_and_warnings.c:459: error: 0xffffffff is not a valid universal character
225 228
226[test_error_string]229[test_error_string]
22760_errors_and_warnings.c:456: error: #error \123\45623060_errors_and_warnings.c:464: error: #error \123\456

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