mirror of
https://github.com/mirror/tinycc.git
synced 2025-03-08 08:40:08 +08:00
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.
This commit is contained in:
parent
bdec3c5345
commit
605538f46d
5
tccgen.c
5
tccgen.c
@ -8482,7 +8482,8 @@ static int decl(int l)
|
||||
sym = sym_push(v, &type, 0, 0);
|
||||
}
|
||||
sym->a = ad.a;
|
||||
sym->f = ad.f;
|
||||
if ((type.t & VT_BTYPE) == VT_FUNC)
|
||||
merge_funcattr(&sym->type.ref->f, &ad.f);
|
||||
if (debug_modes)
|
||||
tcc_debug_typedef (tcc_state, sym);
|
||||
} else if ((type.t & VT_BTYPE) == VT_VOID
|
||||
@ -8493,7 +8494,7 @@ static int decl(int l)
|
||||
if ((type.t & VT_BTYPE) == VT_FUNC) {
|
||||
/* external function definition */
|
||||
/* specific case for func_call attribute */
|
||||
type.ref->f = ad.f;
|
||||
merge_funcattr(&type.ref->f, &ad.f);
|
||||
} else if (!(type.t & VT_ARRAY)) {
|
||||
/* not lvalue if array */
|
||||
r |= VT_LVAL;
|
||||
|
@ -398,6 +398,14 @@ struct S2 {
|
||||
extern int array[2];
|
||||
int array[] = { 1, 2, 3 };
|
||||
|
||||
#elif defined test_incompatible_local_redef
|
||||
void foo (void)
|
||||
{
|
||||
typedef int localfunctype (int);
|
||||
extern localfunctype func2;
|
||||
typedef void localfunctype (int, int);
|
||||
}
|
||||
|
||||
#elif defined test_cast_from_void
|
||||
void v() {}
|
||||
int f() { return v(); }
|
||||
|
@ -190,28 +190,31 @@ bar : 3 ; 3
|
||||
[test_conflicting_array_definition]
|
||||
60_errors_and_warnings.c:399: error: incompatible types for redefinition of 'array'
|
||||
|
||||
[test_incompatible_local_redef]
|
||||
60_errors_and_warnings.c:406: error: incompatible redefinition of 'localfunctype'
|
||||
|
||||
[test_cast_from_void]
|
||||
60_errors_and_warnings.c:403: error: cannot convert 'void' to 'int'
|
||||
60_errors_and_warnings.c:411: error: cannot convert 'void' to 'int'
|
||||
|
||||
[test_switch_W1]
|
||||
60_errors_and_warnings.c:419: warning: implicit declaration of function 'fink'
|
||||
60_errors_and_warnings.c:427: warning: implicit declaration of function 'fink'
|
||||
|
||||
[test_switch_W2]
|
||||
60_errors_and_warnings.c:410: warning: unsupported option '-Wstuff'
|
||||
60_errors_and_warnings.c:421: warning: 'stuff' attribute ignored
|
||||
60_errors_and_warnings.c:418: warning: unsupported option '-Wstuff'
|
||||
60_errors_and_warnings.c:429: warning: 'stuff' attribute ignored
|
||||
|
||||
[test_switch_W3]
|
||||
60_errors_and_warnings.c:418: error: assignment discards qualifiers from pointer target type
|
||||
60_errors_and_warnings.c:426: error: assignment discards qualifiers from pointer target type
|
||||
|
||||
[test_switch_W4]
|
||||
60_errors_and_warnings.c:419: warning: implicit declaration of function 'fink'
|
||||
60_errors_and_warnings.c:421: error: 'stuff' attribute ignored
|
||||
60_errors_and_warnings.c:427: warning: implicit declaration of function 'fink'
|
||||
60_errors_and_warnings.c:429: error: 'stuff' attribute ignored
|
||||
|
||||
[test_invalid_funcparam_1]
|
||||
60_errors_and_warnings.c:424: error: redeclaration of 'a'
|
||||
60_errors_and_warnings.c:432: error: redeclaration of 'a'
|
||||
|
||||
[test_invalid_funcparam_2]
|
||||
60_errors_and_warnings.c:427: error: identifier expected
|
||||
60_errors_and_warnings.c:435: error: identifier expected
|
||||
|
||||
[test_array_funcparam]
|
||||
arg[0] = "X"
|
||||
@ -221,7 +224,7 @@ arg[1] = "Y"
|
||||
[returns 78]
|
||||
|
||||
[test_illegal_unicode]
|
||||
60_errors_and_warnings.c:451: error: 0xffffffff is not a valid universal character
|
||||
60_errors_and_warnings.c:459: error: 0xffffffff is not a valid universal character
|
||||
|
||||
[test_error_string]
|
||||
60_errors_and_warnings.c:456: error: #error \123\456
|
||||
60_errors_and_warnings.c:464: error: #error \123\456
|
||||
|
Loading…
Reference in New Issue
Block a user