tccgen.c: local extern decls: copy s->ref for VT_PTR too

This fixes the issue

    int main() { extern char *x; }
    void main1() { extern char *x; }
    t2.c:5: error: incompatible types for redefinition of 'x'

(reported by Giovanni Mascellani 2019/07/16)
This commit is contained in:
grischka 2019-07-16 17:30:04 +02:00
parent 9298555eb6
commit 7b8799e5ff
4 changed files with 41 additions and 13 deletions

View File

@ -98,7 +98,7 @@ TCC_X += riscv64
# cross libtcc1.a targets to build
LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince
LIBTCC1_X = riscv64
LIBTCC1_X += riscv64
PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)

View File

@ -1096,18 +1096,24 @@ static Sym *sym_copy(Sym *s0, Sym **ps)
return s;
}
/* copy a list of syms */
static void sym_copy_ref(Sym *s0, Sym **ps)
/* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */
static void sym_copy_ref(Sym *s, Sym **ps)
{
Sym *s, **sp = &s0->type.ref;
for (s = *sp, *sp = NULL; s; s = s->next)
sp = &(*sp = sym_copy(s, ps))->next;
int bt = s->type.t & VT_BTYPE;
if (bt == VT_FUNC || bt == VT_PTR) {
Sym **sp = &s->type.ref;
for (s = *sp, *sp = NULL; s; s = s->next) {
Sym *s2 = sym_copy(s, ps);
sp = &(*sp = s2)->next;
sym_copy_ref(s2, ps);
}
}
}
/* define a new external reference to a symbol 'v' */
static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
{
Sym *s; int bt;
Sym *s;
/* look for global symbol */
s = sym_find(v);
@ -1121,16 +1127,14 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
s->a = ad->a;
s->asm_label = ad->asm_label;
s->type.ref = type->ref;
bt = s->type.t & (VT_BTYPE|VT_ARRAY);
/* copy type to the global stack also */
if (local_scope && (bt == VT_FUNC || (bt & VT_ARRAY)))
/* copy type to the global stack */
if (local_stack)
sym_copy_ref(s, &global_stack);
} else {
patch_storage(s, ad, type);
bt = s->type.t & VT_BTYPE;
}
/* push variables to local scope if any */
if (local_stack && bt != VT_FUNC)
/* push variables on local_stack if any */
if (local_stack && (s->type.t & VT_BTYPE) != VT_FUNC)
s = sym_copy(s, &local_stack);
return s;
}

View File

@ -273,5 +273,27 @@ int main ()
int xxx[1] = {1};
int bar() { P(3, xxx[0]); return 0; }
#elif defined test_var_4
struct yyy { int y; };
struct zzz;
void f1() {
extern char *x;
extern char **xx;
extern struct yyy y;
extern struct yyy *yy;
extern struct zzz z;
extern struct zzz *zz;
}
void f2() {
extern char *x;
extern char **xx;
extern struct yyy y;
extern struct yyy *yy;
extern struct zzz z;
extern struct zzz *zz;
}
struct yyy y, *yy;
struct zzz { int z; } z, *zz;
/******************************************************************/
#endif

View File

@ -132,3 +132,5 @@ bar : 3 ; 3
[test_var_3]
60_errors_and_warnings.c:273: error: incompatible types for redefinition of 'xxx'
[test_var_4]