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
84828482 sym = sym_push(v, &type, 0, 0);
84838483 }
84848484 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);
84868487 if (debug_modes)
84878488 tcc_debug_typedef (tcc_state, sym);
84888489 } else if ((type.t & VT_BTYPE) == VT_VOID
@@ -8493,7 +8494,7 @@ static int decl(int l) · 4 unmodified lines
84938494 if ((type.t & VT_BTYPE) == VT_FUNC) {
84948495 /* external function definition */
84958496 /* specific case for func_call attribute */
8496− type.ref->f = ad.f;
8497+ merge_funcattr(&type.ref->f, &ad.f);
84978498 } else if (!(type.t & VT_ARRAY)) {
84988499 /* not lvalue if array */
84998500 r |= VT_LVAL;
tests/tests2/60_errors_and_warnings.c+8−0
@@ -398,6 +398,14 @@ struct S2 { · 397 unmodified lines
398398 extern int array[2];
399399 int array[] = { 1, 2, 3 };
400400
401+#elif defined test_incompatible_local_redef
402+void foo (void)
403+{
404+ typedef int localfunctype (int);
405+ extern localfunctype func2;
406+ typedef void localfunctype (int, int);
407+}
408+
401409 #elif defined test_cast_from_void
402410 void v() {}
403411 int f() { return v(); }
tests/tests2/60_errors_and_warnings.expect+14−11
@@ -190,28 +190,31 @@ bar : 3 ; 3 · 189 unmodified lines
190190 [test_conflicting_array_definition]
191191 60_errors_and_warnings.c:399: error: incompatible types for redefinition of 'array'
192192
193+[test_incompatible_local_redef]
194+60_errors_and_warnings.c:406: error: incompatible redefinition of 'localfunctype'
195+
193196 [test_cast_from_void]
194−60_errors_and_warnings.c:403: error: cannot convert 'void' to 'int'
197+60_errors_and_warnings.c:411: error: cannot convert 'void' to 'int'
195198
196199 [test_switch_W1]
197−60_errors_and_warnings.c:419: warning: implicit declaration of function 'fink'
200+60_errors_and_warnings.c:427: warning: implicit declaration of function 'fink'
198201
199202 [test_switch_W2]
200−60_errors_and_warnings.c:410: warning: unsupported option '-Wstuff'
201−60_errors_and_warnings.c:421: warning: 'stuff' attribute ignored
203+60_errors_and_warnings.c:418: warning: unsupported option '-Wstuff'
204+60_errors_and_warnings.c:429: warning: 'stuff' attribute ignored
202205
203206 [test_switch_W3]
204−60_errors_and_warnings.c:418: error: assignment discards qualifiers from pointer target type
207+60_errors_and_warnings.c:426: error: assignment discards qualifiers from pointer target type
205208
206209 [test_switch_W4]
207−60_errors_and_warnings.c:419: warning: implicit declaration of function 'fink'
208−60_errors_and_warnings.c:421: error: 'stuff' attribute ignored
210+60_errors_and_warnings.c:427: warning: implicit declaration of function 'fink'
211+60_errors_and_warnings.c:429: error: 'stuff' attribute ignored
209212
210213 [test_invalid_funcparam_1]
211−60_errors_and_warnings.c:424: error: redeclaration of 'a'
214+60_errors_and_warnings.c:432: error: redeclaration of 'a'
212215
213216 [test_invalid_funcparam_2]
214−60_errors_and_warnings.c:427: error: identifier expected
217+60_errors_and_warnings.c:435: error: identifier expected
215218
216219 [test_array_funcparam]
217220 arg[0] = "X"
@@ -221,7 +224,7 @@ arg[1] = "Y" · 3 unmodified lines
221224 [returns 78]
222225
223226 [test_illegal_unicode]
224−60_errors_and_warnings.c:451: error: 0xffffffff is not a valid universal character
227+60_errors_and_warnings.c:459: error: 0xffffffff is not a valid universal character
225228
226229 [test_error_string]
227−60_errors_and_warnings.c:456: error: #error \123\456
230+60_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