mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
Fix crash on invalid code
like on 'enum myenum { L = -1 } L;'. It's a bit tedious as there are two paths (for global vs local symbols), and because the scope and enum_val share same storage.
This commit is contained in:
parent
b082659f19
commit
ef0397cf3d
12
tccgen.c
12
tccgen.c
@ -571,6 +571,14 @@ ST_INLN Sym *sym_find(int v)
|
|||||||
return table_ident[v]->sym_identifier;
|
return table_ident[v]->sym_identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sym_scope(Sym *s)
|
||||||
|
{
|
||||||
|
if (IS_ENUM_VAL (s->type.t))
|
||||||
|
return s->type.ref->sym_scope;
|
||||||
|
else
|
||||||
|
return s->sym_scope;
|
||||||
|
}
|
||||||
|
|
||||||
/* push a given symbol on the symbol stack */
|
/* push a given symbol on the symbol stack */
|
||||||
ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
|
ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
|
||||||
{
|
{
|
||||||
@ -596,7 +604,7 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
|
|||||||
s->prev_tok = *ps;
|
s->prev_tok = *ps;
|
||||||
*ps = s;
|
*ps = s;
|
||||||
s->sym_scope = local_scope;
|
s->sym_scope = local_scope;
|
||||||
if (s->prev_tok && s->prev_tok->sym_scope == s->sym_scope)
|
if (s->prev_tok && sym_scope(s->prev_tok) == s->sym_scope)
|
||||||
tcc_error("redeclaration of '%s'",
|
tcc_error("redeclaration of '%s'",
|
||||||
get_tok_str(v & ~SYM_STRUCT, NULL));
|
get_tok_str(v & ~SYM_STRUCT, NULL));
|
||||||
}
|
}
|
||||||
@ -919,7 +927,7 @@ static void merge_attr(AttributeDef *ad, AttributeDef *ad1)
|
|||||||
/* Merge some type attributes. */
|
/* Merge some type attributes. */
|
||||||
static void patch_type(Sym *sym, CType *type)
|
static void patch_type(Sym *sym, CType *type)
|
||||||
{
|
{
|
||||||
if (!(type->t & VT_EXTERN)) {
|
if (!(type->t & VT_EXTERN) || IS_ENUM_VAL(sym->type.t)) {
|
||||||
if (!(sym->type.t & VT_EXTERN))
|
if (!(sym->type.t & VT_EXTERN))
|
||||||
tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
|
tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
|
||||||
sym->type.t &= ~VT_EXTERN;
|
sym->type.t &= ~VT_EXTERN;
|
||||||
|
@ -124,4 +124,10 @@ void f() { _Generic((int const *[]){0}, int:0); }
|
|||||||
void f() { _Generic((int (*(*)(float,char))(double,int)){0}, int:0); }
|
void f() { _Generic((int (*(*)(float,char))(double,int)){0}, int:0); }
|
||||||
#elif defined test_array_to_str
|
#elif defined test_array_to_str
|
||||||
void f() { _Generic((int(*)[3]){0}, int:0); }
|
void f() { _Generic((int(*)[3]){0}, int:0); }
|
||||||
|
#elif defined test_duplicate_def_1
|
||||||
|
static enum myenum { L = -1 } L;
|
||||||
|
#elif defined test_duplicate_def_2
|
||||||
|
void foo(void) {
|
||||||
|
static enum myenum { L = -1 } L;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,3 +53,9 @@
|
|||||||
|
|
||||||
[test_array_to_str]
|
[test_array_to_str]
|
||||||
60_errors_and_warnings.c:126: error: type 'int (*)[3]' does not match any association
|
60_errors_and_warnings.c:126: error: type 'int (*)[3]' does not match any association
|
||||||
|
|
||||||
|
[test_duplicate_def_1]
|
||||||
|
60_errors_and_warnings.c:128: error: redefinition of 'L'
|
||||||
|
|
||||||
|
[test_duplicate_def_2]
|
||||||
|
60_errors_and_warnings.c:131: error: redeclaration of 'L'
|
||||||
|
Loading…
Reference in New Issue
Block a user