Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

Location:
EcnlProtoTool/trunk/tcc-0.9.27
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c

    r321 r331  
    3131ST_DATA int rsym, anon_sym, ind, loc;
    3232
    33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
    34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
    35 #ifdef CONFIG_TCC_ASM
    36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
    37 #endif
    38 #ifdef CONFIG_TCC_BCHECK
    39 /* bound check related sections */
    40 ST_DATA Section *bounds_section; /* contains global data bound description */
    41 ST_DATA Section *lbounds_section; /* contains local data bound description */
    42 #endif
    43 /* symbol sections */
    44 ST_DATA Section *symtab_section, *strtab_section;
    45 /* debug sections */
    46 ST_DATA Section *stab_section, *stabstr_section;
    4733ST_DATA Sym *sym_free_first;
    4834ST_DATA void **sym_pools;
     
    5137ST_DATA Sym *global_stack;
    5238ST_DATA Sym *local_stack;
    53 ST_DATA Sym *scope_stack_bottom;
    5439ST_DATA Sym *define_stack;
    5540ST_DATA Sym *global_label_stack;
    5641ST_DATA Sym *local_label_stack;
    57 
    58 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
     42static int local_scope;
     43static int in_sizeof;
     44static int section_sym;
     45
     46ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
     47ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
     48ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
     49
     50ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
    5951
    6052ST_DATA int const_wanted; /* true if constant wanted */
    61 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
     53ST_DATA int nocode_wanted; /* no code generation wanted */
     54#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
     55#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
    6256ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
    6357ST_DATA CType func_vt; /* current function return type (used by return instruction) */
     58ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
    6459ST_DATA int func_vc;
    6560ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
    66 ST_DATA char *funcname;
    67 
    68 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
     61ST_DATA const char *funcname;
     62ST_DATA int g_debug;
     63
     64ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type;
     65
     66ST_DATA struct switch_t {
     67    struct case_t {
     68        int64_t v1, v2;
     69        int sym;
     70    } **p; int n; /* list of case ranges */
     71    int def_sym; /* default symbol */
     72} *cur_switch; /* current switch */
    6973
    7074/* ------------------------------------------------------------------------- */
     75
    7176static void gen_cast(CType *type);
     77static void gen_cast_s(int t);
    7278static inline CType *pointed_type(CType *type);
    7379static int is_compatible_types(CType *type1, CType *type2);
    7480static int parse_btype(CType *type, AttributeDef *ad);
    75 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
     81static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
    7682static void parse_expr_type(CType *type);
     83static void init_putv(CType *type, Section *sec, unsigned long c);
    7784static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
    78 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
    79 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
    80 static int decl0(int l, int is_for_loop_init);
     85static void block(int *bsym, int *csym, int is_expr);
     86static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
     87static void decl(int l);
     88static int decl0(int l, int is_for_loop_init, Sym *);
    8189static void expr_eq(void);
    82 static void unary_type(CType *type);
    8390static void vla_runtime_type_size(CType *type, int *a);
    84 static int is_compatible_parameter_types(CType *type1, CType *type2);
    85 static void expr_type(CType *type);
     91static void vla_sp_restore(void);
     92static void vla_sp_restore_root(void);
     93static int is_compatible_unqualified_types(CType *type1, CType *type2);
     94static inline int64_t expr_const64(void);
     95static void vpush64(int ty, unsigned long long v);
     96static void vpush(CType *type);
     97static int gvtst(int inv, int t);
     98static void gen_inline_functions(TCCState *s);
     99static void skip_or_save_block(TokenString **str);
     100static void gv_dup(void);
    86101
    87102ST_INLN int is_float(int t)
     
    89104    int bt;
    90105    bt = t & VT_BTYPE;
    91     return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
     106    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
    92107}
    93108
     
    97112ST_FUNC int ieee_finite(double d)
    98113{
    99     int *p = (int *)&d;
     114    int p[4];
     115    memcpy(p, &d, sizeof(double));
    100116    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
    101117}
     118
     119/* compiling intel long double natively */
     120#if (defined __i386__ || defined __x86_64__) \
     121    && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
     122# define TCC_IS_NATIVE_387
     123#endif
    102124
    103125ST_FUNC void test_lvalue(void)
     
    106128        expect("lvalue");
    107129}
     130
     131ST_FUNC void check_vstack(void)
     132{
     133    if (pvtop != vtop)
     134        tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
     135}
     136
     137/* ------------------------------------------------------------------------- */
     138/* vstack debugging aid */
     139
     140#if 0
     141void pv (const char *lbl, int a, int b)
     142{
     143    int i;
     144    for (i = a; i < a + b; ++i) {
     145        SValue *p = &vtop[-i];
     146        printf("%s vtop[-%d] : type.t:%04x  r:%04x  r2:%04x  c.i:%d\n",
     147            lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
     148    }
     149}
     150#endif
     151
     152/* ------------------------------------------------------------------------- */
     153/* start of translation unit info */
     154ST_FUNC void tcc_debug_start(TCCState *s1)
     155{
     156    if (s1->do_debug) {
     157        char buf[512];
     158
     159        /* file info: full path + filename */
     160        section_sym = put_elf_sym(symtab_section, 0, 0,
     161                                  ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
     162                                  text_section->sh_num, NULL);
     163        getcwd(buf, sizeof(buf));
     164#ifdef _WIN32
     165        normalize_slashes(buf);
     166#endif
     167        pstrcat(buf, sizeof(buf), "/");
     168        put_stabs_r(buf, N_SO, 0, 0,
     169                    text_section->data_offset, text_section, section_sym);
     170        put_stabs_r(file->filename, N_SO, 0, 0,
     171                    text_section->data_offset, text_section, section_sym);
     172        last_ind = 0;
     173        last_line_num = 0;
     174    }
     175
     176    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
     177       symbols can be safely used */
     178    put_elf_sym(symtab_section, 0, 0,
     179                ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
     180                SHN_ABS, file->filename);
     181}
     182
     183/* put end of translation unit info */
     184ST_FUNC void tcc_debug_end(TCCState *s1)
     185{
     186    if (!s1->do_debug)
     187        return;
     188    put_stabs_r(NULL, N_SO, 0, 0,
     189        text_section->data_offset, text_section, section_sym);
     190
     191}
     192
     193/* generate line number info */
     194ST_FUNC void tcc_debug_line(TCCState *s1)
     195{
     196    if (!s1->do_debug)
     197        return;
     198    if ((last_line_num != file->line_num || last_ind != ind)) {
     199        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
     200        last_ind = ind;
     201        last_line_num = file->line_num;
     202    }
     203}
     204
     205/* put function symbol */
     206ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
     207{
     208    char buf[512];
     209
     210    if (!s1->do_debug)
     211        return;
     212
     213    /* stabs info */
     214    /* XXX: we put here a dummy type */
     215    snprintf(buf, sizeof(buf), "%s:%c1",
     216             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
     217    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
     218                cur_text_section, sym->c);
     219    /* //gr gdb wants a line at the function */
     220    put_stabn(N_SLINE, 0, file->line_num, 0);
     221
     222    last_ind = 0;
     223    last_line_num = 0;
     224}
     225
     226/* put function size */
     227ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
     228{
     229    if (!s1->do_debug)
     230        return;
     231    put_stabn(N_FUN, 0, 0, size);
     232}
     233
     234/* ------------------------------------------------------------------------- */
     235ST_FUNC int tccgen_compile(TCCState *s1)
     236{
     237    cur_text_section = NULL;
     238    funcname = "";
     239    anon_sym = SYM_FIRST_ANOM;
     240    section_sym = 0;
     241    const_wanted = 0;
     242    nocode_wanted = 0x80000000;
     243
     244    /* define some often used types */
     245    int_type.t = VT_INT;
     246    char_pointer_type.t = VT_BYTE;
     247    mk_pointer(&char_pointer_type);
     248#if PTR_SIZE == 4
     249    size_type.t = VT_INT | VT_UNSIGNED;
     250    ptrdiff_type.t = VT_INT;
     251#elif LONG_SIZE == 4
     252    size_type.t = VT_LLONG | VT_UNSIGNED;
     253    ptrdiff_type.t = VT_LLONG;
     254#else
     255    size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED;
     256    ptrdiff_type.t = VT_LONG | VT_LLONG;
     257#endif
     258    func_old_type.t = VT_FUNC;
     259    func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
     260    func_old_type.ref->f.func_call = FUNC_CDECL;
     261    func_old_type.ref->f.func_type = FUNC_OLD;
     262
     263    tcc_debug_start(s1);
     264
     265#ifdef TCC_TARGET_ARM
     266    arm_init(s1);
     267#endif
     268
     269#ifdef INC_DEBUG
     270    printf("%s: **** new file\n", file->filename);
     271#endif
     272
     273    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
     274    next();
     275    decl(VT_CONST);
     276    gen_inline_functions(s1);
     277    check_vstack();
     278    /* end of translation unit info */
     279    tcc_debug_end(s1);
     280    return 0;
     281}
     282
     283/* ------------------------------------------------------------------------- */
     284ST_FUNC ElfSym *elfsym(Sym *s)
     285{
     286  if (!s || !s->c)
     287    return NULL;
     288  return &((ElfSym *)symtab_section->data)[s->c];
     289}
     290
     291/* apply storage attributes to Elf symbol */
     292ST_FUNC void update_storage(Sym *sym)
     293{
     294    ElfSym *esym;
     295    int sym_bind, old_sym_bind;
     296
     297    esym = elfsym(sym);
     298    if (!esym)
     299        return;
     300
     301    if (sym->a.visibility)
     302        esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
     303            | sym->a.visibility;
     304
     305    if (sym->type.t & VT_STATIC)
     306        sym_bind = STB_LOCAL;
     307    else if (sym->a.weak)
     308        sym_bind = STB_WEAK;
     309    else
     310        sym_bind = STB_GLOBAL;
     311    old_sym_bind = ELFW(ST_BIND)(esym->st_info);
     312    if (sym_bind != old_sym_bind) {
     313        esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
     314    }
     315
     316#ifdef TCC_TARGET_PE
     317    if (sym->a.dllimport)
     318        esym->st_other |= ST_PE_IMPORT;
     319    if (sym->a.dllexport)
     320        esym->st_other |= ST_PE_EXPORT;
     321#endif
     322
     323#if 0
     324    printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
     325        get_tok_str(sym->v, NULL),
     326        sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
     327        sym->a.visibility,
     328        sym->a.dllexport,
     329        sym->a.dllimport
     330        );
     331#endif
     332}
     333
     334/* ------------------------------------------------------------------------- */
     335/* update sym->c so that it points to an external symbol in section
     336   'section' with value 'value' */
     337
     338ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
     339                            addr_t value, unsigned long size,
     340                            int can_add_underscore)
     341{
     342    int sym_type, sym_bind, info, other, t;
     343    ElfSym *esym;
     344    const char *name;
     345    char buf1[256];
     346#ifdef CONFIG_TCC_BCHECK
     347    char buf[32];
     348#endif
     349
     350    if (!sym->c) {
     351        name = get_tok_str(sym->v, NULL);
     352#ifdef CONFIG_TCC_BCHECK
     353        if (tcc_state->do_bounds_check) {
     354            /* XXX: avoid doing that for statics ? */
     355            /* if bound checking is activated, we change some function
     356               names by adding the "__bound" prefix */
     357            switch(sym->v) {
     358#ifdef TCC_TARGET_PE
     359            /* XXX: we rely only on malloc hooks */
     360            case TOK_malloc:
     361            case TOK_free:
     362            case TOK_realloc:
     363            case TOK_memalign:
     364            case TOK_calloc:
     365#endif
     366            case TOK_memcpy:
     367            case TOK_memmove:
     368            case TOK_memset:
     369            case TOK_strlen:
     370            case TOK_strcpy:
     371            case TOK_alloca:
     372                strcpy(buf, "__bound_");
     373                strcat(buf, name);
     374                name = buf;
     375                break;
     376            }
     377        }
     378#endif
     379        t = sym->type.t;
     380        if ((t & VT_BTYPE) == VT_FUNC) {
     381            sym_type = STT_FUNC;
     382        } else if ((t & VT_BTYPE) == VT_VOID) {
     383            sym_type = STT_NOTYPE;
     384        } else {
     385            sym_type = STT_OBJECT;
     386        }
     387        if (t & VT_STATIC)
     388            sym_bind = STB_LOCAL;
     389        else
     390            sym_bind = STB_GLOBAL;
     391        other = 0;
     392#ifdef TCC_TARGET_PE
     393        if (sym_type == STT_FUNC && sym->type.ref) {
     394            Sym *ref = sym->type.ref;
     395            if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
     396                sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
     397                name = buf1;
     398                other |= ST_PE_STDCALL;
     399                can_add_underscore = 0;
     400            }
     401        }
     402#endif
     403        if (tcc_state->leading_underscore && can_add_underscore) {
     404            buf1[0] = '_';
     405            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
     406            name = buf1;
     407        }
     408        if (sym->asm_label)
     409            name = get_tok_str(sym->asm_label, NULL);
     410        info = ELFW(ST_INFO)(sym_bind, sym_type);
     411        sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
     412    } else {
     413        esym = elfsym(sym);
     414        esym->st_value = value;
     415        esym->st_size = size;
     416        esym->st_shndx = sh_num;
     417    }
     418    update_storage(sym);
     419}
     420
     421ST_FUNC void put_extern_sym(Sym *sym, Section *section,
     422                           addr_t value, unsigned long size)
     423{
     424    int sh_num = section ? section->sh_num : SHN_UNDEF;
     425    put_extern_sym2(sym, sh_num, value, size, 1);
     426}
     427
     428/* add a new relocation entry to symbol 'sym' in section 's' */
     429ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
     430                     addr_t addend)
     431{
     432    int c = 0;
     433
     434    if (nocode_wanted && s == cur_text_section)
     435        return;
     436
     437    if (sym) {
     438        if (0 == sym->c)
     439            put_extern_sym(sym, NULL, 0, 0);
     440        c = sym->c;
     441    }
     442
     443    /* now we can add ELF relocation info */
     444    put_elf_reloca(symtab_section, s, offset, type, c, addend);
     445}
     446
     447#if PTR_SIZE == 4
     448ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
     449{
     450    greloca(s, sym, offset, type, 0);
     451}
     452#endif
    108453
    109454/* ------------------------------------------------------------------------- */
     
    131476{
    132477    Sym *sym;
     478#ifndef SYM_DEBUG
    133479    sym = sym_free_first;
    134480    if (!sym)
     
    136482    sym_free_first = sym->next;
    137483    return sym;
     484#else
     485    sym = tcc_malloc(sizeof(Sym));
     486    return sym;
     487#endif
    138488}
    139489
    140490ST_INLN void sym_free(Sym *sym)
    141491{
     492#ifndef SYM_DEBUG
    142493    sym->next = sym_free_first;
    143     tcc_free(sym->asm_label);
    144494    sym_free_first = sym;
     495#else
     496    tcc_free(sym);
     497#endif
    145498}
    146499
    147500/* push, without hashing */
    148 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
     501ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
    149502{
    150503    Sym *s;
    151     if (ps == &local_stack) {
    152         for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
    153             if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
    154                 tcc_error("incompatible types for redefinition of '%s'",
    155                           get_tok_str(v, NULL));
    156     }
    157     s = *ps;
     504
    158505    s = sym_malloc();
    159     s->asm_label = NULL;
     506    memset(s, 0, sizeof *s);
    160507    s->v = v;
    161508    s->type.t = t;
    162     s->type.ref = NULL;
    163 #ifdef _WIN64
    164     s->d = NULL;
    165 #endif
    166509    s->c = c;
    167     s->next = NULL;
    168510    /* add in stack */
    169511    s->prev = *ps;
     
    179521        if (s->v == v)
    180522            return s;
     523        else if (s->v == -1)
     524            return NULL;
    181525        s = s->prev;
    182526    }
     
    226570        s->prev_tok = *ps;
    227571        *ps = s;
     572        s->sym_scope = local_scope;
     573        if (s->prev_tok && s->prev_tok->sym_scope == s->sym_scope)
     574            tcc_error("redeclaration of '%s'",
     575                get_tok_str(v & ~SYM_STRUCT, NULL));
    228576    }
    229577    return s;
     
    240588        /* modify the top most local identifier, so that
    241589           sym_identifier will point to 's' when popped */
    242         while (*ps != NULL)
     590        while (*ps != NULL && (*ps)->sym_scope)
    243591            ps = &(*ps)->prev_tok;
    244         s->prev_tok = NULL;
     592        s->prev_tok = *ps;
    245593        *ps = s;
    246594    }
     
    248596}
    249597
    250 /* pop symbols until top reaches 'b' */
    251 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
     598/* pop symbols until top reaches 'b'.  If KEEP is non-zero don't really
     599   pop them yet from the list, but do remove them from the token array.  */
     600ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
    252601{
    253602    Sym *s, *ss, **ps;
     
    269618            *ps = s->prev_tok;
    270619        }
    271         sym_free(s);
     620        if (!keep)
     621            sym_free(s);
    272622        s = ss;
    273623    }
    274     *ptop = b;
    275 }
    276 
    277 static void weaken_symbol(Sym *sym)
    278 {
    279     sym->type.t |= VT_WEAK;
    280     if (sym->c > 0) {
    281         int esym_type;
    282         ElfW(Sym) *esym;
    283        
    284         esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
    285         esym_type = ELFW(ST_TYPE)(esym->st_info);
    286         esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
    287     }
     624    if (!keep)
     625        *ptop = b;
    288626}
    289627
    290628/* ------------------------------------------------------------------------- */
    291629
    292 ST_FUNC void swap(int *p, int *q)
    293 {
    294     int t;
    295     t = *p;
    296     *p = *q;
    297     *q = t;
    298 }
    299 
    300630static void vsetc(CType *type, int r, CValue *vc)
    301631{
     
    303633
    304634    if (vtop >= vstack + (VSTACK_SIZE - 1))
    305         tcc_error("memory full");
     635        tcc_error("memory full (vstack)");
    306636    /* cannot let cpu flags if other instruction are generated. Also
    307637       avoid leaving VT_JMP anywhere except on the top of the stack
    308        because it would complicate the code generator. */
    309     if (vtop >= vstack) {
     638       because it would complicate the code generator.
     639
     640       Don't do this when nocode_wanted.  vtop might come from
     641       !nocode_wanted regions (see 88_codeopt.c) and transforming
     642       it to a register without actually generating code is wrong
     643       as their value might still be used for real.  All values
     644       we push under nocode_wanted will eventually be popped
     645       again, so that the VT_CMP/VT_JMP value will be in vtop
     646       when code is unsuppressed again.
     647
     648       Same logic below in vswap(); */
     649    if (vtop >= vstack && !nocode_wanted) {
    310650        v = vtop->r & VT_VALMASK;
    311651        if (v == VT_CMP || (v & ~1) == VT_JMP)
    312652            gv(RC_INT);
    313653    }
     654
    314655    vtop++;
    315656    vtop->type = *type;
     
    317658    vtop->r2 = VT_CONST;
    318659    vtop->c = *vc;
     660    vtop->sym = NULL;
     661}
     662
     663ST_FUNC void vswap(void)
     664{
     665    SValue tmp;
     666    /* cannot vswap cpu flags. See comment at vsetc() above */
     667    if (vtop >= vstack && !nocode_wanted) {
     668        int v = vtop->r & VT_VALMASK;
     669        if (v == VT_CMP || (v & ~1) == VT_JMP)
     670            gv(RC_INT);
     671    }
     672    tmp = vtop[0];
     673    vtop[0] = vtop[-1];
     674    vtop[-1] = tmp;
     675}
     676
     677/* pop stack value */
     678ST_FUNC void vpop(void)
     679{
     680    int v;
     681    v = vtop->r & VT_VALMASK;
     682#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
     683    /* for x86, we need to pop the FP stack */
     684    if (v == TREG_ST0) {
     685        o(0xd8dd); /* fstp %st(0) */
     686    } else
     687#endif
     688    if (v == VT_JMP || v == VT_JMPI) {
     689        /* need to put correct jump if && or || without test */
     690        gsym(vtop->c.i);
     691    }
     692    vtop--;
    319693}
    320694
    321695/* push constant of type "type" with useless value */
    322 void vpush(CType *type)
    323 {
    324     CValue cval;
    325     vsetc(type, VT_CONST, &cval);
     696ST_FUNC void vpush(CType *type)
     697{
     698    vset(type, VT_CONST, 0);
    326699}
    327700
     
    335708
    336709/* push a pointer sized constant */
    337 static void vpushs(long long v)
     710static void vpushs(addr_t v)
    338711{
    339712  CValue cval;
    340   if (PTR_SIZE == 4)
    341     cval.i = (int)v;
    342   else
    343     cval.ull = v;
     713  cval.i = v;
    344714  vsetc(&size_type, VT_CONST, &cval);
    345715}
    346716
    347717/* push arbitrary 64bit constant */
    348 void vpush64(int ty, unsigned long long v)
     718ST_FUNC void vpush64(int ty, unsigned long long v)
    349719{
    350720    CValue cval;
     
    352722    ctype.t = ty;
    353723    ctype.ref = NULL;
    354     cval.ull = v;
     724    cval.i = v;
    355725    vsetc(&ctype, VT_CONST, &cval);
    356726}
     
    360730{
    361731    vpush64(VT_LLONG, v);
     732}
     733
     734ST_FUNC void vset(CType *type, int r, int v)
     735{
     736    CValue cval;
     737
     738    cval.i = v;
     739    vsetc(type, r, &cval);
     740}
     741
     742static void vseti(int r, int v)
     743{
     744    CType type;
     745    type.t = VT_INT;
     746    type.ref = NULL;
     747    vset(&type, r, v);
     748}
     749
     750ST_FUNC void vpushv(SValue *v)
     751{
     752    if (vtop >= vstack + (VSTACK_SIZE - 1))
     753        tcc_error("memory full (vstack)");
     754    vtop++;
     755    *vtop = *v;
     756}
     757
     758static void vdup(void)
     759{
     760    vpushv(vtop);
     761}
     762
     763/* rotate n first stack elements to the bottom
     764   I1 ... In -> I2 ... In I1 [top is right]
     765*/
     766ST_FUNC void vrotb(int n)
     767{
     768    int i;
     769    SValue tmp;
     770
     771    tmp = vtop[-n + 1];
     772    for(i=-n+1;i!=0;i++)
     773        vtop[i] = vtop[i+1];
     774    vtop[0] = tmp;
     775}
     776
     777/* rotate the n elements before entry e towards the top
     778   I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
     779 */
     780ST_FUNC void vrote(SValue *e, int n)
     781{
     782    int i;
     783    SValue tmp;
     784
     785    tmp = *e;
     786    for(i = 0;i < n - 1; i++)
     787        e[-i] = e[-i - 1];
     788    e[-n + 1] = tmp;
     789}
     790
     791/* rotate n first stack elements to the top
     792   I1 ... In -> In I1 ... I(n-1)  [top is right]
     793 */
     794ST_FUNC void vrott(int n)
     795{
     796    vrote(vtop, n);
     797}
     798
     799/* push a symbol value of TYPE */
     800static inline void vpushsym(CType *type, Sym *sym)
     801{
     802    CValue cval;
     803    cval.i = 0;
     804    vsetc(type, VT_CONST | VT_SYM, &cval);
     805    vtop->sym = sym;
    362806}
    363807
     
    379823static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
    380824{
    381     CValue cval;
    382 
    383     cval.ul = 0;
    384     vsetc(type, VT_CONST | VT_SYM, &cval);
    385     vtop->sym = get_sym_ref(type, sec, offset, size);
     825    vpushsym(type, get_sym_ref(type, sec, offset, size)); 
    386826}
    387827
     
    397837        s->type.ref = type->ref;
    398838        s->r = r | VT_CONST | VT_SYM;
     839    } else if (IS_ASM_SYM(s)) {
     840        s->type.t = type->t | (s->type.t & VT_EXTERN);
     841        s->type.ref = type->ref;
     842        update_storage(s);
    399843    }
    400844    return s;
    401845}
    402846
    403 /* define a new external reference to a symbol 'v' with alternate asm
    404    name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
    405    is no alternate name (most cases) */
    406 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
     847/* Merge some type attributes.  */
     848static void patch_type(Sym *sym, CType *type)
     849{
     850    if (!(type->t & VT_EXTERN)) {
     851        if (!(sym->type.t & VT_EXTERN))
     852            tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
     853        sym->type.t &= ~VT_EXTERN;
     854    }
     855
     856    if (IS_ASM_SYM(sym)) {
     857        /* stay static if both are static */
     858        sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
     859        sym->type.ref = type->ref;
     860    }
     861
     862    if (!is_compatible_types(&sym->type, type)) {
     863        tcc_error("incompatible types for redefinition of '%s'",
     864                  get_tok_str(sym->v, NULL));
     865
     866    } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
     867        int static_proto = sym->type.t & VT_STATIC;
     868        /* warn if static follows non-static function declaration */
     869        if ((type->t & VT_STATIC) && !static_proto && !(type->t & VT_INLINE))
     870            tcc_warning("static storage ignored for redefinition of '%s'",
     871                get_tok_str(sym->v, NULL));
     872
     873        if (0 == (type->t & VT_EXTERN)) {
     874            /* put complete type, use static from prototype */
     875            sym->type.t = (type->t & ~VT_STATIC) | static_proto;
     876            if (type->t & VT_INLINE)
     877                sym->type.t = type->t;
     878            sym->type.ref = type->ref;
     879        }
     880
     881    } else {
     882        if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
     883            /* set array size if it was omitted in extern declaration */
     884            if (sym->type.ref->c < 0)
     885                sym->type.ref->c = type->ref->c;
     886            else if (sym->type.ref->c != type->ref->c)
     887                tcc_error("conflicting type for '%s'", get_tok_str(sym->v, NULL));
     888        }
     889        if ((type->t ^ sym->type.t) & VT_STATIC)
     890            tcc_warning("storage mismatch for redefinition of '%s'",
     891                get_tok_str(sym->v, NULL));
     892    }
     893}
     894
     895
     896/* Merge some storage attributes.  */
     897static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
     898{
     899    if (type)
     900        patch_type(sym, type);
     901
     902#ifdef TCC_TARGET_PE
     903    if (sym->a.dllimport != ad->a.dllimport)
     904        tcc_error("incompatible dll linkage for redefinition of '%s'",
     905            get_tok_str(sym->v, NULL));
     906    sym->a.dllexport |= ad->a.dllexport;
     907#endif
     908    sym->a.weak |= ad->a.weak;
     909    if (ad->a.visibility) {
     910        int vis = sym->a.visibility;
     911        int vis2 = ad->a.visibility;
     912        if (vis == STV_DEFAULT)
     913            vis = vis2;
     914        else if (vis2 != STV_DEFAULT)
     915            vis = (vis < vis2) ? vis : vis2;
     916        sym->a.visibility = vis;
     917    }
     918    if (ad->a.aligned)
     919        sym->a.aligned = ad->a.aligned;
     920    if (ad->asm_label)
     921        sym->asm_label = ad->asm_label;
     922    update_storage(sym);
     923}
     924
     925/* define a new external reference to a symbol 'v' */
     926static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
    407927{
    408928    Sym *s;
    409 
    410929    s = sym_find(v);
    411930    if (!s) {
    412931        /* push forward reference */
    413932        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
    414         s->asm_label = asm_label;
    415933        s->type.t |= VT_EXTERN;
    416     } else if (s->type.ref == func_old_type.ref) {
    417         s->type.ref = type->ref;
    418         s->r = r | VT_CONST | VT_SYM;
    419         s->type.t |= VT_EXTERN;
    420     } else if (!is_compatible_types(&s->type, type)) {
    421         tcc_error("incompatible types for redefinition of '%s'",
    422               get_tok_str(v, NULL));
     934        s->a = ad->a;
     935        s->sym_scope = 0;
     936    } else {
     937        if (s->type.ref == func_old_type.ref) {
     938            s->type.ref = type->ref;
     939            s->r = r | VT_CONST | VT_SYM;
     940            s->type.t |= VT_EXTERN;
     941        }
     942        patch_storage(s, ad, type);
    423943    }
    424944    return s;
     
    428948ST_FUNC void vpush_global_sym(CType *type, int v)
    429949{
    430     Sym *sym;
    431     CValue cval;
    432 
    433     sym = external_global_sym(v, type, 0);
    434     cval.ul = 0;
    435     vsetc(type, VT_CONST | VT_SYM, &cval);
    436     vtop->sym = sym;
    437 }
    438 
    439 ST_FUNC void vset(CType *type, int r, int v)
    440 {
    441     CValue cval;
    442 
    443     cval.i = v;
    444     vsetc(type, r, &cval);
    445 }
    446 
    447 static void vseti(int r, int v)
    448 {
    449     CType type;
    450     type.t = VT_INT;
    451     type.ref = 0;
    452     vset(&type, r, v);
    453 }
    454 
    455 ST_FUNC void vswap(void)
    456 {
    457     SValue tmp;
    458     /* cannot let cpu flags if other instruction are generated. Also
    459        avoid leaving VT_JMP anywhere except on the top of the stack
    460        because it would complicate the code generator. */
    461     if (vtop >= vstack) {
    462         int v = vtop->r & VT_VALMASK;
    463         if (v == VT_CMP || (v & ~1) == VT_JMP)
    464             gv(RC_INT);
    465     }
    466     tmp = vtop[0];
    467     vtop[0] = vtop[-1];
    468     vtop[-1] = tmp;
    469 
    470 /* XXX: +2% overall speed possible with optimized memswap
    471  *
    472  *  memswap(&vtop[0], &vtop[1], sizeof *vtop);
    473  */
    474 }
    475 
    476 ST_FUNC void vpushv(SValue *v)
    477 {
    478     if (vtop >= vstack + (VSTACK_SIZE - 1))
    479         tcc_error("memory full");
    480     vtop++;
    481     *vtop = *v;
    482 }
    483 
    484 static void vdup(void)
    485 {
    486     vpushv(vtop);
     950    vpushsym(type, external_global_sym(v, type, 0));
     951}
     952
     953/* save registers up to (vtop - n) stack entry */
     954ST_FUNC void save_regs(int n)
     955{
     956    SValue *p, *p1;
     957    for(p = vstack, p1 = vtop - n; p <= p1; p++)
     958        save_reg(p->r);
    487959}
    488960
     
    490962ST_FUNC void save_reg(int r)
    491963{
     964    save_reg_upstack(r, 0);
     965}
     966
     967/* save r to the memory stack, and mark it as being free,
     968   if seen up to (vtop - n) stack entry */
     969ST_FUNC void save_reg_upstack(int r, int n)
     970{
    492971    int l, saved, size, align;
    493     SValue *p, sv;
     972    SValue *p, *p1, sv;
    494973    CType *type;
     974
     975    if ((r &= VT_VALMASK) >= VT_CONST)
     976        return;
     977    if (nocode_wanted)
     978        return;
    495979
    496980    /* modify all stack values */
    497981    saved = 0;
    498982    l = 0;
    499     for(p=vstack;p<=vtop;p++) {
     983    for(p = vstack, p1 = vtop - n; p <= p1; p++) {
    500984        if ((p->r & VT_VALMASK) == r ||
    501985            ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
     
    508992                if ((p->r & VT_LVAL) ||
    509993                    (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
    510 #ifdef TCC_TARGET_X86_64
     994#if PTR_SIZE == 8
    511995                    type = &char_pointer_type;
    512996#else
     
    5171001                sv.type.t = type->t;
    5181002                sv.r = VT_LOCAL | VT_LVAL;
    519                 sv.c.ul = loc;
     1003                sv.c.i = loc;
    5201004                store(r, &sv);
    5211005#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
     
    5251009                }
    5261010#endif
    527 #ifndef TCC_TARGET_X86_64
     1011#if PTR_SIZE == 4
    5281012                /* special long long case */
    5291013                if ((type->t & VT_BTYPE) == VT_LLONG) {
    530                     sv.c.ul += 4;
     1014                    sv.c.i += 4;
    5311015                    store(p->r2, &sv);
    5321016                }
     
    5391023                /* also clear the bounded flag because the
    5401024                   relocation address of the function was stored in
    541                    p->c.ul */
     1025                   p->c.i */
    5421026                p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
    5431027            } else {
     
    5451029            }
    5461030            p->r2 = VT_CONST;
    547             p->c.ul = l;
     1031            p->c.i = l;
    5481032        }
    5491033    }
     
    5841068    for(r=0;r<NB_REGS;r++) {
    5851069        if (reg_classes[r] & rc) {
     1070            if (nocode_wanted)
     1071                return r;
    5861072            for(p=vstack;p<=vtop;p++) {
    5871073                if ((p->r & VT_VALMASK) == r ||
     
    6131099}
    6141100
    615 /* save registers up to (vtop - n) stack entry */
    616 ST_FUNC void save_regs(int n)
    617 {
    618     int r;
    619     SValue *p, *p1;
    620     p1 = vtop - n;
    621     for(p = vstack;p <= p1; p++) {
    622         r = p->r & VT_VALMASK;
    623         if (r < VT_CONST) {
    624             save_reg(r);
    625         }
    626     }
    627 }
    628 
    629 /* move register 's' to 'r', and flush previous value of r to memory
     1101/* move register 's' (of type 't') to 'r', and flush previous value of r to memory
    6301102   if needed */
    631 static void move_reg(int r, int s)
     1103static void move_reg(int r, int s, int t)
    6321104{
    6331105    SValue sv;
     
    6351107    if (r != s) {
    6361108        save_reg(r);
    637         sv.type.t = VT_INT;
     1109        sv.type.t = t;
     1110        sv.type.ref = NULL;
    6381111        sv.r = s;
    639         sv.c.ul = 0;
     1112        sv.c.i = 0;
    6401113        load(r, &sv);
    6411114    }
     
    6431116
    6441117/* get address of vtop (vtop MUST BE an lvalue) */
    645 static void gaddrof(void)
    646 {
    647     if (vtop->r & VT_REF)
    648         gv(RC_INT);
     1118ST_FUNC void gaddrof(void)
     1119{
    6491120    vtop->r &= ~VT_LVAL;
    6501121    /* tricky: if saved lvalue, then we can go back to lvalue */
     
    6701141            /* must save type because we must set it to int to get pointer */
    6711142            type1 = vtop->type;
    672             vtop->type.t = VT_INT;
     1143            vtop->type.t = VT_PTR;
    6731144            gaddrof();
    6741145            vpushi(0);
     
    6831154#endif
    6841155
     1156static void incr_bf_adr(int o)
     1157{
     1158    vtop->type = char_pointer_type;
     1159    gaddrof();
     1160    vpushi(o);
     1161    gen_op('+');
     1162    vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN))
     1163        | (VT_BYTE|VT_UNSIGNED);
     1164    vtop->r = (vtop->r & ~VT_LVAL_TYPE)
     1165        | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL);
     1166}
     1167
     1168/* single-byte load mode for packed or otherwise unaligned bitfields */
     1169static void load_packed_bf(CType *type, int bit_pos, int bit_size)
     1170{
     1171    int n, o, bits;
     1172    save_reg_upstack(vtop->r, 1);
     1173    vpush64(type->t & VT_BTYPE, 0); // B X
     1174    bits = 0, o = bit_pos >> 3, bit_pos &= 7;
     1175    do {
     1176        vswap(); // X B
     1177        incr_bf_adr(o);
     1178        vdup(); // X B B
     1179        n = 8 - bit_pos;
     1180        if (n > bit_size)
     1181            n = bit_size;
     1182        if (bit_pos)
     1183            vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
     1184        if (n < 8)
     1185            vpushi((1 << n) - 1), gen_op('&');
     1186        gen_cast(type);
     1187        if (bits)
     1188            vpushi(bits), gen_op(TOK_SHL);
     1189        vrotb(3); // B Y X
     1190        gen_op('|'); // B X
     1191        bits += n, bit_size -= n, o = 1;
     1192    } while (bit_size);
     1193    vswap(), vpop();
     1194    if (!(type->t & VT_UNSIGNED)) {
     1195        n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
     1196        vpushi(n), gen_op(TOK_SHL);
     1197        vpushi(n), gen_op(TOK_SAR);
     1198    }
     1199}
     1200
     1201/* single-byte store mode for packed or otherwise unaligned bitfields */
     1202static void store_packed_bf(int bit_pos, int bit_size)
     1203{
     1204    int bits, n, o, m, c;
     1205
     1206    c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     1207    vswap(); // X B
     1208    save_reg_upstack(vtop->r, 1);
     1209    bits = 0, o = bit_pos >> 3, bit_pos &= 7;
     1210    do {
     1211        incr_bf_adr(o); // X B
     1212        vswap(); //B X
     1213        c ? vdup() : gv_dup(); // B V X
     1214        vrott(3); // X B V
     1215        if (bits)
     1216            vpushi(bits), gen_op(TOK_SHR);
     1217        if (bit_pos)
     1218            vpushi(bit_pos), gen_op(TOK_SHL);
     1219        n = 8 - bit_pos;
     1220        if (n > bit_size)
     1221            n = bit_size;
     1222        if (n < 8) {
     1223            m = ((1 << n) - 1) << bit_pos;
     1224            vpushi(m), gen_op('&'); // X B V1
     1225            vpushv(vtop-1); // X B V1 B
     1226            vpushi(m & 0x80 ? ~m & 0x7f : ~m);
     1227            gen_op('&'); // X B V1 B1
     1228            gen_op('|'); // X B V2
     1229        }
     1230        vdup(), vtop[-1] = vtop[-2]; // X B B V2
     1231        vstore(), vpop(); // X B
     1232        bits += n, bit_size -= n, bit_pos = 0, o = 1;
     1233    } while (bit_size);
     1234    vpop(), vpop();
     1235}
     1236
     1237static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
     1238{
     1239    int t;
     1240    if (0 == sv->type.ref)
     1241        return 0;
     1242    t = sv->type.ref->auxtype;
     1243    if (t != -1 && t != VT_STRUCT) {
     1244        sv->type.t = (sv->type.t & ~VT_BTYPE) | t;
     1245        sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t);
     1246    }
     1247    return t;
     1248}
     1249
    6851250/* store vtop a register belonging to class 'rc'. lvalues are
    6861251   converted to values. Cannot be used if cannot be converted to
     
    6881253ST_FUNC int gv(int rc)
    6891254{
    690     int r, bit_pos, bit_size, size, align, i;
    691 #ifndef TCC_TARGET_X86_64
    692     int rc2;
    693 #endif
     1255    int r, bit_pos, bit_size, size, align, rc2;
    6941256
    6951257    /* NOTE: get_reg can modify vstack[] */
    6961258    if (vtop->type.t & VT_BITFIELD) {
    6971259        CType type;
    698         int bits = 32;
    699         bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
    700         bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
     1260
     1261        bit_pos = BIT_POS(vtop->type.t);
     1262        bit_size = BIT_SIZE(vtop->type.t);
    7011263        /* remove bit field info to avoid loops */
    702         vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
    703         /* cast to int to propagate signedness in following ops */
    704         if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
    705             type.t = VT_LLONG;
    706             bits = 64;
    707         } else
    708             type.t = VT_INT;
    709         if((vtop->type.t & VT_UNSIGNED) ||
    710            (vtop->type.t & VT_BTYPE) == VT_BOOL)
     1264        vtop->type.t &= ~VT_STRUCT_MASK;
     1265
     1266        type.ref = NULL;
     1267        type.t = vtop->type.t & VT_UNSIGNED;
     1268        if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
    7111269            type.t |= VT_UNSIGNED;
    712         gen_cast(&type);
    713         /* generate shifts */
    714         vpushi(bits - (bit_pos + bit_size));
    715         gen_op(TOK_SHL);
    716         vpushi(bits - bit_size);
    717         /* NOTE: transformed to SHR if unsigned */
    718         gen_op(TOK_SAR);
     1270
     1271        r = adjust_bf(vtop, bit_pos, bit_size);
     1272
     1273        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
     1274            type.t |= VT_LLONG;
     1275        else
     1276            type.t |= VT_INT;
     1277
     1278        if (r == VT_STRUCT) {
     1279            load_packed_bf(&type, bit_pos, bit_size);
     1280        } else {
     1281            int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
     1282            /* cast to int to propagate signedness in following ops */
     1283            gen_cast(&type);
     1284            /* generate shifts */
     1285            vpushi(bits - (bit_pos + bit_size));
     1286            gen_op(TOK_SHL);
     1287            vpushi(bits - bit_size);
     1288            /* NOTE: transformed to SHR if unsigned */
     1289            gen_op(TOK_SAR);
     1290        }
    7191291        r = gv(rc);
    7201292    } else {
    7211293        if (is_float(vtop->type.t) &&
    7221294            (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
    723             Sym *sym;
    724             int *ptr;
    7251295            unsigned long offset;
    726 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
    727             CValue check;
    728 #endif
    729            
    730             /* XXX: unify with initializers handling ? */
    7311296            /* CPUs usually cannot use float constants, so we store them
    7321297               generically in data segment */
    7331298            size = type_size(&vtop->type, &align);
    734             offset = (data_section->data_offset + align - 1) & -align;
    735             data_section->data_offset = offset;
    736             /* XXX: not portable yet */
    737 #if defined(__i386__) || defined(__x86_64__)
    738             /* Zero pad x87 tenbyte long doubles */
    739             if (size == LDOUBLE_SIZE) {
    740                 vtop->c.tab[2] &= 0xffff;
    741 #if LDOUBLE_SIZE == 16
    742                 vtop->c.tab[3] = 0;
    743 #endif
    744             }
    745 #endif
    746             ptr = section_ptr_add(data_section, size);
    747             size = size >> 2;
    748 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
    749             check.d = 1;
    750             if(check.tab[0])
    751                 for(i=0;i<size;i++)
    752                     ptr[i] = vtop->c.tab[size-1-i];
    753             else
    754 #endif
    755             for(i=0;i<size;i++)
    756                 ptr[i] = vtop->c.tab[i];
    757             sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
    758             vtop->r |= VT_LVAL | VT_SYM;
    759             vtop->sym = sym;
    760             vtop->c.ul = 0;
     1299            if (NODATA_WANTED)
     1300                size = 0, align = 1;
     1301            offset = section_add(data_section, size, align);
     1302            vpush_ref(&vtop->type, data_section, offset, size);
     1303            vswap();
     1304            init_putv(&vtop->type, data_section, offset);
     1305            vtop->r |= VT_LVAL;
    7611306        }
    7621307#ifdef CONFIG_TCC_BCHECK
     
    7661311
    7671312        r = vtop->r & VT_VALMASK;
    768 #ifndef TCC_TARGET_X86_64
    769         rc2 = RC_INT;
     1313        rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
     1314#ifndef TCC_TARGET_ARM64
    7701315        if (rc == RC_IRET)
    7711316            rc2 = RC_LRET;
     1317#ifdef TCC_TARGET_X86_64
     1318        else if (rc == RC_FRET)
     1319            rc2 = RC_QRET;
     1320#endif
    7721321#endif
    7731322        /* need to reload if:
     
    7781327         || (vtop->r & VT_LVAL)
    7791328         || !(reg_classes[r] & rc)
    780 #ifndef TCC_TARGET_X86_64
     1329#if PTR_SIZE == 8
     1330         || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
     1331         || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
     1332#else
    7811333         || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
    7821334#endif
     
    7841336        {
    7851337            r = get_reg(rc);
    786 #ifndef TCC_TARGET_X86_64
     1338#if PTR_SIZE == 8
     1339            if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
     1340                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
     1341#else
    7871342            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
    788                 int r2;
     1343                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
    7891344                unsigned long long ll;
     1345#endif
     1346                int r2, original_type;
     1347                original_type = vtop->type.t;
    7901348                /* two register type load : expand to two words
    7911349                   temporarily */
     1350#if PTR_SIZE == 4
    7921351                if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
    7931352                    /* load constant */
    794                     ll = vtop->c.ull;
    795                     vtop->c.ui = ll; /* first word */
     1353                    ll = vtop->c.i;
     1354                    vtop->c.i = ll; /* first word */
    7961355                    load(r, vtop);
    7971356                    vtop->r = r; /* save register value */
    7981357                    vpushi(ll >> 32); /* second word */
    799                 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
    800                            (vtop->r & VT_LVAL)) {
     1358                } else
     1359#endif
     1360                if (vtop->r & VT_LVAL) {
    8011361                    /* We do not want to modifier the long long
    8021362                       pointer here, so the safest (and less
    8031363                       efficient) is to save all the other registers
    8041364                       in the stack. XXX: totally inefficient. */
     1365               #if 0
    8051366                    save_regs(1);
     1367               #else
     1368                    /* lvalue_save: save only if used further down the stack */
     1369                    save_reg_upstack(vtop->r, 1);
     1370               #endif
    8061371                    /* load from memory */
     1372                    vtop->type.t = load_type;
    8071373                    load(r, vtop);
    8081374                    vdup();
    8091375                    vtop[-1].r = r; /* save register value */
    8101376                    /* increment pointer to get second word */
    811                     vtop->type.t = VT_INT;
     1377                    vtop->type.t = addr_type;
    8121378                    gaddrof();
    813                     vpushi(4);
     1379                    vpushi(load_size);
    8141380                    gen_op('+');
    8151381                    vtop->r |= VT_LVAL;
     1382                    vtop->type.t = load_type;
    8161383                } else {
    8171384                    /* move registers */
     
    8281395                /* write second register */
    8291396                vtop->r2 = r2;
    830             } else
    831 #endif
    832             if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
     1397                vtop->type.t = original_type;
     1398            } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
    8331399                int t1, t;
    8341400                /* lvalue of scalar type : need to use lvalue type
     
    8941460}
    8951461
     1462#ifndef TCC_TARGET_ARM64
    8961463/* wrapper around RC_FRET to return a register by type */
    8971464static int rc_fret(int t)
     
    9041471    return RC_FRET;
    9051472}
     1473#endif
    9061474
    9071475/* wrapper around REG_FRET to return a register by type */
     
    9161484}
    9171485
    918 /* expand long long on stack in two int registers */
     1486#if PTR_SIZE == 4
     1487/* expand 64bit on stack in two ints */
    9191488static void lexpand(void)
    9201489{
    921     int u;
    922 
    923     u = vtop->type.t & VT_UNSIGNED;
    924     gv(RC_INT);
    925     vdup();
    926     vtop[0].r = vtop[-1].r2;
    927     vtop[0].r2 = VT_CONST;
    928     vtop[-1].r2 = VT_CONST;
    929     vtop[0].type.t = VT_INT | u;
    930     vtop[-1].type.t = VT_INT | u;
    931 }
     1490    int u, v;
     1491    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
     1492    v = vtop->r & (VT_VALMASK | VT_LVAL);
     1493    if (v == VT_CONST) {
     1494        vdup();
     1495        vtop[0].c.i >>= 32;
     1496    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
     1497        vdup();
     1498        vtop[0].c.i += 4;
     1499    } else {
     1500        gv(RC_INT);
     1501        vdup();
     1502        vtop[0].r = vtop[-1].r2;
     1503        vtop[0].r2 = vtop[-1].r2 = VT_CONST;
     1504    }
     1505    vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
     1506}
     1507#endif
    9321508
    9331509#ifdef TCC_TARGET_ARM
     
    9371513    int u,v;
    9381514
    939     u = vtop->type.t & VT_UNSIGNED;
     1515    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
    9401516    vdup();
    9411517    vtop->r2 = VT_CONST;
     
    9431519    v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
    9441520    if (v == VT_CONST) {
    945       vtop[-1].c.ui = vtop->c.ull;
    946       vtop->c.ui = vtop->c.ull >> 32;
     1521      vtop[-1].c.i = vtop->c.i;
     1522      vtop->c.i = vtop->c.i >> 32;
    9471523      vtop->r = VT_CONST;
    9481524    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
    949       vtop->c.ui += 4;
     1525      vtop->c.i += 4;
    9501526      vtop->r = vtop[-1].r;
    9511527    } else if (v > VT_CONST) {
     
    9591535#endif
    9601536
     1537#if PTR_SIZE == 4
    9611538/* build a long long from two ints */
    9621539static void lbuild(int t)
     
    9671544    vpop();
    9681545}
    969 
    970 /* rotate n first stack elements to the bottom
    971    I1 ... In -> I2 ... In I1 [top is right]
    972 */
    973 ST_FUNC void vrotb(int n)
    974 {
    975     int i;
    976     SValue tmp;
    977 
    978     tmp = vtop[-n + 1];
    979     for(i=-n+1;i!=0;i++)
    980         vtop[i] = vtop[i+1];
    981     vtop[0] = tmp;
    982 }
    983 
    984 /* rotate the n elements before entry e towards the top
    985    I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
    986  */
    987 ST_FUNC void vrote(SValue *e, int n)
    988 {
    989     int i;
    990     SValue tmp;
    991 
    992     tmp = *e;
    993     for(i = 0;i < n - 1; i++)
    994         e[-i] = e[-i - 1];
    995     e[-n + 1] = tmp;
    996 }
    997 
    998 /* rotate n first stack elements to the top
    999    I1 ... In -> In I1 ... I(n-1)  [top is right]
    1000  */
    1001 ST_FUNC void vrott(int n)
    1002 {
    1003     vrote(vtop, n);
    1004 }
    1005 
    1006 /* pop stack value */
    1007 ST_FUNC void vpop(void)
    1008 {
    1009     int v;
    1010     v = vtop->r & VT_VALMASK;
    1011 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
    1012     /* for x86, we need to pop the FP stack */
    1013     if (v == TREG_ST0 && !nocode_wanted) {
    1014         o(0xd8dd); /* fstp %st(0) */
    1015     } else
    1016 #endif
    1017     if (v == VT_JMP || v == VT_JMPI) {
    1018         /* need to put correct jump if && or || without test */
    1019         gsym(vtop->c.ul);
    1020     }
    1021     vtop--;
    1022 }
     1546#endif
    10231547
    10241548/* convert stack entry to register and duplicate its value in another
     
    10301554
    10311555    t = vtop->type.t;
     1556#if PTR_SIZE == 4
    10321557    if ((t & VT_BTYPE) == VT_LLONG) {
     1558        if (t & VT_BITFIELD) {
     1559            gv(RC_INT);
     1560            t = vtop->type.t;
     1561        }
    10331562        lexpand();
    10341563        gv_dup();
     
    10441573        lbuild(t);
    10451574        vswap();
    1046     } else {
     1575    } else
     1576#endif
     1577    {
    10471578        /* duplicate value */
    10481579        rc = RC_INT;
     
    10601591        r1 = get_reg(rc);
    10611592        sv.r = r;
    1062         sv.c.ul = 0;
     1593        sv.c.i = 0;
    10631594        load(r1, &sv); /* move r to r1 */
    10641595        vdup();
     
    10691600}
    10701601
    1071 #ifndef TCC_TARGET_X86_64
     1602/* Generate value test
     1603 *
     1604 * Generate a test for any value (jump, comparison and integers) */
     1605ST_FUNC int gvtst(int inv, int t)
     1606{
     1607    int v = vtop->r & VT_VALMASK;
     1608    if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
     1609        vpushi(0);
     1610        gen_op(TOK_NE);
     1611    }
     1612    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
     1613        /* constant jmp optimization */
     1614        if ((vtop->c.i != 0) != inv)
     1615            t = gjmp(t);
     1616        vtop--;
     1617        return t;
     1618    }
     1619    return gtst(inv, t);
     1620}
     1621
     1622#if PTR_SIZE == 4
    10721623/* generate CPU independent (unsigned) long long operations */
    10731624static void gen_opl(int op)
     
    11121663    case '+':
    11131664    case '-':
     1665        //pv("gen_opl A",0,2);
    11141666        t = vtop->type.t;
    11151667        vswap();
     
    11261678        vswap();
    11271679        /* stack: H1 H2 L1 L2 */
     1680        //pv("gen_opl B",0,4);
    11281681        if (op == '*') {
    11291682            vpushv(vtop - 1);
     
    11811734            /* constant: simpler */
    11821735            /* NOTE: all comments are for SHL. the other cases are
    1183                done by swaping words */
     1736               done by swapping words */
    11841737            vpop();
    11851738            if (op != TOK_SHL)
     
    12661819        b = 0;
    12671820        gen_op(op1);
    1268         if (op1 != TOK_NE) {
    1269             a = gtst(1, 0);
    1270         }
    1271         if (op != TOK_EQ) {
    1272             /* generate non equal test */
    1273             /* XXX: NOT PORTABLE yet */
    1274             if (a == 0) {
    1275                 b = gtst(0, 0);
    1276             } else {
    1277 #if defined(TCC_TARGET_I386)
    1278                 b = psym(0x850f, 0);
    1279 #elif defined(TCC_TARGET_ARM)
    1280                 b = ind;
    1281                 o(0x1A000000 | encbranch(ind, 0, 1));
    1282 #elif defined(TCC_TARGET_C67)
    1283                 tcc_error("not implemented");
    1284 #elif defined(TCC_TARGET_IL)
    1285                 tcc_error("not implemented");
    1286 #else
    1287 #error not supported
    1288 #endif
     1821        if (op == TOK_NE) {
     1822            b = gvtst(0, 0);
     1823        } else {
     1824            a = gvtst(1, 0);
     1825            if (op != TOK_EQ) {
     1826                /* generate non equal test */
     1827                vpushi(TOK_NE);
     1828                vtop->r = VT_CMP;
     1829                b = gvtst(0, 0);
    12891830            }
    12901831        }
     
    13001841            op1 = TOK_UGE;
    13011842        gen_op(op1);
    1302         a = gtst(1, a);
     1843        a = gvtst(1, a);
    13031844        gsym(b);
    13041845        vseti(VT_JMPI, a);
     
    13081849#endif
    13091850
     1851static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
     1852{
     1853    uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
     1854    return (a ^ b) >> 63 ? -x : x;
     1855}
     1856
     1857static int gen_opic_lt(uint64_t a, uint64_t b)
     1858{
     1859    return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
     1860}
     1861
    13101862/* handle integer constant optimizations and various machine
    13111863   independent opt */
    13121864static void gen_opic(int op)
    13131865{
    1314     int c1, c2, t1, t2, n;
    1315     SValue *v1, *v2;
    1316     long long l1, l2;
    1317     typedef unsigned long long U;
    1318 
    1319     v1 = vtop - 1;
    1320     v2 = vtop;
    1321     t1 = v1->type.t & VT_BTYPE;
    1322     t2 = v2->type.t & VT_BTYPE;
    1323 
    1324     if (t1 == VT_LLONG)
    1325         l1 = v1->c.ll;
    1326     else if (v1->type.t & VT_UNSIGNED)
    1327         l1 = v1->c.ui;
    1328     else
    1329         l1 = v1->c.i;
    1330 
    1331     if (t2 == VT_LLONG)
    1332         l2 = v2->c.ll;
    1333     else if (v2->type.t & VT_UNSIGNED)
    1334         l2 = v2->c.ui;
    1335     else
    1336         l2 = v2->c.i;
    1337 
    1338     /* currently, we cannot do computations with forward symbols */
    1339     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    1340     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     1866    SValue *v1 = vtop - 1;
     1867    SValue *v2 = vtop;
     1868    int t1 = v1->type.t & VT_BTYPE;
     1869    int t2 = v2->type.t & VT_BTYPE;
     1870    int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     1871    int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     1872    uint64_t l1 = c1 ? v1->c.i : 0;
     1873    uint64_t l2 = c2 ? v2->c.i : 0;
     1874    int shm = (t1 == VT_LLONG) ? 63 : 31;
     1875
     1876    if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
     1877        l1 = ((uint32_t)l1 |
     1878              (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
     1879    if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
     1880        l2 = ((uint32_t)l2 |
     1881              (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
     1882
    13411883    if (c1 && c2) {
    13421884        switch(op) {
     
    13601902            }
    13611903            switch(op) {
    1362             default: l1 /= l2; break;
    1363             case '%': l1 %= l2; break;
    1364             case TOK_UDIV: l1 = (U)l1 / l2; break;
    1365             case TOK_UMOD: l1 = (U)l1 % l2; break;
     1904            default: l1 = gen_opic_sdiv(l1, l2); break;
     1905            case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
     1906            case TOK_UDIV: l1 = l1 / l2; break;
     1907            case TOK_UMOD: l1 = l1 % l2; break;
    13661908            }
    13671909            break;
    1368         case TOK_SHL: l1 <<= l2; break;
    1369         case TOK_SHR: l1 = (U)l1 >> l2; break;
    1370         case TOK_SAR: l1 >>= l2; break;
     1910        case TOK_SHL: l1 <<= (l2 & shm); break;
     1911        case TOK_SHR: l1 >>= (l2 & shm); break;
     1912        case TOK_SAR:
     1913            l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
     1914            break;
    13711915            /* tests */
    1372         case TOK_ULT: l1 = (U)l1 < (U)l2; break;
    1373         case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
     1916        case TOK_ULT: l1 = l1 < l2; break;
     1917        case TOK_UGE: l1 = l1 >= l2; break;
    13741918        case TOK_EQ: l1 = l1 == l2; break;
    13751919        case TOK_NE: l1 = l1 != l2; break;
    1376         case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
    1377         case TOK_UGT: l1 = (U)l1 > (U)l2; break;
    1378         case TOK_LT: l1 = l1 < l2; break;
    1379         case TOK_GE: l1 = l1 >= l2; break;
    1380         case TOK_LE: l1 = l1 <= l2; break;
    1381         case TOK_GT: l1 = l1 > l2; break;
     1920        case TOK_ULE: l1 = l1 <= l2; break;
     1921        case TOK_UGT: l1 = l1 > l2; break;
     1922        case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
     1923        case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
     1924        case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
     1925        case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
    13821926            /* logical */
    13831927        case TOK_LAND: l1 = l1 && l2; break;
     
    13861930            goto general_case;
    13871931        }
    1388         v1->c.ll = l1;
     1932        if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
     1933            l1 = ((uint32_t)l1 |
     1934                (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
     1935        v1->c.i = l1;
    13891936        vtop--;
    13901937    } else {
     
    13961943            l2 = l1; //l = l1, l1 = l2, l2 = l;
    13971944        }
    1398         /* Filter out NOP operations like x*1, x-0, x&-1... */
    1399         if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
    1400                      op == TOK_PDIV) &&
    1401                     l2 == 1) ||
    1402                    ((op == '+' || op == '-' || op == '|' || op == '^' ||
    1403                      op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
    1404                     l2 == 0) ||
    1405                    (op == '&' &&
    1406                     l2 == -1))) {
    1407             /* nothing to do */
     1945        if (!const_wanted &&
     1946            c1 && ((l1 == 0 &&
     1947                    (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
     1948                   (l1 == -1 && op == TOK_SAR))) {
     1949            /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
     1950            vtop--;
     1951        } else if (!const_wanted &&
     1952                   c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
     1953                          (op == '|' &&
     1954                            (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
     1955                          (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
     1956            /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
     1957            if (l2 == 1)
     1958                vtop->c.i = 0;
     1959            vswap();
     1960            vtop--;
     1961        } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
     1962                          op == TOK_PDIV) &&
     1963                           l2 == 1) ||
     1964                          ((op == '+' || op == '-' || op == '|' || op == '^' ||
     1965                            op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
     1966                           l2 == 0) ||
     1967                          (op == '&' &&
     1968                            (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
     1969            /* filter out NOP operations like x*1, x-0, x&-1... */
    14081970            vtop--;
    14091971        } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
    14101972            /* try to use shifts instead of muls or divs */
    14111973            if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
    1412                 n = -1;
     1974                int n = -1;
    14131975                while (l2) {
    14141976                    l2 >>= 1;
    14151977                    n++;
    14161978                }
    1417                 vtop->c.ll = n;
     1979                vtop->c.i = n;
    14181980                if (op == '*')
    14191981                    op = TOK_SHL;
     
    14301992            if (op == '-')
    14311993                l2 = -l2;
     1994            l2 += vtop[-1].c.i;
     1995            /* The backends can't always deal with addends to symbols
     1996               larger than +-1<<31.  Don't construct such.  */
     1997            if ((int)l2 != l2)
     1998                goto general_case;
    14321999            vtop--;
    1433             vtop->c.ll += l2;
     2000            vtop->c.i = l2;
    14342001        } else {
    14352002        general_case:
    1436             if (!nocode_wanted) {
    14372003                /* call low level op generator */
    1438                 if (t1 == VT_LLONG || t2 == VT_LLONG)
     2004                if (t1 == VT_LLONG || t2 == VT_LLONG ||
     2005                    (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
    14392006                    gen_opl(op);
    14402007                else
    14412008                    gen_opi(op);
    1442             } else {
    1443                 vtop--;
    1444             }
    14452009        }
    14462010    }
     
    14522016    int c1, c2;
    14532017    SValue *v1, *v2;
     2018#if defined _MSC_VER && defined _AMD64_
     2019    /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
     2020    volatile
     2021#endif
    14542022    long double f1, f2;
    14552023
     
    15032071    } else {
    15042072    general_case:
    1505         if (!nocode_wanted) {
    1506             gen_opf(op);
    1507         } else {
    1508             vtop--;
    1509         }
     2073        gen_opf(op);
    15102074    }
    15112075}
     
    15272091    if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
    15282092        return 0;
    1529     return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
    1530         ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
    1531         ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
     2093    return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
     2094        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
     2095        ((p->type.t & VT_BTYPE) == VT_PTR &&
     2096         (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
    15322097}
    15332098
     
    15382103}
    15392104
    1540 /* check types for comparison or substraction of pointers */
     2105/* check types for comparison or subtraction of pointers */
    15412106static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
    15422107{
     
    15752140    tmp_type1 = *type1;
    15762141    tmp_type2 = *type2;
    1577     tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    1578     tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
     2142    tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
     2143    tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    15792144    if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
    15802145        /* gcc-like error if '-' is used */
     
    15922157    CType type1;
    15932158
     2159redo:
    15942160    t1 = vtop[-1].type.t;
    15952161    t2 = vtop[0].type.t;
     
    15972163    bt2 = t2 & VT_BTYPE;
    15982164       
    1599     if (bt1 == VT_PTR || bt2 == VT_PTR) {
     2165    if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
     2166        tcc_error("operation on a struct");
     2167    } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
     2168        if (bt2 == VT_FUNC) {
     2169            mk_pointer(&vtop->type);
     2170            gaddrof();
     2171        }
     2172        if (bt1 == VT_FUNC) {
     2173            vswap();
     2174            mk_pointer(&vtop->type);
     2175            gaddrof();
     2176            vswap();
     2177        }
     2178        goto redo;
     2179    } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
    16002180        /* at least one operand is a pointer */
    1601         /* relationnal op: must be both pointers */
     2181        /* relational op: must be both pointers */
    16022182        if (op >= TOK_ULT && op <= TOK_LOR) {
    16032183            check_comparison_pointer_types(vtop - 1, vtop, op);
    16042184            /* pointers are handled are unsigned */
    1605 #ifdef TCC_TARGET_X86_64
     2185#if PTR_SIZE == 8
    16062186            t = VT_LLONG | VT_UNSIGNED;
    16072187#else
     
    16232203            vrott(3);
    16242204            gen_opic(op);
    1625             /* set to integer type */
    1626 #ifdef TCC_TARGET_X86_64
    1627             vtop->type.t = VT_LLONG;
    1628 #else
    1629             vtop->type.t = VT_INT;
    1630 #endif
     2205            vtop->type.t = ptrdiff_type.t;
    16312206            vswap();
    16322207            gen_op(TOK_PDIV);
     
    16382213            if (bt2 == VT_PTR) {
    16392214                vswap();
    1640                 swap(&t1, &t2);
    1641             }
     2215                t = t1, t1 = t2, t2 = t;
     2216            }
     2217#if PTR_SIZE == 4
     2218            if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
     2219                /* XXX: truncate here because gen_opl can't handle ptr + long long */
     2220                gen_cast_s(VT_INT);
     2221#endif
    16422222            type1 = vtop[-1].type;
    16432223            type1.t &= ~VT_ARRAY;
     
    16482228                if (u < 0)
    16492229                    tcc_error("unknown array element size");
    1650 #ifdef TCC_TARGET_X86_64
     2230#if PTR_SIZE == 8
    16512231                vpushll(u);
    16522232#else
     
    16562236            }
    16572237            gen_op('*');
    1658 #ifdef CONFIG_TCC_BCHECK
     2238#if 0
     2239/* #ifdef CONFIG_TCC_BCHECK
     2240    The main reason to removing this code:
     2241        #include <stdio.h>
     2242        int main ()
     2243        {
     2244            int v[10];
     2245            int i = 10;
     2246            int j = 9;
     2247            fprintf(stderr, "v+i-j  = %p\n", v+i-j);
     2248            fprintf(stderr, "v+(i-j)  = %p\n", v+(i-j));
     2249        }
     2250    When this code is on. then the output looks like
     2251        v+i-j = 0xfffffffe
     2252        v+(i-j) = 0xbff84000
     2253    */
    16592254            /* if evaluating constant expression, no code should be
    16602255               generated, so no bound check */
     
    16922287    } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
    16932288        t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
    1694         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
     2289        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
    16952290          t |= VT_UNSIGNED;
     2291        t |= (VT_LONG & t1);
    16962292        goto std_op;
    16972293    } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
    16982294        /* cast to biggest op */
    1699         t = VT_LLONG;
     2295        t = VT_LLONG | VT_LONG;
     2296        if (bt1 == VT_LLONG)
     2297            t &= t1;
     2298        if (bt2 == VT_LLONG)
     2299            t &= t2;
    17002300        /* convert to unsigned if it does not fit in a long long */
    1701         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
    1702             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
     2301        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
     2302            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
    17032303            t |= VT_UNSIGNED;
    17042304        goto std_op;
    1705     } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
    1706         tcc_error("comparison of struct");
    17072305    } else {
    17082306        /* integer operations */
    1709         t = VT_INT;
     2307        t = VT_INT | (VT_LONG & (t1 | t2));
    17102308        /* convert to unsigned if it does not fit in an integer */
    1711         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
    1712             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
     2309        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
     2310            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
    17132311            t |= VT_UNSIGNED;
    17142312    std_op:
     
    17332331        vswap();
    17342332        type1.t = t;
     2333        type1.ref = NULL;
    17352334        gen_cast(&type1);
    17362335        vswap();
     
    17452344            gen_opic(op);
    17462345        if (op >= TOK_ULT && op <= TOK_GT) {
    1747             /* relationnal op: the result is an int */
     2346            /* relational op: the result is an int */
    17482347            vtop->type.t = VT_INT;
    17492348        } else {
     
    17512350        }
    17522351    }
     2352    // Make sure that we have converted to an rvalue:
     2353    if (vtop->r & VT_LVAL)
     2354        gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
    17532355}
    17542356
     
    17572359static void gen_cvt_itof1(int t)
    17582360{
     2361#ifdef TCC_TARGET_ARM64
     2362    gen_cvt_itof(t);
     2363#else
    17592364    if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
    17602365        (VT_LLONG | VT_UNSIGNED)) {
     
    17752380        gen_cvt_itof(t);
    17762381    }
     2382#endif
    17772383}
    17782384#endif
     
    17812387static void gen_cvt_ftoi1(int t)
    17822388{
     2389#ifdef TCC_TARGET_ARM64
     2390    gen_cvt_ftoi(t);
     2391#else
    17832392    int st;
    17842393
     
    18022411        gen_cvt_ftoi(t);
    18032412    }
     2413#endif
    18042414}
    18052415
     
    18082418{
    18092419    int bits, dbt;
     2420
     2421    /* cannot cast static initializers */
     2422    if (STATIC_DATA_WANTED)
     2423        return;
     2424
    18102425    dbt = t & VT_BTYPE;
    18112426    /* XXX: add optimization if lvalue : just change type and offset */
     
    18182433        gen_op('&');
    18192434    } else {
    1820         bits = 32 - bits;
     2435        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
     2436            bits = 64 - bits;
     2437        else
     2438            bits = 32 - bits;
    18212439        vpushi(bits);
    18222440        gen_op(TOK_SHL);
     
    18312449
    18322450/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
     2451static void gen_cast_s(int t)
     2452{
     2453    CType type;
     2454    type.t = t;
     2455    type.ref = NULL;
     2456    gen_cast(&type);
     2457}
     2458
    18332459static void gen_cast(CType *type)
    18342460{
     
    18562482        c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    18572483        p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
     2484#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
     2485        c &= dbt != VT_LDOUBLE;
     2486#endif
    18582487        if (c) {
    18592488            /* constant case: we can do it now */
     
    18662495            if (df) {
    18672496                if ((sbt & VT_BTYPE) == VT_LLONG) {
    1868                     if (sbt & VT_UNSIGNED)
    1869                         vtop->c.ld = vtop->c.ull;
     2497                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
     2498                        vtop->c.ld = vtop->c.i;
    18702499                    else
    1871                         vtop->c.ld = vtop->c.ll;
     2500                        vtop->c.ld = -(long double)-vtop->c.i;
    18722501                } else if(!sf) {
    1873                     if (sbt & VT_UNSIGNED)
    1874                         vtop->c.ld = vtop->c.ui;
     2502                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
     2503                        vtop->c.ld = (uint32_t)vtop->c.i;
    18752504                    else
    1876                         vtop->c.ld = vtop->c.i;
     2505                        vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
    18772506                }
    18782507
     
    18822511                    vtop->c.d = (double)vtop->c.ld;
    18832512            } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
    1884                 vtop->c.ull = (unsigned long long)vtop->c.ld;
     2513                vtop->c.i = vtop->c.ld;
    18852514            } else if (sf && dbt == VT_BOOL) {
    18862515                vtop->c.i = (vtop->c.ld != 0);
    18872516            } else {
    18882517                if(sf)
    1889                     vtop->c.ll = (long long)vtop->c.ld;
     2518                    vtop->c.i = vtop->c.ld;
    18902519                else if (sbt == (VT_LLONG|VT_UNSIGNED))
    1891                     vtop->c.ll = vtop->c.ull;
     2520                    ;
    18922521                else if (sbt & VT_UNSIGNED)
    1893                     vtop->c.ll = vtop->c.ui;
    1894 #ifdef TCC_TARGET_X86_64
     2522                    vtop->c.i = (uint32_t)vtop->c.i;
     2523#if PTR_SIZE == 8
    18952524                else if (sbt == VT_PTR)
    18962525                    ;
    18972526#endif
    18982527                else if (sbt != VT_LLONG)
    1899                     vtop->c.ll = vtop->c.i;
     2528                    vtop->c.i = ((uint32_t)vtop->c.i |
     2529                                  -(vtop->c.i & 0x80000000));
    19002530
    19012531                if (dbt == (VT_LLONG|VT_UNSIGNED))
    1902                     vtop->c.ull = vtop->c.ll;
     2532                    ;
    19032533                else if (dbt == VT_BOOL)
    1904                     vtop->c.i = (vtop->c.ll != 0);
     2534                    vtop->c.i = (vtop->c.i != 0);
     2535#if PTR_SIZE == 8
     2536                else if (dbt == VT_PTR)
     2537                    ;
     2538#endif
    19052539                else if (dbt != VT_LLONG) {
    1906                     int s = 0;
    1907                     if ((dbt & VT_BTYPE) == VT_BYTE)
    1908                         s = 24;
    1909                     else if ((dbt & VT_BTYPE) == VT_SHORT)
    1910                         s = 16;
    1911 
    1912                     if(dbt & VT_UNSIGNED)
    1913                         vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
    1914                     else
    1915                         vtop->c.i = ((int)vtop->c.ll << s) >> s;
     2540                    uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
     2541                                  (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
     2542                                  0xffffffff);
     2543                    vtop->c.i &= m;
     2544                    if (!(dbt & VT_UNSIGNED))
     2545                        vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
    19162546                }
    19172547            }
     
    19192549            vtop->r = VT_CONST;
    19202550            vtop->c.i = 1;
    1921         } else if (!nocode_wanted) {
     2551        } else {
    19222552            /* non constant case: generate code */
    19232553            if (sf && df) {
     
    19452575                    }
    19462576                }
    1947 #ifndef TCC_TARGET_X86_64
     2577#if PTR_SIZE == 4
    19482578            } else if ((dbt & VT_BTYPE) == VT_LLONG) {
    19492579                if ((sbt & VT_BTYPE) != VT_LLONG) {
     
    19592589                            /* cast from pointer to int before we apply
    19602590                               shift operation, which pointers don't support*/
    1961                             gen_cast(&int_type);
     2591                            gen_cast_s(VT_INT);
    19622592                        }
    19632593                        gv_dup();
     
    19772607                    (sbt & VT_BTYPE) != VT_FUNC) {
    19782608                    /* need to convert from 32bit to 64bit */
    1979                     int r = gv(RC_INT);
     2609                    gv(RC_INT);
    19802610                    if (sbt != (VT_INT | VT_UNSIGNED)) {
     2611#if defined(TCC_TARGET_ARM64)
     2612                        gen_cvt_sxtw();
     2613#elif defined(TCC_TARGET_X86_64)
     2614                        int r = gv(RC_INT);
    19812615                        /* x86_64 specific: movslq */
    19822616                        o(0x6348);
    19832617                        o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
     2618#else
     2619#error
     2620#endif
    19842621                    }
    19852622                }
     
    19962633                }
    19972634                force_charshort_cast(dbt);
     2635#if PTR_SIZE == 4
    19982636            } else if ((dbt & VT_BTYPE) == VT_INT) {
    19992637                /* scalar to int */
    2000                 if (sbt == VT_LLONG) {
     2638                if ((sbt & VT_BTYPE) == VT_LLONG) {
    20012639                    /* from long long: just take low order word */
    20022640                    lexpand();
     
    20062644                   the lvalue already contains the real type size (see
    20072645                   VT_LVAL_xxx constants) */
     2646#endif
    20082647            }
    20092648        }
     
    20442683            return PTR_SIZE;
    20452684        }
     2685    } else if (IS_ENUM(type->t) && type->ref->c == -1) {
     2686        return -1; /* incomplete enum */
    20462687    } else if (bt == VT_LDOUBLE) {
    20472688        *a = LDOUBLE_ALIGN;
     
    20642705#endif
    20652706        return 8;
    2066     } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
     2707    } else if (bt == VT_INT || bt == VT_FLOAT) {
    20672708        *a = 4;
    20682709        return 4;
     
    20702711        *a = 2;
    20712712        return 2;
     2713    } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
     2714        *a = 8;
     2715        return 16;
    20722716    } else {
    20732717        /* char, void, function, _Bool */
     
    20822726{
    20832727    if (type->t & VT_VLA) {
     2728        type_size(&type->ref->type, a);
    20842729        vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
    20852730    } else {
     
    20882733}
    20892734
     2735static void vla_sp_restore(void) {
     2736    if (vlas_in_scope) {
     2737        gen_vla_sp_restore(vla_sp_loc);
     2738    }
     2739}
     2740
     2741static void vla_sp_restore_root(void) {
     2742    if (vlas_in_scope) {
     2743        gen_vla_sp_restore(vla_sp_root_loc);
     2744    }
     2745}
     2746
    20902747/* return the pointed type of t */
    20912748static inline CType *pointed_type(CType *type)
     
    20992756    Sym *s;
    21002757    s = sym_push(SYM_FIELD, type, 0, -1);
    2101     type->t = VT_PTR | (type->t & ~VT_TYPE);
     2758    type->t = VT_PTR | (type->t & VT_STORAGE);
    21022759    type->ref = s;
    21032760}
     
    21132770        return 0;
    21142771    /* check func_call */
    2115     if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
     2772    if (s1->f.func_call != s2->f.func_call)
    21162773        return 0;
    21172774    /* XXX: not complete */
    2118     if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
     2775    if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD)
    21192776        return 1;
    2120     if (s1->c != s2->c)
     2777    if (s1->f.func_type != s2->f.func_type)
    21212778        return 0;
    21222779    while (s1 != NULL) {
    21232780        if (s2 == NULL)
    21242781            return 0;
    2125         if (!is_compatible_parameter_types(&s1->type, &s2->type))
     2782        if (!is_compatible_unqualified_types(&s1->type, &s2->type))
    21262783            return 0;
    21272784        s1 = s1->next;
     
    21482805        t1 &= ~(VT_CONSTANT | VT_VOLATILE);
    21492806        t2 &= ~(VT_CONSTANT | VT_VOLATILE);
     2807    }
     2808
     2809    /* Default Vs explicit signedness only matters for char */
     2810    if ((t1 & VT_BTYPE) != VT_BYTE) {
     2811        t1 &= ~VT_DEFSIGN;
     2812        t2 &= ~VT_DEFSIGN;
    21502813    }
    21512814    /* XXX: bitfields ? */
     
    21772840/* return true if type1 and type2 are the same (ignoring qualifiers).
    21782841*/
    2179 static int is_compatible_parameter_types(CType *type1, CType *type2)
     2842static int is_compatible_unqualified_types(CType *type1, CType *type2)
    21802843{
    21812844    return compare_types(type1,type2,1);
     
    21942857    const char *tstr;
    21952858
    2196     t = type->t & VT_TYPE;
     2859    t = type->t;
    21972860    bt = t & VT_BTYPE;
    21982861    buf[0] = '\0';
     2862
     2863    if (t & VT_EXTERN)
     2864        pstrcat(buf, buf_size, "extern ");
     2865    if (t & VT_STATIC)
     2866        pstrcat(buf, buf_size, "static ");
     2867    if (t & VT_TYPEDEF)
     2868        pstrcat(buf, buf_size, "typedef ");
     2869    if (t & VT_INLINE)
     2870        pstrcat(buf, buf_size, "inline ");
     2871    if (t & VT_VOLATILE)
     2872        pstrcat(buf, buf_size, "volatile ");
    21992873    if (t & VT_CONSTANT)
    22002874        pstrcat(buf, buf_size, "const ");
    2201     if (t & VT_VOLATILE)
    2202         pstrcat(buf, buf_size, "volatile ");
    2203     if (t & VT_UNSIGNED)
    2204         pstrcat(buf, buf_size, "unsigned ");
     2875
     2876    if (((t & VT_DEFSIGN) && bt == VT_BYTE)
     2877        || ((t & VT_UNSIGNED)
     2878            && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
     2879            && !IS_ENUM(t)
     2880            ))
     2881        pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
     2882
     2883    buf_size -= strlen(buf);
     2884    buf += strlen(buf);
     2885
    22052886    switch(bt) {
    22062887    case VT_VOID:
     
    22182899    case VT_INT:
    22192900        tstr = "int";
    2220         goto add_tstr;
    2221     case VT_LONG:
    2222         tstr = "long";
    2223         goto add_tstr;
     2901        goto maybe_long;
    22242902    case VT_LLONG:
    22252903        tstr = "long long";
    2226         goto add_tstr;
     2904    maybe_long:
     2905        if (t & VT_LONG)
     2906            tstr = "long";
     2907        if (!IS_ENUM(t))
     2908            goto add_tstr;
     2909        tstr = "enum ";
     2910        goto tstruct;
    22272911    case VT_FLOAT:
    22282912        tstr = "float";
     
    22362920        pstrcat(buf, buf_size, tstr);
    22372921        break;
    2238     case VT_ENUM:
    22392922    case VT_STRUCT:
    2240         if (bt == VT_STRUCT)
    2241             tstr = "struct ";
    2242         else
    2243             tstr = "enum ";
     2923        tstr = "struct ";
     2924        if (IS_UNION(t))
     2925            tstr = "union ";
     2926    tstruct:
    22442927        pstrcat(buf, buf_size, tstr);
    22452928        v = type->ref->v & ~SYM_STRUCT;
     
    22652948    case VT_PTR:
    22662949        s = type->ref;
     2950        if (t & VT_ARRAY) {
     2951            snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
     2952            type_to_str(buf, buf_size, &s->type, buf1);
     2953            goto no_var;
     2954        }
    22672955        pstrcpy(buf1, sizeof(buf1), "*");
     2956        if (t & VT_CONSTANT)
     2957            pstrcat(buf1, buf_size, "const ");
     2958        if (t & VT_VOLATILE)
     2959            pstrcat(buf1, buf_size, "volatile ");
    22682960        if (varstr)
    22692961            pstrcat(buf1, sizeof(buf1), varstr);
     
    22822974static void gen_assign_cast(CType *dt)
    22832975{
    2284     CType *st, *type1, *type2, tmp_type1, tmp_type2;
     2976    CType *st, *type1, *type2;
    22852977    char buf1[256], buf2[256];
    22862978    int dbt, sbt;
     
    22892981    dbt = dt->t & VT_BTYPE;
    22902982    sbt = st->t & VT_BTYPE;
    2291     if (sbt == VT_VOID)
    2292         tcc_error("Cannot assign void value");
     2983    if (sbt == VT_VOID || dbt == VT_VOID) {
     2984        if (sbt == VT_VOID && dbt == VT_VOID)
     2985            ; /*
     2986              It is Ok if both are void
     2987              A test program:
     2988                void func1() {}
     2989                void func2() {
     2990                  return func1();
     2991                }
     2992              gcc accepts this program
     2993              */
     2994        else
     2995            tcc_error("cannot cast from/to void");
     2996    }
    22932997    if (dt->t & VT_CONSTANT)
    22942998        tcc_warning("assignment of read-only location");
     
    23053009        }
    23063010        type1 = pointed_type(dt);
    2307         /* a function is implicitely a function pointer */
     3011        /* a function is implicitly a function pointer */
    23083012        if (sbt == VT_FUNC) {
    23093013            if ((type1->t & VT_BTYPE) != VT_VOID &&
     
    23193023            /* void * can match anything */
    23203024        } else {
    2321             /* exact type match, except for unsigned */
    2322             tmp_type1 = *type1;
    2323             tmp_type2 = *type2;
    2324             tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    2325             tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    2326             if (!is_compatible_types(&tmp_type1, &tmp_type2))
    2327                 tcc_warning("assignment from incompatible pointer type");
     3025            //printf("types %08x %08x\n", type1->t, type2->t);
     3026            /* exact type match, except for qualifiers */
     3027            if (!is_compatible_unqualified_types(type1, type2)) {
     3028                /* Like GCC don't warn by default for merely changes
     3029                   in pointer target signedness.  Do warn for different
     3030                   base types, though, in particular for unsigned enums
     3031                   and signed int targets.  */
     3032                if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG))
     3033                    || IS_ENUM(type1->t) || IS_ENUM(type2->t)
     3034                    )
     3035                    tcc_warning("assignment from incompatible pointer type");
     3036            }
    23283037        }
    23293038        /* check const and volatile */
     
    23383047        if (sbt == VT_PTR || sbt == VT_FUNC) {
    23393048            tcc_warning("assignment makes integer from pointer without a cast");
     3049        } else if (sbt == VT_STRUCT) {
     3050            goto case_VT_STRUCT;
    23403051        }
    23413052        /* XXX: more tests */
    23423053        break;
    23433054    case VT_STRUCT:
    2344         tmp_type1 = *dt;
    2345         tmp_type2 = *st;
    2346         tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
    2347         tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
    2348         if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
     3055    case_VT_STRUCT:
     3056        if (!is_compatible_unqualified_types(dt, st)) {
    23493057        error:
    23503058            type_to_str(buf1, sizeof(buf1), st, NULL);
     
    23713079        /* optimize char/short casts */
    23723080        delayed_cast = VT_MUSTCAST;
    2373         vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
     3081        vtop->type.t = ft & VT_TYPE;
    23743082        /* XXX: factorize */
    23753083        if (ft & VT_CONSTANT)
     
    23853093        /* structure assignment : generate memcpy */
    23863094        /* XXX: optimize if small size */
    2387         if (!nocode_wanted) {
    23883095            size = type_size(&vtop->type, &align);
    23893096
     
    24013108            else
    24023109#endif
    2403             vpush_global_sym(&func_old_type, TOK_memcpy);
     3110            /* Use memmove, rather than memcpy, as dest and src may be same: */
     3111            vpush_global_sym(&func_old_type, TOK_memmove);
    24043112
    24053113            vswap();
     
    24113119            vpushi(size);
    24123120            gfunc_call(3);
    2413         } else {
    2414             vswap();
    2415             vpop();
    2416         }
     3121
    24173122        /* leave source on stack */
    24183123    } else if (ft & VT_BITFIELD) {
    24193124        /* bitfield store handling */
    2420         bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
    2421         bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
     3125
     3126        /* save lvalue as expression result (example: s.b = s.a = n;) */
     3127        vdup(), vtop[-1] = vtop[-2];
     3128
     3129        bit_pos = BIT_POS(ft);
     3130        bit_size = BIT_SIZE(ft);
    24223131        /* remove bit field info to avoid loops */
    2423         vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
    2424 
    2425         /* duplicate source into other register */
    2426         gv_dup();
    2427         vswap();
    2428         vrott(3);
    2429 
    2430         if((ft & VT_BTYPE) == VT_BOOL) {
     3132        vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
     3133
     3134        if ((ft & VT_BTYPE) == VT_BOOL) {
    24313135            gen_cast(&vtop[-1].type);
    24323136            vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
    24333137        }
    24343138
    2435         /* duplicate destination */
    2436         vdup();
    2437         vtop[-1] = vtop[-2];
    2438 
    2439         /* mask and shift source */
    2440         if((ft & VT_BTYPE) != VT_BOOL) {
    2441             if((ft & VT_BTYPE) == VT_LLONG) {
    2442                 vpushll((1ULL << bit_size) - 1ULL);
    2443             } else {
    2444                 vpushi((1 << bit_size) - 1);
    2445             }
     3139        r = adjust_bf(vtop - 1, bit_pos, bit_size);
     3140        if (r == VT_STRUCT) {
     3141            gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT);
     3142            store_packed_bf(bit_pos, bit_size);
     3143        } else {
     3144            unsigned long long mask = (1ULL << bit_size) - 1;
     3145            if ((ft & VT_BTYPE) != VT_BOOL) {
     3146                /* mask source */
     3147                if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG)
     3148                    vpushll(mask);
     3149                else
     3150                    vpushi((unsigned)mask);
     3151                gen_op('&');
     3152            }
     3153            /* shift source */
     3154            vpushi(bit_pos);
     3155            gen_op(TOK_SHL);
     3156            vswap();
     3157            /* duplicate destination */
     3158            vdup();
     3159            vrott(3);
     3160            /* load destination, mask and or with source */
     3161            if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
     3162                vpushll(~(mask << bit_pos));
     3163            else
     3164                vpushi(~((unsigned)mask << bit_pos));
    24463165            gen_op('&');
    2447         }
    2448         vpushi(bit_pos);
    2449         gen_op(TOK_SHL);
    2450         /* load destination, mask and or with source */
    2451         vswap();
    2452         if((ft & VT_BTYPE) == VT_LLONG) {
    2453             vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
    2454         } else {
    2455             vpushi(~(((1 << bit_size) - 1) << bit_pos));
    2456         }
    2457         gen_op('&');
    2458         gen_op('|');
    2459         /* store result */
    2460         vstore();
    2461 
    2462         /* pop off shifted source from "duplicate source..." above */
    2463         vpop();
    2464 
     3166            gen_op('|');
     3167            /* store result */
     3168            vstore();
     3169            /* ... and discard */
     3170            vpop();
     3171        }
     3172    } else if (dbt == VT_VOID) {
     3173        --vtop;
    24653174    } else {
    24663175#ifdef CONFIG_TCC_BCHECK
    2467         /* bound check case */
    2468         if (vtop[-1].r & VT_MUSTBOUND) {
    2469             vswap();
    2470             gbound();
    2471             vswap();
    2472         }
    2473 #endif
    2474         if (!nocode_wanted) {
     3176            /* bound check case */
     3177            if (vtop[-1].r & VT_MUSTBOUND) {
     3178                vswap();
     3179                gbound();
     3180                vswap();
     3181            }
     3182#endif
    24753183            rc = RC_INT;
    24763184            if (is_float(ft)) {
     
    24793187                if ((ft & VT_BTYPE) == VT_LDOUBLE) {
    24803188                    rc = RC_ST0;
     3189                } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
     3190                    rc = RC_FRET;
    24813191                }
    24823192#endif
     
    24873197                SValue sv;
    24883198                t = get_reg(RC_INT);
    2489 #ifdef TCC_TARGET_X86_64
     3199#if PTR_SIZE == 8
    24903200                sv.type.t = VT_PTR;
    24913201#else
     
    24933203#endif
    24943204                sv.r = VT_LOCAL | VT_LVAL;
    2495                 sv.c.ul = vtop[-1].c.ul;
     3205                sv.c.i = vtop[-1].c.i;
    24963206                load(t, &sv);
    24973207                vtop[-1].r = t | VT_LVAL;
    24983208            }
    2499             store(r, vtop - 1);
    2500 #ifndef TCC_TARGET_X86_64
    2501             /* two word case handling : store second register at word + 4 */
     3209            /* two word case handling : store second register at word + 4 (or +8 for x86-64)  */
     3210#if PTR_SIZE == 8
     3211            if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
     3212                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
     3213#else
    25023214            if ((ft & VT_BTYPE) == VT_LLONG) {
     3215                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
     3216#endif
     3217                vtop[-1].type.t = load_type;
     3218                store(r, vtop - 1);
    25033219                vswap();
    25043220                /* convert to int to increment easily */
    2505                 vtop->type.t = VT_INT;
     3221                vtop->type.t = addr_type;
    25063222                gaddrof();
    2507                 vpushi(4);
     3223                vpushi(load_size);
    25083224                gen_op('+');
    25093225                vtop->r |= VT_LVAL;
    25103226                vswap();
     3227                vtop[-1].type.t = load_type;
    25113228                /* XXX: it works because r2 is spilled last ! */
    25123229                store(vtop->r2, vtop - 1);
    2513             }
    2514 #endif
    2515         }
     3230            } else {
     3231                store(r, vtop - 1);
     3232            }
     3233
    25163234        vswap();
    25173235        vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
     
    25383256}
    25393257
    2540 /* Parse GNUC __attribute__ extension. Currently, the following
    2541    extensions are recognized:
    2542    - aligned(n) : set data/function alignment.
    2543    - packed : force data alignment to 1
    2544    - section(x) : generate data/code in this section.
    2545    - unused : currently ignored, but may be used someday.
    2546    - regparm(n) : pass function parameters in registers (i386 only)
    2547  */
     3258ST_FUNC void parse_mult_str (CString *astr, const char *msg)
     3259{
     3260    /* read the string */
     3261    if (tok != TOK_STR)
     3262        expect(msg);
     3263    cstr_new(astr);
     3264    while (tok == TOK_STR) {
     3265        /* XXX: add \0 handling too ? */
     3266        cstr_cat(astr, tokc.str.data, -1);
     3267        next();
     3268    }
     3269    cstr_ccat(astr, '\0');
     3270}
     3271
     3272/* If I is >= 1 and a power of two, returns log2(i)+1.
     3273   If I is 0 returns 0.  */
     3274static int exact_log2p1(int i)
     3275{
     3276  int ret;
     3277  if (!i)
     3278    return 0;
     3279  for (ret = 1; i >= 1 << 8; ret += 8)
     3280    i >>= 8;
     3281  if (i >= 1 << 4)
     3282    ret += 4, i >>= 4;
     3283  if (i >= 1 << 2)
     3284    ret += 2, i >>= 2;
     3285  if (i >= 1 << 1)
     3286    ret++;
     3287  return ret;
     3288}
     3289
     3290/* Parse __attribute__((...)) GNUC extension. */
    25483291static void parse_attribute(AttributeDef *ad)
    25493292{
    25503293    int t, n;
     3294    CString astr;
    25513295   
    2552     while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
     3296redo:
     3297    if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
     3298        return;
    25533299    next();
    25543300    skip('(');
     
    25633309        case TOK_SECTION2:
    25643310            skip('(');
    2565             if (tok != TOK_STR)
    2566                 expect("section name");
    2567             ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
    2568             next();
     3311            parse_mult_str(&astr, "section name");
     3312            ad->section = find_section(tcc_state, (char *)astr.data);
    25693313            skip(')');
     3314            cstr_free(&astr);
    25703315            break;
    25713316        case TOK_ALIAS1:
    25723317        case TOK_ALIAS2:
    25733318            skip('(');
    2574             if (tok != TOK_STR)
    2575                 expect("alias(\"target\")");
     3319            parse_mult_str(&astr, "alias(\"target\")");
    25763320            ad->alias_target = /* save string as token, for later */
    2577               tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
    2578             next();
     3321              tok_alloc((char*)astr.data, astr.size-1)->tok;
    25793322            skip(')');
     3323            cstr_free(&astr);
     3324            break;
     3325        case TOK_VISIBILITY1:
     3326        case TOK_VISIBILITY2:
     3327            skip('(');
     3328            parse_mult_str(&astr,
     3329                           "visibility(\"default|hidden|internal|protected\")");
     3330            if (!strcmp (astr.data, "default"))
     3331                ad->a.visibility = STV_DEFAULT;
     3332            else if (!strcmp (astr.data, "hidden"))
     3333                ad->a.visibility = STV_HIDDEN;
     3334            else if (!strcmp (astr.data, "internal"))
     3335                ad->a.visibility = STV_INTERNAL;
     3336            else if (!strcmp (astr.data, "protected"))
     3337                ad->a.visibility = STV_PROTECTED;
     3338            else
     3339                expect("visibility(\"default|hidden|internal|protected\")");
     3340            skip(')');
     3341            cstr_free(&astr);
    25803342            break;
    25813343        case TOK_ALIGNED1:
     
    25903352                n = MAX_ALIGN;
    25913353            }
    2592             ad->aligned = n;
     3354            ad->a.aligned = exact_log2p1(n);
     3355            if (n != 1 << (ad->a.aligned - 1))
     3356              tcc_error("alignment of %d is larger than implemented", n);
    25933357            break;
    25943358        case TOK_PACKED1:
    25953359        case TOK_PACKED2:
    2596             ad->packed = 1;
     3360            ad->a.packed = 1;
    25973361            break;
    25983362        case TOK_WEAK1:
    25993363        case TOK_WEAK2:
    2600             ad->weak = 1;
     3364            ad->a.weak = 1;
    26013365            break;
    26023366        case TOK_UNUSED1:
     
    26133377        case TOK_CDECL2:
    26143378        case TOK_CDECL3:
    2615             ad->func_call = FUNC_CDECL;
     3379            ad->f.func_call = FUNC_CDECL;
    26163380            break;
    26173381        case TOK_STDCALL1:
    26183382        case TOK_STDCALL2:
    26193383        case TOK_STDCALL3:
    2620             ad->func_call = FUNC_STDCALL;
     3384            ad->f.func_call = FUNC_STDCALL;
    26213385            break;
    26223386#ifdef TCC_TARGET_I386
     
    26303394                n = 0;
    26313395            if (n > 0)
    2632                 ad->func_call = FUNC_FASTCALL1 + n - 1;
     3396                ad->f.func_call = FUNC_FASTCALL1 + n - 1;
    26333397            skip(')');
    26343398            break;
     
    26363400        case TOK_FASTCALL2:
    26373401        case TOK_FASTCALL3:
    2638             ad->func_call = FUNC_FASTCALLW;
     3402            ad->f.func_call = FUNC_FASTCALLW;
    26393403            break;           
    26403404#endif
     
    26433407            switch(tok) {
    26443408                case TOK_MODE_DI:
    2645                     ad->mode = VT_LLONG + 1;
     3409                    ad->attr_mode = VT_LLONG + 1;
     3410                    break;
     3411                case TOK_MODE_QI:
     3412                    ad->attr_mode = VT_BYTE + 1;
    26463413                    break;
    26473414                case TOK_MODE_HI:
    2648                     ad->mode = VT_SHORT + 1;
     3415                    ad->attr_mode = VT_SHORT + 1;
    26493416                    break;
    26503417                case TOK_MODE_SI:
    2651                     ad->mode = VT_INT + 1;
     3418                case TOK_MODE_word:
     3419                    ad->attr_mode = VT_INT + 1;
    26523420                    break;
    26533421                default:
     
    26593427            break;
    26603428        case TOK_DLLEXPORT:
    2661             ad->func_export = 1;
     3429            ad->a.dllexport = 1;
    26623430            break;
    26633431        case TOK_DLLIMPORT:
    2664             ad->func_import = 1;
     3432            ad->a.dllimport = 1;
    26653433            break;
    26663434        default:
     
    26863454    skip(')');
    26873455    skip(')');
    2688     }
    2689 }
    2690 
    2691 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
     3456    goto redo;
     3457}
     3458
     3459static Sym * find_field (CType *type, int v)
     3460{
     3461    Sym *s = type->ref;
     3462    v |= SYM_FIELD;
     3463    while ((s = s->next) != NULL) {
     3464        if ((s->v & SYM_FIELD) &&
     3465            (s->type.t & VT_BTYPE) == VT_STRUCT &&
     3466            (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
     3467            Sym *ret = find_field (&s->type, v);
     3468            if (ret)
     3469                return ret;
     3470        }
     3471        if (s->v == v)
     3472          break;
     3473    }
     3474    return s;
     3475}
     3476
     3477static void struct_add_offset (Sym *s, int offset)
     3478{
     3479    while ((s = s->next) != NULL) {
     3480        if ((s->v & SYM_FIELD) &&
     3481            (s->type.t & VT_BTYPE) == VT_STRUCT &&
     3482            (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
     3483            struct_add_offset(s->type.ref, offset);
     3484        } else
     3485          s->c += offset;
     3486    }
     3487}
     3488
     3489static void struct_layout(CType *type, AttributeDef *ad)
     3490{
     3491    int size, align, maxalign, offset, c, bit_pos, bit_size;
     3492    int packed, a, bt, prevbt, prev_bit_size;
     3493    int pcc = !tcc_state->ms_bitfields;
     3494    int pragma_pack = *tcc_state->pack_stack_ptr;
     3495    Sym *f;
     3496
     3497    maxalign = 1;
     3498    offset = 0;
     3499    c = 0;
     3500    bit_pos = 0;
     3501    prevbt = VT_STRUCT; /* make it never match */
     3502    prev_bit_size = 0;
     3503
     3504//#define BF_DEBUG
     3505
     3506    for (f = type->ref->next; f; f = f->next) {
     3507        if (f->type.t & VT_BITFIELD)
     3508            bit_size = BIT_SIZE(f->type.t);
     3509        else
     3510            bit_size = -1;
     3511        size = type_size(&f->type, &align);
     3512        a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
     3513        packed = 0;
     3514
     3515        if (pcc && bit_size == 0) {
     3516            /* in pcc mode, packing does not affect zero-width bitfields */
     3517
     3518        } else {
     3519            /* in pcc mode, attribute packed overrides if set. */
     3520            if (pcc && (f->a.packed || ad->a.packed))
     3521                align = packed = 1;
     3522
     3523            /* pragma pack overrides align if lesser and packs bitfields always */
     3524            if (pragma_pack) {
     3525                packed = 1;
     3526                if (pragma_pack < align)
     3527                    align = pragma_pack;
     3528                /* in pcc mode pragma pack also overrides individual align */
     3529                if (pcc && pragma_pack < a)
     3530                    a = 0;
     3531            }
     3532        }
     3533        /* some individual align was specified */
     3534        if (a)
     3535            align = a;
     3536
     3537        if (type->ref->type.t == VT_UNION) {
     3538            if (pcc && bit_size >= 0)
     3539                size = (bit_size + 7) >> 3;
     3540            offset = 0;
     3541            if (size > c)
     3542                c = size;
     3543
     3544        } else if (bit_size < 0) {
     3545            if (pcc)
     3546                c += (bit_pos + 7) >> 3;
     3547            c = (c + align - 1) & -align;
     3548            offset = c;
     3549            if (size > 0)
     3550                c += size;
     3551            bit_pos = 0;
     3552            prevbt = VT_STRUCT;
     3553            prev_bit_size = 0;
     3554
     3555        } else {
     3556            /* A bit-field.  Layout is more complicated.  There are two
     3557               options: PCC (GCC) compatible and MS compatible */
     3558            if (pcc) {
     3559                /* In PCC layout a bit-field is placed adjacent to the
     3560                   preceding bit-fields, except if:
     3561                   - it has zero-width
     3562                   - an individual alignment was given
     3563                   - it would overflow its base type container and
     3564                     there is no packing */
     3565                if (bit_size == 0) {
     3566            new_field:
     3567                    c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
     3568                    bit_pos = 0;
     3569                } else if (f->a.aligned) {
     3570                    goto new_field;
     3571                } else if (!packed) {
     3572                    int a8 = align * 8;
     3573                    int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
     3574                    if (ofs > size / align)
     3575                        goto new_field;
     3576                }
     3577
     3578                /* in pcc mode, long long bitfields have type int if they fit */
     3579                if (size == 8 && bit_size <= 32)
     3580                    f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
     3581
     3582                while (bit_pos >= align * 8)
     3583                    c += align, bit_pos -= align * 8;
     3584                offset = c;
     3585
     3586                /* In PCC layout named bit-fields influence the alignment
     3587                   of the containing struct using the base types alignment,
     3588                   except for packed fields (which here have correct align).  */
     3589                if (f->v & SYM_FIRST_ANOM
     3590                    // && bit_size // ??? gcc on ARM/rpi does that
     3591                    )
     3592                    align = 1;
     3593
     3594            } else {
     3595                bt = f->type.t & VT_BTYPE;
     3596                if ((bit_pos + bit_size > size * 8)
     3597                    || (bit_size > 0) == (bt != prevbt)
     3598                    ) {
     3599                    c = (c + align - 1) & -align;
     3600                    offset = c;
     3601                    bit_pos = 0;
     3602                    /* In MS bitfield mode a bit-field run always uses
     3603                       at least as many bits as the underlying type.
     3604                       To start a new run it's also required that this
     3605                       or the last bit-field had non-zero width.  */
     3606                    if (bit_size || prev_bit_size)
     3607                        c += size;
     3608                }
     3609                /* In MS layout the records alignment is normally
     3610                   influenced by the field, except for a zero-width
     3611                   field at the start of a run (but by further zero-width
     3612                   fields it is again).  */
     3613                if (bit_size == 0 && prevbt != bt)
     3614                    align = 1;
     3615                prevbt = bt;
     3616                prev_bit_size = bit_size;
     3617            }
     3618
     3619            f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
     3620                        | (bit_pos << VT_STRUCT_SHIFT);
     3621            bit_pos += bit_size;
     3622        }
     3623        if (align > maxalign)
     3624            maxalign = align;
     3625
     3626#ifdef BF_DEBUG
     3627        printf("set field %s offset %-2d size %-2d align %-2d",
     3628               get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
     3629        if (f->type.t & VT_BITFIELD) {
     3630            printf(" pos %-2d bits %-2d",
     3631                    BIT_POS(f->type.t),
     3632                    BIT_SIZE(f->type.t)
     3633                    );
     3634        }
     3635        printf("\n");
     3636#endif
     3637
     3638        if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) {
     3639            Sym *ass;
     3640            /* An anonymous struct/union.  Adjust member offsets
     3641               to reflect the real offset of our containing struct.
     3642               Also set the offset of this anon member inside
     3643               the outer struct to be zero.  Via this it
     3644               works when accessing the field offset directly
     3645               (from base object), as well as when recursing
     3646               members in initializer handling.  */
     3647            int v2 = f->type.ref->v;
     3648            if (!(v2 & SYM_FIELD) &&
     3649                (v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
     3650                Sym **pps;
     3651                /* This happens only with MS extensions.  The
     3652                   anon member has a named struct type, so it
     3653                   potentially is shared with other references.
     3654                   We need to unshare members so we can modify
     3655                   them.  */
     3656                ass = f->type.ref;
     3657                f->type.ref = sym_push(anon_sym++ | SYM_FIELD,
     3658                                       &f->type.ref->type, 0,
     3659                                       f->type.ref->c);
     3660                pps = &f->type.ref->next;
     3661                while ((ass = ass->next) != NULL) {
     3662                    *pps = sym_push(ass->v, &ass->type, 0, ass->c);
     3663                    pps = &((*pps)->next);
     3664                }
     3665                *pps = NULL;
     3666            }
     3667            struct_add_offset(f->type.ref, offset);
     3668            f->c = 0;
     3669        } else {
     3670            f->c = offset;
     3671        }
     3672
     3673        f->r = 0;
     3674    }
     3675
     3676    if (pcc)
     3677        c += (bit_pos + 7) >> 3;
     3678
     3679    /* store size and alignment */
     3680    a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
     3681    if (a < maxalign)
     3682        a = maxalign;
     3683    type->ref->r = a;
     3684    if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
     3685        /* can happen if individual align for some member was given.  In
     3686           this case MSVC ignores maxalign when aligning the size */
     3687        a = pragma_pack;
     3688        if (a < bt)
     3689            a = bt;
     3690    }
     3691    c = (c + a - 1) & -a;
     3692    type->ref->c = c;
     3693
     3694#ifdef BF_DEBUG
     3695    printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
     3696#endif
     3697
     3698    /* check whether we can access bitfields by their type */
     3699    for (f = type->ref->next; f; f = f->next) {
     3700        int s, px, cx, c0;
     3701        CType t;
     3702
     3703        if (0 == (f->type.t & VT_BITFIELD))
     3704            continue;
     3705        f->type.ref = f;
     3706        f->auxtype = -1;
     3707        bit_size = BIT_SIZE(f->type.t);
     3708        if (bit_size == 0)
     3709            continue;
     3710        bit_pos = BIT_POS(f->type.t);
     3711        size = type_size(&f->type, &align);
     3712        if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
     3713            continue;
     3714
     3715        /* try to access the field using a different type */
     3716        c0 = -1, s = align = 1;
     3717        for (;;) {
     3718            px = f->c * 8 + bit_pos;
     3719            cx = (px >> 3) & -align;
     3720            px = px - (cx << 3);
     3721            if (c0 == cx)
     3722                break;
     3723            s = (px + bit_size + 7) >> 3;
     3724            if (s > 4) {
     3725                t.t = VT_LLONG;
     3726            } else if (s > 2) {
     3727                t.t = VT_INT;
     3728            } else if (s > 1) {
     3729                t.t = VT_SHORT;
     3730            } else {
     3731                t.t = VT_BYTE;
     3732            }
     3733            s = type_size(&t, &align);
     3734            c0 = cx;
     3735        }
     3736
     3737        if (px + bit_size <= s * 8 && cx + s <= c) {
     3738            /* update offset and bit position */
     3739            f->c = cx;
     3740            bit_pos = px;
     3741            f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
     3742                        | (bit_pos << VT_STRUCT_SHIFT);
     3743            if (s != size)
     3744                f->auxtype = t.t;
     3745#ifdef BF_DEBUG
     3746            printf("FIX field %s offset %-2d size %-2d align %-2d "
     3747                "pos %-2d bits %-2d\n",
     3748                get_tok_str(f->v & ~SYM_FIELD, NULL),
     3749                cx, s, align, px, bit_size);
     3750#endif
     3751        } else {
     3752            /* fall back to load/store single-byte wise */
     3753            f->auxtype = VT_STRUCT;
     3754#ifdef BF_DEBUG
     3755            printf("FIX field %s : load byte-wise\n",
     3756                 get_tok_str(f->v & ~SYM_FIELD, NULL));
     3757#endif
     3758        }
     3759    }
     3760}
     3761
     3762/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
    26923763static void struct_decl(CType *type, int u)
    26933764{
    2694     int a, v, size, align, maxalign, c, offset;
    2695     int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
    2696     Sym *s, *ss, *ass, **ps;
    2697     AttributeDef ad;
     3765    int v, c, size, align, flexible;
     3766    int bit_size, bsize, bt;
     3767    Sym *s, *ss, **ps;
     3768    AttributeDef ad, ad1;
    26983769    CType type1, btype;
    26993770
    2700     a = tok; /* save decl type */
     3771    memset(&ad, 0, sizeof ad);
    27013772    next();
     3773    parse_attribute(&ad);
    27023774    if (tok != '{') {
    27033775        v = tok;
     
    27073779            expect("struct/union/enum name");
    27083780        s = struct_find(v);
    2709         if (s) {
    2710             if (s->type.t != a)
    2711                 tcc_error("invalid type");
    2712             goto do_decl;
     3781        if (s && (s->sym_scope == local_scope || tok != '{')) {
     3782            if (u == s->type.t)
     3783                goto do_decl;
     3784            if (u == VT_ENUM && IS_ENUM(s->type.t))
     3785                goto do_decl;
     3786            tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
    27133787        }
    27143788    } else {
    27153789        v = anon_sym++;
    27163790    }
    2717     type1.t = a;
     3791    /* Record the original enum/struct/union token.  */
     3792    type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
     3793    type1.ref = NULL;
    27183794    /* we put an undefined size for struct/union */
    27193795    s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
    27203796    s->r = 0; /* default alignment is zero as gcc */
    2721     /* put struct/union/enum name in type */
    2722  do_decl:
    2723     type->t = u;
     3797do_decl:
     3798    type->t = s->type.t;
    27243799    type->ref = s;
    2725    
     3800
    27263801    if (tok == '{') {
    27273802        next();
     
    27293804            tcc_error("struct/union/enum already defined");
    27303805        /* cannot be empty */
    2731         c = 0;
    27323806        /* non empty enums are not allowed */
    2733         if (a == TOK_ENUM) {
     3807        ps = &s->next;
     3808        if (u == VT_ENUM) {
     3809            long long ll = 0, pl = 0, nl = 0;
     3810            CType t;
     3811            t.ref = s;
     3812            /* enum symbols have static storage */
     3813            t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
    27343814            for(;;) {
    27353815                v = tok;
    27363816                if (v < TOK_UIDENT)
    27373817                    expect("identifier");
     3818                ss = sym_find(v);
     3819                if (ss && !local_stack)
     3820                    tcc_error("redefinition of enumerator '%s'",
     3821                              get_tok_str(v, NULL));
    27383822                next();
    27393823                if (tok == '=') {
    27403824                    next();
    2741                     c = expr_const();
     3825                    ll = expr_const64();
    27423826                }
    2743                 /* enum symbols have static storage */
    2744                 ss = sym_push(v, &int_type, VT_CONST, c);
    2745                 ss->type.t |= VT_STATIC;
     3827                ss = sym_push(v, &t, VT_CONST, 0);
     3828                ss->enum_val = ll;
     3829                *ps = ss, ps = &ss->next;
     3830                if (ll < nl)
     3831                    nl = ll;
     3832                if (ll > pl)
     3833                    pl = ll;
    27463834                if (tok != ',')
    27473835                    break;
    27483836                next();
    2749                 c++;
     3837                ll++;
    27503838                /* NOTE: we accept a trailing comma */
    27513839                if (tok == '}')
     
    27533841            }
    27543842            skip('}');
     3843            /* set integral type of the enum */
     3844            t.t = VT_INT;
     3845            if (nl >= 0) {
     3846                if (pl != (unsigned)pl)
     3847                    t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
     3848                t.t |= VT_UNSIGNED;
     3849            } else if (pl != (int)pl || nl != (int)nl)
     3850                t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
     3851            s->type.t = type->t = t.t | VT_ENUM;
     3852            s->c = 0;
     3853            /* set type for enum members */
     3854            for (ss = s->next; ss; ss = ss->next) {
     3855                ll = ss->enum_val;
     3856                if (ll == (int)ll) /* default is int if it fits */
     3857                    continue;
     3858                if (t.t & VT_UNSIGNED) {
     3859                    ss->type.t |= VT_UNSIGNED;
     3860                    if (ll == (unsigned)ll)
     3861                        continue;
     3862                }
     3863                ss->type.t = (ss->type.t & ~VT_BTYPE)
     3864                    | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
     3865            }
    27553866        } else {
    2756             maxalign = 1;
    2757             ps = &s->next;
    2758             prevbt = VT_INT;
    2759             bit_pos = 0;
    2760             offset = 0;
     3867            c = 0;
     3868            flexible = 0;
    27613869            while (tok != '}') {
    2762                 parse_btype(&btype, &ad);
     3870                if (!parse_btype(&btype, &ad1)) {
     3871                    skip(';');
     3872                    continue;
     3873                }
    27633874                while (1) {
     3875                    if (flexible)
     3876                        tcc_error("flexible array member '%s' not at the end of struct",
     3877                              get_tok_str(v, NULL));
    27643878                    bit_size = -1;
    27653879                    v = 0;
    27663880                    type1 = btype;
    27673881                    if (tok != ':') {
    2768                         type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
    2769                         if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
    2770                             expect("identifier");
     3882                        if (tok != ';')
     3883                            type_decl(&type1, &ad1, &v, TYPE_DIRECT);
     3884                        if (v == 0) {
     3885                            if ((type1.t & VT_BTYPE) != VT_STRUCT)
     3886                                expect("identifier");
     3887                            else {
     3888                                int v = btype.ref->v;
     3889                                if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
     3890                                    if (tcc_state->ms_extensions == 0)
     3891                                        expect("identifier");
     3892                                }
     3893                            }
     3894                        }
     3895                        if (type_size(&type1, &align) < 0) {
     3896                            if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
     3897                                flexible = 1;
     3898                            else
     3899                                tcc_error("field '%s' has incomplete type",
     3900                                      get_tok_str(v, NULL));
     3901                        }
    27713902                        if ((type1.t & VT_BTYPE) == VT_FUNC ||
    2772                             (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
     3903                            (type1.t & VT_STORAGE))
    27733904                            tcc_error("invalid type for '%s'",
    27743905                                  get_tok_str(v, NULL));
     
    27843915                            tcc_error("zero width for bit-field '%s'",
    27853916                                  get_tok_str(v, NULL));
     3917                        parse_attribute(&ad1);
    27863918                    }
    27873919                    size = type_size(&type1, &align);
    2788                     if (ad.aligned) {
    2789                         if (align < ad.aligned)
    2790                             align = ad.aligned;
    2791                     } else if (ad.packed) {
    2792                         align = 1;
    2793                     } else if (*tcc_state->pack_stack_ptr) {
    2794                         if (align > *tcc_state->pack_stack_ptr)
    2795                             align = *tcc_state->pack_stack_ptr;
    2796                     }
    2797                     lbit_pos = 0;
    27983920                    if (bit_size >= 0) {
    27993921                        bt = type1.t & VT_BTYPE;
     
    28023924                            bt != VT_SHORT &&
    28033925                            bt != VT_BOOL &&
    2804                             bt != VT_ENUM &&
    28053926                            bt != VT_LLONG)
    28063927                            tcc_error("bitfields must have scalar type");
     
    28093930                            tcc_error("width of '%s' exceeds its type",
    28103931                                  get_tok_str(v, NULL));
    2811                         } else if (bit_size == bsize) {
     3932                        } else if (bit_size == bsize
     3933                                    && !ad.a.packed && !ad1.a.packed) {
    28123934                            /* no need for bit fields */
    2813                             bit_pos = 0;
    2814                         } else if (bit_size == 0) {
    2815                             /* XXX: what to do if only padding in a
    2816                                structure ? */
    2817                             /* zero size: means to pad */
    2818                             bit_pos = 0;
     3935                            ;
     3936                        } else if (bit_size == 64) {
     3937                            tcc_error("field width 64 not implemented");
    28193938                        } else {
    2820                             /* we do not have enough room ?
    2821                                did the type change?
    2822                                is it a union? */
    2823                             if ((bit_pos + bit_size) > bsize ||
    2824                                 bt != prevbt || a == TOK_UNION)
    2825                                 bit_pos = 0;
    2826                             lbit_pos = bit_pos;
    2827                             /* XXX: handle LSB first */
    2828                             type1.t |= VT_BITFIELD |
    2829                                 (bit_pos << VT_STRUCT_SHIFT) |
    2830                                 (bit_size << (VT_STRUCT_SHIFT + 6));
    2831                             bit_pos += bit_size;
     3939                            type1.t = (type1.t & ~VT_STRUCT_MASK)
     3940                                | VT_BITFIELD
     3941                                | (bit_size << (VT_STRUCT_SHIFT + 6));
    28323942                        }
    2833                         prevbt = bt;
    2834                     } else {
    2835                         bit_pos = 0;
    28363943                    }
    28373944                    if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
    2838                         /* add new memory data only if starting
    2839                            bit field */
    2840                         if (lbit_pos == 0) {
    2841                             if (a == TOK_STRUCT) {
    2842                                 c = (c + align - 1) & -align;
    2843                                 offset = c;
    2844                                 if (size > 0)
    2845                                     c += size;
    2846                             } else {
    2847                                 offset = 0;
    2848                                 if (size > c)
    2849                                     c = size;
    2850                             }
    2851                             if (align > maxalign)
    2852                                 maxalign = align;
    2853                         }
    2854 #if 0
    2855                         printf("add field %s offset=%d",
    2856                                get_tok_str(v, NULL), offset);
    2857                         if (type1.t & VT_BITFIELD) {
    2858                             printf(" pos=%d size=%d",
    2859                                    (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
    2860                                    (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
    2861                         }
    2862                         printf("\n");
    2863 #endif
     3945                        /* Remember we've seen a real field to check
     3946                           for placement of flexible array member. */
     3947                        c = 1;
    28643948                    }
    2865                     if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
    2866                         ass = type1.ref;
    2867                         while ((ass = ass->next) != NULL) {
    2868                            ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
    2869                            *ps = ss;
    2870                            ps = &ss->next;
    2871                         }
    2872                     } else if (v) {
    2873                         ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
     3949                    /* If member is a struct or bit-field, enforce
     3950                       placing into the struct (as anonymous).  */
     3951                    if (v == 0 &&
     3952                        ((type1.t & VT_BTYPE) == VT_STRUCT ||
     3953                         bit_size >= 0)) {
     3954                        v = anon_sym++;
     3955                    }
     3956                    if (v) {
     3957                        ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
     3958                        ss->a = ad1.a;
    28743959                        *ps = ss;
    28753960                        ps = &ss->next;
     
    28823967            }
    28833968            skip('}');
    2884             /* store size and alignment */
    2885             s->c = (c + maxalign - 1) & -maxalign;
    2886             s->r = maxalign;
    2887         }
    2888     }
     3969            parse_attribute(&ad);
     3970            struct_layout(type, &ad);
     3971        }
     3972    }
     3973}
     3974
     3975static void sym_to_attr(AttributeDef *ad, Sym *s)
     3976{
     3977    if (s->a.aligned && 0 == ad->a.aligned)
     3978        ad->a.aligned = s->a.aligned;
     3979    if (s->f.func_call && 0 == ad->f.func_call)
     3980        ad->f.func_call = s->f.func_call;
     3981    if (s->f.func_type && 0 == ad->f.func_type)
     3982        ad->f.func_type = s->f.func_type;
     3983    if (s->a.packed)
     3984        ad->a.packed = 1;
     3985}
     3986
     3987/* Add type qualifiers to a type. If the type is an array then the qualifiers
     3988   are added to the element type, copied because it could be a typedef. */
     3989static void parse_btype_qualify(CType *type, int qualifiers)
     3990{
     3991    while (type->t & VT_ARRAY) {
     3992        type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
     3993        type = &type->ref->type;
     3994    }
     3995    type->t |= qualifiers;
    28893996}
    28903997
     
    28944001static int parse_btype(CType *type, AttributeDef *ad)
    28954002{
    2896     int t, u, type_found, typespec_found, typedef_found;
     4003    int t, u, bt, st, type_found, typespec_found, g;
    28974004    Sym *s;
    28984005    CType type1;
     
    29014008    type_found = 0;
    29024009    typespec_found = 0;
    2903     typedef_found = 0;
    2904     t = 0;
     4010    t = VT_INT;
     4011    bt = st = -1;
     4012    type->ref = NULL;
     4013
    29054014    while(1) {
    29064015        switch(tok) {
     
    29164025            next();
    29174026        basic_type1:
    2918             if ((t & VT_BTYPE) != 0)
    2919                 tcc_error("too many basic types");
    2920             t |= u;
     4027            if (u == VT_SHORT || u == VT_LONG) {
     4028                if (st != -1 || (bt != -1 && bt != VT_INT))
     4029                    tmbt: tcc_error("too many basic types");
     4030                st = u;
     4031            } else {
     4032                if (bt != -1 || (st != -1 && u != VT_INT))
     4033                    goto tmbt;
     4034                bt = u;
     4035            }
     4036            if (u != VT_INT)
     4037                t = (t & ~(VT_BTYPE|VT_LONG)) | u;
    29214038            typespec_found = 1;
    29224039            break;
     
    29284045            goto basic_type;
    29294046        case TOK_INT:
    2930             next();
    2931             typespec_found = 1;
    2932             break;
     4047            u = VT_INT;
     4048            goto basic_type;
    29334049        case TOK_LONG:
    2934             next();
    29354050            if ((t & VT_BTYPE) == VT_DOUBLE) {
    2936 #ifndef TCC_TARGET_PE
    2937                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
    2938 #endif
    2939             } else if ((t & VT_BTYPE) == VT_LONG) {
    2940                 t = (t & ~VT_BTYPE) | VT_LLONG;
     4051                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
     4052            } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
     4053                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
    29414054            } else {
    29424055                u = VT_LONG;
    2943                 goto basic_type1;
    2944             }
     4056                goto basic_type;
     4057            }
     4058            next();
    29454059            break;
     4060#ifdef TCC_TARGET_ARM64
     4061        case TOK_UINT128:
     4062            /* GCC's __uint128_t appears in some Linux header files. Make it a
     4063               synonym for long double to get the size and alignment right. */
     4064            u = VT_LDOUBLE;
     4065            goto basic_type;
     4066#endif
    29464067        case TOK_BOOL:
    29474068            u = VT_BOOL;
     
    29514072            goto basic_type;
    29524073        case TOK_DOUBLE:
    2953             next();
    2954             if ((t & VT_BTYPE) == VT_LONG) {
    2955 #ifdef TCC_TARGET_PE
    2956                 t = (t & ~VT_BTYPE) | VT_DOUBLE;
    2957 #else
    2958                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
    2959 #endif
     4074            if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
     4075                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
    29604076            } else {
    29614077                u = VT_DOUBLE;
    2962                 goto basic_type1;
    2963             }
     4078                goto basic_type;
     4079            }
     4080            next();
    29644081            break;
    29654082        case TOK_ENUM:
     
    29704087            goto basic_type1;
    29714088        case TOK_STRUCT:
     4089            struct_decl(&type1, VT_STRUCT);
     4090            goto basic_type2;
    29724091        case TOK_UNION:
    2973             struct_decl(&type1, VT_STRUCT);
     4092            struct_decl(&type1, VT_UNION);
    29744093            goto basic_type2;
    29754094
     
    29784097        case TOK_CONST2:
    29794098        case TOK_CONST3:
    2980             t |= VT_CONSTANT;
     4099            type->t = t;
     4100            parse_btype_qualify(type, VT_CONSTANT);
     4101            t = type->t;
    29814102            next();
    29824103            break;
     
    29844105        case TOK_VOLATILE2:
    29854106        case TOK_VOLATILE3:
    2986             t |= VT_VOLATILE;
     4107            type->t = t;
     4108            parse_btype_qualify(type, VT_VOLATILE);
     4109            t = type->t;
    29874110            next();
    29884111            break;
     
    29904113        case TOK_SIGNED2:
    29914114        case TOK_SIGNED3:
     4115            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
     4116                tcc_error("signed and unsigned modifier");
     4117            t |= VT_DEFSIGN;
     4118            next();
    29924119            typespec_found = 1;
    2993             t |= VT_SIGNED;
    2994             next();
    29954120            break;
    29964121        case TOK_REGISTER:
     
    30024127            break;
    30034128        case TOK_UNSIGNED:
    3004             t |= VT_UNSIGNED;
     4129            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
     4130                tcc_error("signed and unsigned modifier");
     4131            t |= VT_DEFSIGN | VT_UNSIGNED;
    30054132            next();
    30064133            typespec_found = 1;
     
    30094136            /* storage */
    30104137        case TOK_EXTERN:
    3011             t |= VT_EXTERN;
    3012             next();
    3013             break;
     4138            g = VT_EXTERN;
     4139            goto storage;
    30144140        case TOK_STATIC:
    3015             t |= VT_STATIC;
    3016             next();
    3017             break;
     4141            g = VT_STATIC;
     4142            goto storage;
    30184143        case TOK_TYPEDEF:
    3019             t |= VT_TYPEDEF;
     4144            g = VT_TYPEDEF;
     4145            goto storage;
     4146       storage:
     4147            if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
     4148                tcc_error("multiple storage classes");
     4149            t |= g;
    30204150            next();
    30214151            break;
     
    30314161        case TOK_ATTRIBUTE2:
    30324162            parse_attribute(ad);
    3033             if (ad->mode) {
    3034                 u = ad->mode -1;
    3035                 t = (t & ~VT_BTYPE) | u;
     4163            if (ad->attr_mode) {
     4164                u = ad->attr_mode -1;
     4165                t = (t & ~(VT_BTYPE|VT_LONG)) | u;
    30364166            }
    30374167            break;
     
    30444174            /* remove all storage modifiers except typedef */
    30454175            type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
     4176            if (type1.ref)
     4177                sym_to_attr(ad, type1.ref);
    30464178            goto basic_type2;
    30474179        default:
    3048             if (typespec_found || typedef_found)
     4180            if (typespec_found)
    30494181                goto the_end;
    30504182            s = sym_find(tok);
    30514183            if (!s || !(s->type.t & VT_TYPEDEF))
    30524184                goto the_end;
    3053             typedef_found = 1;
    3054             t |= (s->type.t & ~VT_TYPEDEF);
     4185            t &= ~(VT_BTYPE|VT_LONG);
     4186            u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
     4187            type->t = (s->type.t & ~VT_TYPEDEF) | u;
    30554188            type->ref = s->type.ref;
    3056             if (s->r) {
    3057                 /* get attributes from typedef */
    3058                 if (0 == ad->aligned)
    3059                     ad->aligned = FUNC_ALIGN(s->r);
    3060                 if (0 == ad->func_call)
    3061                     ad->func_call = FUNC_CALL(s->r);
    3062                 ad->packed |= FUNC_PACKED(s->r);
    3063             }
     4189            if (t)
     4190                parse_btype_qualify(type, t);
     4191            t = type->t;
     4192            /* get attributes from typedef */
     4193            sym_to_attr(ad, s);
    30644194            next();
    30654195            typespec_found = 1;
     4196            st = bt = -2;
    30664197            break;
    30674198        }
     
    30694200    }
    30704201the_end:
    3071     if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
    3072         tcc_error("signed and unsigned modifier");
    30734202    if (tcc_state->char_is_unsigned) {
    3074         if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
     4203        if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
    30754204            t |= VT_UNSIGNED;
    30764205    }
    3077     t &= ~VT_SIGNED;
    3078 
    3079     /* long is never used as type */
    3080     if ((t & VT_BTYPE) == VT_LONG)
    3081 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
    3082         t = (t & ~VT_BTYPE) | VT_INT;
    3083 #else
    3084         t = (t & ~VT_BTYPE) | VT_LLONG;
     4206    /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
     4207    bt = t & (VT_BTYPE|VT_LONG);
     4208    if (bt == VT_LONG)
     4209        t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
     4210#ifdef TCC_TARGET_PE
     4211    if (bt == VT_LDOUBLE)
     4212        t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
    30854213#endif
    30864214    type->t = t;
     
    31054233{
    31064234    skip('(');
    3107     /* read the string */
    3108     if (tok != TOK_STR)
    3109         expect("string constant");
    3110     cstr_new(astr);
    3111     while (tok == TOK_STR) {
    3112         /* XXX: add \0 handling too ? */
    3113         cstr_cat(astr, tokc.cstr->data);
    3114         next();
    3115     }
    3116     cstr_ccat(astr, '\0');
    3117 }
    3118 
    3119 /* Parse an asm label and return the label
    3120  * Don't forget to free the CString in the caller! */
    3121 static void asm_label_instr(CString *astr)
    3122 {
     4235    parse_mult_str(astr, "string constant");
     4236}
     4237
     4238/* Parse an asm label and return the token */
     4239static int asm_label_instr(void)
     4240{
     4241    int v;
     4242    CString astr;
     4243
    31234244    next();
    3124     parse_asm_str(astr);
     4245    parse_asm_str(&astr);
    31254246    skip(')');
    31264247#ifdef ASM_DEBUG
    3127     printf("asm_alias: \"%s\"\n", (char *)astr->data);
    3128 #endif
    3129 }
    3130 
    3131 static void post_type(CType *type, AttributeDef *ad)
     4248    printf("asm_alias: \"%s\"\n", (char *)astr.data);
     4249#endif
     4250    v = tok_alloc(astr.data, astr.size - 1)->tok;
     4251    cstr_free(&astr);
     4252    return v;
     4253}
     4254
     4255static int post_type(CType *type, AttributeDef *ad, int storage, int td)
    31324256{
    31334257    int n, l, t1, arg_size, align;
     
    31374261
    31384262    if (tok == '(') {
    3139         /* function declaration */
     4263        /* function type, or recursive declarator (return if so) */
    31404264        next();
    3141         l = 0;
     4265        if (td && !(td & TYPE_ABSTRACT))
     4266          return 0;
     4267        if (tok == ')')
     4268          l = 0;
     4269        else if (parse_btype(&pt, &ad1))
     4270          l = FUNC_NEW;
     4271        else if (td)
     4272          return 0;
     4273        else
     4274          l = FUNC_OLD;
    31424275        first = NULL;
    31434276        plast = &first;
    31444277        arg_size = 0;
    3145         if (tok != ')') {
     4278        if (l) {
    31464279            for(;;) {
    31474280                /* read param name and compute offset */
    31484281                if (l != FUNC_OLD) {
    3149                     if (!parse_btype(&pt, &ad1)) {
    3150                         if (l) {
    3151                             tcc_error("invalid type");
    3152                         } else {
    3153                             l = FUNC_OLD;
    3154                             goto old_proto;
    3155                         }
    3156                     }
    3157                     l = FUNC_NEW;
    31584282                    if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
    31594283                        break;
     
    31634287                    arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
    31644288                } else {
    3165                 old_proto:
    31664289                    n = tok;
    31674290                    if (n < TOK_UIDENT)
    31684291                        expect("identifier");
    3169                     pt.t = VT_INT;
     4292                    pt.t = VT_VOID; /* invalid type */
    31704293                    next();
    31714294                }
     
    31824305                    break;
    31834306                }
    3184             }
    3185         }
    3186         /* if no parameters, then old type prototype */
    3187         if (l == 0)
     4307                if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
     4308                    tcc_error("invalid type");
     4309            }
     4310        } else
     4311            /* if no parameters, then old type prototype */
    31884312            l = FUNC_OLD;
    31894313        skip(')');
     
    31974321            next();
    31984322            skip(']'); /* only handle simple "[]" */
    3199             type->t |= VT_PTR;
     4323            mk_pointer(type);
    32004324        }
    32014325        /* we push a anonymous symbol which will contain the function prototype */
    3202         ad->func_args = arg_size;
    3203         s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
     4326        ad->f.func_args = arg_size;
     4327        ad->f.func_type = l;
     4328        s = sym_push(SYM_FIELD, type, 0, 0);
     4329        s->a = ad->a;
     4330        s->f = ad->f;
    32044331        s->next = first;
    32054332        type->t = VT_FUNC;
    32064333        type->ref = s;
    32074334    } else if (tok == '[') {
     4335        int saved_nocode_wanted = nocode_wanted;
    32084336        /* array definition */
    32094337        next();
     
    32134341        t1 = 0;
    32144342        if (tok != ']') {
    3215             if (!local_stack || nocode_wanted)
    3216                  vpushi(expr_const());
    3217             else gexpr();
     4343            if (!local_stack || (storage & VT_STATIC))
     4344                vpushi(expr_const());
     4345            else {
     4346                /* VLAs (which can only happen with local_stack && !VT_STATIC)
     4347                   length must always be evaluated, even under nocode_wanted,
     4348                   so that its size slot is initialized (e.g. under sizeof
     4349                   or typeof).  */
     4350                nocode_wanted = 0;
     4351                gexpr();
     4352            }
    32184353            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    32194354                n = vtop->c.i;
     
    32284363        skip(']');
    32294364        /* parse next post type */
    3230         post_type(type, ad);
     4365        post_type(type, ad, storage, 0);
     4366        if (type->t == VT_FUNC)
     4367            tcc_error("declaration of an array of functions");
    32314368        t1 |= type->t & VT_VLA;
    32324369       
     
    32384375            vla_runtime_type_size(type, &align);
    32394376            gen_op('*');
    3240             vset(&int_type, VT_LOCAL|VT_LVAL, loc);
     4377            vset(&int_type, VT_LOCAL|VT_LVAL, n);
    32414378            vswap();
    32424379            vstore();
     
    32444381        if (n != -1)
    32454382            vpop();
     4383        nocode_wanted = saved_nocode_wanted;
    32464384               
    32474385        /* we push an anonymous symbol which will contain the array
     
    32514389        type->ref = s;
    32524390    }
    3253 }
    3254 
    3255 /* Parse a type declaration (except basic type), and return the type
     4391    return 1;
     4392}
     4393
     4394/* Parse a type declarator (except basic type), and return the type
    32564395   in 'type'. 'td' is a bitmask indicating which kind of type decl is
    32574396   expected. 'type' should contain the basic type. 'ad' is the
    32584397   attribute definition of the basic type. It can be modified by
    3259    type_decl().
    3260  */
    3261 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
    3262 {
    3263     Sym *s;
    3264     CType type1, *type2;
     4398   type_decl().  If this (possibly abstract) declarator is a pointer chain
     4399   it returns the innermost pointed to type (equals *type, but is a different
     4400   pointer), otherwise returns type itself, that's used for recursive calls.  */
     4401static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
     4402{
     4403    CType *post, *ret;
    32654404    int qualifiers, storage;
     4405
     4406    /* recursive type, remove storage bits first, apply them later again */
     4407    storage = type->t & VT_STORAGE;
     4408    type->t &= ~VT_STORAGE;
     4409    post = ret = type;
    32664410
    32674411    while (tok == '*') {
     
    32844428        case TOK_RESTRICT3:
    32854429            goto redo;
     4430        /* XXX: clarify attribute handling */
     4431        case TOK_ATTRIBUTE1:
     4432        case TOK_ATTRIBUTE2:
     4433            parse_attribute(ad);
     4434            break;
    32864435        }
    32874436        mk_pointer(type);
    32884437        type->t |= qualifiers;
    3289     }
    3290    
    3291     /* XXX: clarify attribute handling */
    3292     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
    3293         parse_attribute(ad);
    3294 
    3295     /* recursive type */
    3296     /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
    3297     type1.t = 0; /* XXX: same as int */
     4438        if (ret == type)
     4439            /* innermost pointed to type is the one for the first derivation */
     4440            ret = pointed_type(type);
     4441    }
     4442
    32984443    if (tok == '(') {
    3299         next();
    3300         /* XXX: this is not correct to modify 'ad' at this point, but
    3301            the syntax is not clear */
    3302         if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
    3303             parse_attribute(ad);
    3304         type_decl(&type1, ad, v, td);
    3305         skip(')');
     4444        /* This is possibly a parameter type list for abstract declarators
     4445           ('int ()'), use post_type for testing this.  */
     4446        if (!post_type(type, ad, 0, td)) {
     4447            /* It's not, so it's a nested declarator, and the post operations
     4448               apply to the innermost pointed to type (if any).  */
     4449            /* XXX: this is not correct to modify 'ad' at this point, but
     4450               the syntax is not clear */
     4451            parse_attribute(ad);
     4452            post = type_decl(type, ad, v, td);
     4453            skip(')');
     4454        }
     4455    } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
     4456        /* type identifier */
     4457        *v = tok;
     4458        next();
    33064459    } else {
    3307         /* type identifier */
    3308         if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
    3309             *v = tok;
    3310             next();
    3311         } else {
    3312             if (!(td & TYPE_ABSTRACT))
    3313                 expect("identifier");
    3314             *v = 0;
    3315         }
    3316     }
    3317     storage = type->t & VT_STORAGE;
    3318     type->t &= ~VT_STORAGE;
    3319     if (storage & VT_STATIC) {
    3320         int saved_nocode_wanted = nocode_wanted;
    3321         nocode_wanted = 1;
    3322         post_type(type, ad);
    3323         nocode_wanted = saved_nocode_wanted;
    3324     } else
    3325         post_type(type, ad);
     4460        if (!(td & TYPE_ABSTRACT))
     4461          expect("identifier");
     4462        *v = 0;
     4463    }
     4464    post_type(post, ad, storage, 0);
     4465    parse_attribute(ad);
    33264466    type->t |= storage;
    3327     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
    3328         parse_attribute(ad);
    3329    
    3330     if (!type1.t)
    3331         return;
    3332     /* append type at the end of type1 */
    3333     type2 = &type1;
    3334     for(;;) {
    3335         s = type2->ref;
    3336         type2 = &s->type;
    3337         if (!type2->t) {
    3338             *type2 = *type;
    3339             break;
    3340         }
    3341     }
    3342     *type = type1;
     4467    return ret;
    33434468}
    33444469
     
    33684493        expect("pointer");
    33694494    }
    3370     if ((vtop->r & VT_LVAL) && !nocode_wanted)
     4495    if (vtop->r & VT_LVAL)
    33714496        gv(RC_INT);
    33724497    vtop->type = *pointed_type(&vtop->type);
     
    33894514    CType type;
    33904515
    3391     func_type = func->c;
     4516    func_type = func->f.func_type;
    33924517    if (func_type == FUNC_OLD ||
    33934518        (func_type == FUNC_ELLIPSIS && arg == NULL)) {
    33944519        /* default casting : only need to convert float to double */
    33954520        if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
    3396             type.t = VT_DOUBLE;
     4521            gen_cast_s(VT_DOUBLE);
     4522        } else if (vtop->type.t & VT_BITFIELD) {
     4523            type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
     4524            type.ref = vtop->type.ref;
    33974525            gen_cast(&type);
    33984526        }
     
    34064534}
    34074535
     4536/* parse an expression and return its type without any side effect. */
     4537static void expr_type(CType *type, void (*expr_fn)(void))
     4538{
     4539    nocode_wanted++;
     4540    expr_fn();
     4541    *type = vtop->type;
     4542    vpop();
     4543    nocode_wanted--;
     4544}
     4545
    34084546/* parse an expression of the form '(type)' or '(expr)' and return its
    34094547   type */
     
    34174555        type_decl(type, &ad, &n, TYPE_ABSTRACT);
    34184556    } else {
    3419         expr_type(type);
     4557        expr_type(type, gexpr);
    34204558    }
    34214559    skip(')');
     
    34334571}
    34344572
    3435 static void vpush_tokc(int t)
    3436 {
    3437     CType type;
    3438     type.t = t;
    3439     type.ref = 0;
    3440     vsetc(&type, VT_CONST, &tokc);
     4573static void parse_builtin_params(int nc, const char *args)
     4574{
     4575    char c, sep = '(';
     4576    CType t;
     4577    if (nc)
     4578        nocode_wanted++;
     4579    next();
     4580    while ((c = *args++)) {
     4581        skip(sep);
     4582        sep = ',';
     4583        switch (c) {
     4584            case 'e': expr_eq(); continue;
     4585            case 't': parse_type(&t); vpush(&t); continue;
     4586            default: tcc_error("internal error"); break;
     4587        }
     4588    }
     4589    skip(')');
     4590    if (nc)
     4591        nocode_wanted--;
    34414592}
    34424593
     
    34474598    Sym *s;
    34484599    AttributeDef ad;
    3449     static int in_sizeof = 0;
    34504600
    34514601    sizeof_caller = in_sizeof;
    34524602    in_sizeof = 0;
     4603    type.ref = NULL;
    34534604    /* XXX: GCC 2.95.3 does not generate a table although it should be
    34544605       better here */
     
    34584609        next();
    34594610        goto tok_next;
     4611    case TOK_LCHAR:
     4612#ifdef TCC_TARGET_PE
     4613        t = VT_SHORT|VT_UNSIGNED;
     4614        goto push_tokc;
     4615#endif
    34604616    case TOK_CINT:
    34614617    case TOK_CCHAR:
    3462     case TOK_LCHAR:
    3463         vpushi(tokc.i);
     4618        t = VT_INT;
     4619 push_tokc:
     4620        type.t = t;
     4621        vsetc(&type, VT_CONST, &tokc);
    34644622        next();
    34654623        break;
    34664624    case TOK_CUINT:
    3467         vpush_tokc(VT_INT | VT_UNSIGNED);
    3468         next();
    3469         break;
     4625        t = VT_INT | VT_UNSIGNED;
     4626        goto push_tokc;
    34704627    case TOK_CLLONG:
    3471         vpush_tokc(VT_LLONG);
    3472         next();
    3473         break;
     4628        t = VT_LLONG;
     4629        goto push_tokc;
    34744630    case TOK_CULLONG:
    3475         vpush_tokc(VT_LLONG | VT_UNSIGNED);
    3476         next();
    3477         break;
     4631        t = VT_LLONG | VT_UNSIGNED;
     4632        goto push_tokc;
    34784633    case TOK_CFLOAT:
    3479         vpush_tokc(VT_FLOAT);
    3480         next();
    3481         break;
     4634        t = VT_FLOAT;
     4635        goto push_tokc;
    34824636    case TOK_CDOUBLE:
    3483         vpush_tokc(VT_DOUBLE);
    3484         next();
    3485         break;
     4637        t = VT_DOUBLE;
     4638        goto push_tokc;
    34864639    case TOK_CLDOUBLE:
    3487         vpush_tokc(VT_LDOUBLE);
    3488         next();
    3489         break;
     4640        t = VT_LDOUBLE;
     4641        goto push_tokc;
     4642    case TOK_CLONG:
     4643        t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
     4644        goto push_tokc;
     4645    case TOK_CULONG:
     4646        t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
     4647        goto push_tokc;
    34904648    case TOK___FUNCTION__:
    34914649        if (!gnu_ext)
     
    35044662            type.ref->c = len;
    35054663            vpush_ref(&type, data_section, data_section->data_offset, len);
    3506             ptr = section_ptr_add(data_section, len);
    3507             memcpy(ptr, funcname, len);
     4664            if (!NODATA_WANTED) {
     4665                ptr = section_ptr_add(data_section, len);
     4666                memcpy(ptr, funcname, len);
     4667            }
    35084668            next();
    35094669        }
     
    35194679        /* string parsing */
    35204680        t = VT_BYTE;
     4681        if (tcc_state->char_is_unsigned)
     4682            t = VT_BYTE | VT_UNSIGNED;
    35214683    str_init:
    35224684        if (tcc_state->warn_write_strings)
     
    35264688        type.t |= VT_ARRAY;
    35274689        memset(&ad, 0, sizeof(AttributeDef));
    3528         decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
     4690        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
    35294691        break;
    35304692    case '(':
     
    35454707                    r |= lvalue_type(type.t);
    35464708                memset(&ad, 0, sizeof(AttributeDef));
    3547                 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
     4709                decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
    35484710            } else {
    35494711                if (sizeof_caller) {
     
    35554717            }
    35564718        } else if (tok == '{') {
     4719            int saved_nocode_wanted = nocode_wanted;
     4720            if (const_wanted)
     4721                tcc_error("expected constant");
    35574722            /* save all registers */
    3558             save_regs(0); 
     4723            save_regs(0);
    35594724            /* statement expression : we do not accept break/continue
    3560                inside as GCC does */
    3561             block(NULL, NULL, NULL, NULL, 0, 1);
     4725               inside as GCC does.  We do retain the nocode_wanted state,
     4726               as statement expressions can't ever be entered from the
     4727               outside, so any reactivation of code emission (from labels
     4728               or loop heads) can be disabled again after the end of it. */
     4729            block(NULL, NULL, 1);
     4730            nocode_wanted = saved_nocode_wanted;
    35624731            skip(')');
    35634732        } else {
     
    35804749        /* arrays can also be used although they are not lvalues */
    35814750        if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
    3582             !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
     4751            !(vtop->type.t & VT_ARRAY))
    35834752            test_lvalue();
    35844753        mk_pointer(&vtop->type);
     
    35894758        unary();
    35904759        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    3591             CType boolean;
    3592             boolean.t = VT_BOOL;
    3593             gen_cast(&boolean);
     4760            gen_cast_s(VT_BOOL);
    35944761            vtop->c.i = !vtop->c.i;
    35954762        } else if ((vtop->r & VT_VALMASK) == VT_CMP)
    3596             vtop->c.i = vtop->c.i ^ 1;
     4763            vtop->c.i ^= 1;
    35974764        else {
    35984765            save_regs(1);
    3599             vseti(VT_JMP, gtst(1, 0));
     4766            vseti(VT_JMP, gvtst(1, 0));
    36004767        }
    36014768        break;
     
    36084775    case '+':
    36094776        next();
    3610         /* in order to force cast, we add zero */
    36114777        unary();
    36124778        if ((vtop->type.t & VT_BTYPE) == VT_PTR)
    36134779            tcc_error("pointer not accepted for unary plus");
    3614         vpushi(0);
    3615         gen_op('+');
     4780        /* In order to force cast, we add zero, except for floating point
     4781           where we really need an noop (otherwise -0.0 will be transformed
     4782           into +0.0).  */
     4783        if (!is_float(vtop->type.t)) {
     4784            vpushi(0);
     4785            gen_op('+');
     4786        }
    36164787        break;
    36174788    case TOK_SIZEOF:
     
    36214792        next();
    36224793        in_sizeof++;
    3623         unary_type(&type); // Perform a in_sizeof = 0;
     4794        expr_type(&type, unary); /* Perform a in_sizeof = 0; */
     4795        s = vtop[1].sym; /* hack: accessing previous vtop */
    36244796        size = type_size(&type, &align);
     4797        if (s && s->a.aligned)
     4798            align = 1 << (s->a.aligned - 1);
    36254799        if (t == TOK_SIZEOF) {
    36264800            if (!(type.t & VT_VLA)) {
     
    36374811        break;
    36384812
     4813    case TOK_builtin_expect:
     4814        /* __builtin_expect is a no-op for now */
     4815        parse_builtin_params(0, "ee");
     4816        vpop();
     4817        break;
    36394818    case TOK_builtin_types_compatible_p:
     4819        parse_builtin_params(0, "tt");
     4820        vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
     4821        vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
     4822        n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
     4823        vtop -= 2;
     4824        vpushi(n);
     4825        break;
     4826    case TOK_builtin_choose_expr:
     4827        {
     4828            int64_t c;
     4829            next();
     4830            skip('(');
     4831            c = expr_const64();
     4832            skip(',');
     4833            if (!c) {
     4834                nocode_wanted++;
     4835            }
     4836            expr_eq();
     4837            if (!c) {
     4838                vpop();
     4839                nocode_wanted--;
     4840            }
     4841            skip(',');
     4842            if (c) {
     4843                nocode_wanted++;
     4844            }
     4845            expr_eq();
     4846            if (c) {
     4847                vpop();
     4848                nocode_wanted--;
     4849            }
     4850            skip(')');
     4851        }
     4852        break;
     4853    case TOK_builtin_constant_p:
     4854        parse_builtin_params(1, "e");
     4855        n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     4856        vtop--;
     4857        vpushi(n);
     4858        break;
     4859    case TOK_builtin_frame_address:
     4860    case TOK_builtin_return_address:
    36404861        {
    3641             CType type1, type2;
     4862            int tok1 = tok;
     4863            int level;
    36424864            next();
    36434865            skip('(');
    3644             parse_type(&type1);
    3645             skip(',');
    3646             parse_type(&type2);
    3647             skip(')');
    3648             type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
    3649             type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
    3650             vpushi(is_compatible_types(&type1, &type2));
    3651         }
    3652         break;
    3653     case TOK_builtin_constant_p:
    3654         {
    3655             int saved_nocode_wanted, res;
    3656             next();
    3657             skip('(');
    3658             saved_nocode_wanted = nocode_wanted;
    3659             nocode_wanted = 1;
    3660             gexpr();
    3661             res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    3662             vpop();
    3663             nocode_wanted = saved_nocode_wanted;
    3664             skip(')');
    3665             vpushi(res);
    3666         }
    3667         break;
    3668     case TOK_builtin_frame_address:
    3669         {
    3670             int level;
    3671             CType type;
    3672             next();
    3673             skip('(');
    3674             if (tok != TOK_CINT || tokc.i < 0) {
    3675                 tcc_error("__builtin_frame_address only takes positive integers");
    3676             }
    3677             level = tokc.i;
     4866            if (tok != TOK_CINT) {
     4867                tcc_error("%s only takes positive integers",
     4868                          tok1 == TOK_builtin_return_address ?
     4869                          "__builtin_return_address" :
     4870                          "__builtin_frame_address");
     4871            }
     4872            level = (uint32_t)tokc.i;
    36784873            next();
    36794874            skip(')');
     
    36854880                indir();                    /* -> parent frame */
    36864881            }
     4882            if (tok1 == TOK_builtin_return_address) {
     4883                // assume return address is just above frame pointer on stack
     4884                vpushi(PTR_SIZE);
     4885                gen_op('+');
     4886                mk_pointer(&vtop->type);
     4887                indir();
     4888            }
    36874889        }
    36884890        break;
    36894891#ifdef TCC_TARGET_X86_64
     4892#ifdef TCC_TARGET_PE
     4893    case TOK_builtin_va_start:
     4894        parse_builtin_params(0, "ee");
     4895        r = vtop->r & VT_VALMASK;
     4896        if (r == VT_LLOCAL)
     4897            r = VT_LOCAL;
     4898        if (r != VT_LOCAL)
     4899            tcc_error("__builtin_va_start expects a local variable");
     4900        vtop->r = r;
     4901        vtop->type = char_pointer_type;
     4902        vtop->c.i += 8;
     4903        vstore();
     4904        break;
     4905#else
    36904906    case TOK_builtin_va_arg_types:
    3691         {
    3692             /* This definition must be synced with stdarg.h */
    3693             enum __va_arg_type {
    3694                 __va_gen_reg, __va_float_reg, __va_stack
    3695             };
    3696             CType type;
    3697             int bt;
    3698             next();
    3699             skip('(');
    3700             parse_type(&type);
    3701             skip(')');
    3702             bt = type.t & VT_BTYPE;
    3703             if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
    3704                 vpushi(__va_stack);
    3705             } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
    3706                 vpushi(__va_float_reg);
    3707             } else {
    3708                 vpushi(__va_gen_reg);
    3709             }
    3710         }
     4907        parse_builtin_params(0, "t");
     4908        vpushi(classify_x86_64_va_arg(&vtop->type));
     4909        vswap();
     4910        vpop();
    37114911        break;
    37124912#endif
     4913#endif
     4914
     4915#ifdef TCC_TARGET_ARM64
     4916    case TOK___va_start: {
     4917        parse_builtin_params(0, "ee");
     4918        //xx check types
     4919        gen_va_start();
     4920        vpushi(0);
     4921        vtop->type.t = VT_VOID;
     4922        break;
     4923    }
     4924    case TOK___va_arg: {
     4925        parse_builtin_params(0, "et");
     4926        type = vtop->type;
     4927        vpop();
     4928        //xx check types
     4929        gen_va_arg(&type);
     4930        vtop->type = type;
     4931        break;
     4932    }
     4933    case TOK___arm64_clear_cache: {
     4934        parse_builtin_params(0, "ee");
     4935        gen_clear_cache();
     4936        vpushi(0);
     4937        vtop->type.t = VT_VOID;
     4938        break;
     4939    }
     4940#endif
     4941    /* pre operations */
    37134942    case TOK_INC:
    37144943    case TOK_DEC:
     
    37204949    case '-':
    37214950        next();
    3722         vpushi(0);
    37234951        unary();
    3724         gen_op('-');
     4952        t = vtop->type.t & VT_BTYPE;
     4953        if (is_float(t)) {
     4954            /* In IEEE negate(x) isn't subtract(0,x), but rather
     4955               subtract(-0, x).  */
     4956            vpush(&vtop->type);
     4957            if (t == VT_FLOAT)
     4958                vtop->c.f = -1.0 * 0.0;
     4959            else if (t == VT_DOUBLE)
     4960                vtop->c.d = -1.0 * 0.0;
     4961            else
     4962                vtop->c.ld = -1.0 * 0.0;
     4963        } else
     4964            vpushi(0);
     4965        vswap();
     4966        gen_op('-');
    37254967        break;
    37264968    case TOK_LAND:
     
    37434985            s->type.t |= VT_STATIC;
    37444986        }
    3745         vset(&s->type, VT_CONST | VT_SYM, 0);
    3746         vtop->sym = s;
     4987        vpushsym(&s->type, s);
    37474988        next();
    37484989        break;
    3749    
     4990
     4991    case TOK_GENERIC:
     4992    {
     4993        CType controlling_type;
     4994        int has_default = 0;
     4995        int has_match = 0;
     4996        int learn = 0;
     4997        TokenString *str = NULL;
     4998
     4999        next();
     5000        skip('(');
     5001        expr_type(&controlling_type, expr_eq);
     5002        controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
     5003        for (;;) {
     5004            learn = 0;
     5005            skip(',');
     5006            if (tok == TOK_DEFAULT) {
     5007                if (has_default)
     5008                    tcc_error("too many 'default'");
     5009                has_default = 1;
     5010                if (!has_match)
     5011                    learn = 1;
     5012                next();
     5013            } else {
     5014                AttributeDef ad_tmp;
     5015                int itmp;
     5016                CType cur_type;
     5017                parse_btype(&cur_type, &ad_tmp);
     5018                type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
     5019                if (compare_types(&controlling_type, &cur_type, 0)) {
     5020                    if (has_match) {
     5021                      tcc_error("type match twice");
     5022                    }
     5023                    has_match = 1;
     5024                    learn = 1;
     5025                }
     5026            }
     5027            skip(':');
     5028            if (learn) {
     5029                if (str)
     5030                    tok_str_free(str);
     5031                skip_or_save_block(&str);
     5032            } else {
     5033                skip_or_save_block(NULL);
     5034            }
     5035            if (tok == ')')
     5036                break;
     5037        }
     5038        if (!str) {
     5039            char buf[60];
     5040            type_to_str(buf, sizeof buf, &controlling_type, NULL);
     5041            tcc_error("type '%s' does not match any association", buf);
     5042        }
     5043        begin_macro(str, 1);
     5044        next();
     5045        expr_eq();
     5046        if (tok != TOK_EOF)
     5047            expect(",");
     5048        end_macro();
     5049        next();
     5050        break;
     5051    }
    37505052    // special qnan , snan and infinity values
    37515053    case TOK___NAN__:
     
    37695071            expect("identifier");
    37705072        s = sym_find(t);
    3771         if (!s) {
     5073        if (!s || IS_ASM_SYM(s)) {
     5074            const char *name = get_tok_str(t, NULL);
    37725075            if (tok != '(')
    3773                 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
     5076                tcc_error("'%s' undeclared", name);
    37745077            /* for simple function calls, we tolerate undeclared
    37755078               external reference to int() function */
    3776             if (tcc_state->warn_implicit_function_declaration)
    3777                 tcc_warning("implicit declaration of function '%s'",
    3778                         get_tok_str(t, NULL));
     5079            if (tcc_state->warn_implicit_function_declaration
     5080#ifdef TCC_TARGET_PE
     5081                /* people must be warned about using undeclared WINAPI functions
     5082                   (which usually start with uppercase letter) */
     5083                || (name[0] >= 'A' && name[0] <= 'Z')
     5084#endif
     5085            )
     5086                tcc_warning("implicit declaration of function '%s'", name);
    37795087            s = external_global_sym(t, &func_old_type, 0);
    37805088        }
    3781         if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
    3782             (VT_STATIC | VT_INLINE | VT_FUNC)) {
    3783             /* if referencing an inline function, then we generate a
    3784                symbol to it if not already done. It will have the
    3785                effect to generate code for it at the end of the
    3786                compilation unit. Inline function as always
    3787                generated in the text section. */
    3788             if (!s->c)
    3789                 put_extern_sym(s, text_section, 0, 0);
    3790             r = VT_SYM | VT_CONST;
    3791         } else {
    3792             r = s->r;
    3793         }
     5089
     5090        r = s->r;
     5091        /* A symbol that has a register is a local register variable,
     5092           which starts out as VT_LOCAL value.  */
     5093        if ((r & VT_VALMASK) < VT_CONST)
     5094            r = (r & ~VT_VALMASK) | VT_LOCAL;
     5095
    37945096        vset(&s->type, r, s->c);
    3795         /* if forward reference, we must point to s */
    3796         if (vtop->r & VT_SYM) {
    3797             vtop->sym = s;
    3798             vtop->c.ul = 0;
     5097        /* Point to s as backpointer (even without r&VT_SYM).
     5098           Will be used by at least the x86 inline asm parser for
     5099           regvars.  */
     5100        vtop->sym = s;
     5101
     5102        if (r & VT_SYM) {
     5103            vtop->c.i = 0;
     5104        } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
     5105            vtop->c.i = s->enum_val;
    37995106        }
    38005107        break;
     
    38065113            inc(1, tok);
    38075114            next();
    3808         } else if (tok == '.' || tok == TOK_ARROW) {
     5115        } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
    38095116            int qualifiers;
    38105117            /* field */
     
    38145121            test_lvalue();
    38155122            gaddrof();
    3816             next();
    38175123            /* expect pointer on structure */
    38185124            if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
    38195125                expect("struct or union");
    3820             s = vtop->type.ref;
    3821             /* find field */
    3822             tok |= SYM_FIELD;
    3823             while ((s = s->next) != NULL) {
    3824                 if (s->v == tok)
    3825                     break;
    3826             }
     5126            if (tok == TOK_CDOUBLE)
     5127                expect("field name");
     5128            next();
     5129            if (tok == TOK_CINT || tok == TOK_CUINT)
     5130                expect("field name");
     5131            s = find_field(&vtop->type, tok);
    38275132            if (!s)
    3828                 tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, NULL));
     5133                tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, &tokc));
    38295134            /* add field offset to pointer */
    38305135            vtop->type = char_pointer_type; /* change type to 'char *' */
     
    38395144#ifdef CONFIG_TCC_BCHECK
    38405145                /* if bound checking, the referenced pointer must be checked */
    3841                 if (tcc_state->do_bounds_check)
     5146                if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
    38425147                    vtop->r |= VT_MUSTBOUND;
    38435148#endif
     
    38535158            SValue ret;
    38545159            Sym *sa;
    3855             int nb_args;
     5160            int nb_args, ret_nregs, ret_align, regsize, variadic;
    38565161
    38575162            /* function call  */
     
    38735178            next();
    38745179            sa = s->next; /* first parameter */
    3875             nb_args = 0;
     5180            nb_args = regsize = 0;
    38765181            ret.r2 = VT_CONST;
    38775182            /* compute first implicit argument if a structure is returned */
    38785183            if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
    3879                 /* get some space for the returned structure */
    3880                 size = type_size(&s->type, &align);
    3881                 loc = (loc - size) & -align;
     5184                variadic = (s->f.func_type == FUNC_ELLIPSIS);
     5185                ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
     5186                                       &ret_align, &regsize);
     5187                if (!ret_nregs) {
     5188                    /* get some space for the returned structure */
     5189                    size = type_size(&s->type, &align);
     5190#ifdef TCC_TARGET_ARM64
     5191                /* On arm64, a small struct is return in registers.
     5192                   It is much easier to write it to memory if we know
     5193                   that we are allowed to write some extra bytes, so
     5194                   round the allocated space up to a power of 2: */
     5195                if (size < 16)
     5196                    while (size & (size - 1))
     5197                        size = (size | (size - 1)) + 1;
     5198#endif
     5199                    loc = (loc - size) & -align;
     5200                    ret.type = s->type;
     5201                    ret.r = VT_LOCAL | VT_LVAL;
     5202                    /* pass it as 'int' to avoid structure arg passing
     5203                       problems */
     5204                    vseti(VT_LOCAL, loc);
     5205                    ret.c = vtop->c;
     5206                    nb_args++;
     5207                }
     5208            } else {
     5209                ret_nregs = 1;
    38825210                ret.type = s->type;
    3883                 ret.r = VT_LOCAL | VT_LVAL;
    3884                 /* pass it as 'int' to avoid structure arg passing
    3885                    problems */
    3886                 vseti(VT_LOCAL, loc);
    3887                 ret.c = vtop->c;
    3888                 nb_args++;
    3889             } else {
    3890                 ret.type = s->type;
     5211            }
     5212
     5213            if (ret_nregs) {
    38915214                /* return in register */
    38925215                if (is_float(ret.type.t)) {
    38935216                    ret.r = reg_fret(ret.type.t);
     5217#ifdef TCC_TARGET_X86_64
     5218                    if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
     5219                      ret.r2 = REG_QRET;
     5220#endif
    38945221                } else {
     5222#ifndef TCC_TARGET_ARM64
     5223#ifdef TCC_TARGET_X86_64
     5224                    if ((ret.type.t & VT_BTYPE) == VT_QLONG)
     5225#else
    38955226                    if ((ret.type.t & VT_BTYPE) == VT_LLONG)
     5227#endif
    38965228                        ret.r2 = REG_LRET;
     5229#endif
    38975230                    ret.r = REG_IRET;
    38985231                }
     
    39145247                tcc_error("too few arguments to function");
    39155248            skip(')');
    3916             if (!nocode_wanted) {
    3917                 gfunc_call(nb_args);
    3918             } else {
    3919                 vtop -= (nb_args + 1);
    3920             }
     5249            gfunc_call(nb_args);
     5250
    39215251            /* return value */
    3922             vsetc(&ret.type, ret.r, &ret.c);
    3923             vtop->r2 = ret.r2;
     5252            for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
     5253                vsetc(&ret.type, r, &ret.c);
     5254                vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
     5255            }
     5256
     5257            /* handle packed struct return */
     5258            if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
     5259                int addr, offset;
     5260
     5261                size = type_size(&s->type, &align);
     5262                /* We're writing whole regs often, make sure there's enough
     5263                   space.  Assume register size is power of 2.  */
     5264                if (regsize > align)
     5265                  align = regsize;
     5266                loc = (loc - size) & -align;
     5267                addr = loc;
     5268                offset = 0;
     5269                for (;;) {
     5270                    vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
     5271                    vswap();
     5272                    vstore();
     5273                    vtop--;
     5274                    if (--ret_nregs == 0)
     5275                        break;
     5276                    offset += regsize;
     5277                }
     5278                vset(&s->type, VT_LOCAL | VT_LVAL, addr);
     5279            }
    39245280        } else {
    39255281            break;
     
    40245380}
    40255381
    4026 /* XXX: fix this mess */
    4027 static void expr_land_const(void)
    4028 {
    4029     expr_or();
    4030     while (tok == TOK_LAND) {
    4031         next();
    4032         expr_or();
    4033         gen_op(TOK_LAND);
    4034     }
    4035 }
    4036 
    4037 /* XXX: fix this mess */
    4038 static void expr_lor_const(void)
    4039 {
    4040     expr_land_const();
    4041     while (tok == TOK_LOR) {
    4042         next();
    4043         expr_land_const();
    4044         gen_op(TOK_LOR);
    4045     }
    4046 }
    4047 
    4048 /* only used if non constant */
    40495382static void expr_land(void)
    40505383{
    4051     int t;
    4052 
    40535384    expr_or();
    40545385    if (tok == TOK_LAND) {
    4055         t = 0;
    4056         save_regs(1);
    4057         for(;;) {
    4058             t = gtst(1, t);
    4059             if (tok != TOK_LAND) {
    4060                 vseti(VT_JMPI, t);
    4061                 break;
    4062             }
    4063             next();
    4064             expr_or();
    4065         }
     5386        int t = 0;
     5387        for(;;) {
     5388            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
     5389                gen_cast_s(VT_BOOL);
     5390                if (vtop->c.i) {
     5391                    vpop();
     5392                } else {
     5393                    nocode_wanted++;
     5394                    while (tok == TOK_LAND) {
     5395                        next();
     5396                        expr_or();
     5397                        vpop();
     5398                    }
     5399                    nocode_wanted--;
     5400                    if (t)
     5401                      gsym(t);
     5402                    gen_cast_s(VT_INT);
     5403                    break;
     5404                }
     5405            } else {
     5406                if (!t)
     5407                  save_regs(1);
     5408                t = gvtst(1, t);
     5409            }
     5410            if (tok != TOK_LAND) {
     5411                if (t)
     5412                  vseti(VT_JMPI, t);
     5413                else
     5414                  vpushi(1);
     5415                break;
     5416            }
     5417            next();
     5418            expr_or();
     5419        }
    40665420    }
    40675421}
     
    40695423static void expr_lor(void)
    40705424{
    4071     int t;
    4072 
    40735425    expr_land();
    40745426    if (tok == TOK_LOR) {
    4075         t = 0;
    4076         save_regs(1);
    4077         for(;;) {
    4078             t = gtst(0, t);
    4079             if (tok != TOK_LOR) {
    4080                 vseti(VT_JMP, t);
    4081                 break;
    4082             }
    4083             next();
    4084             expr_land();
    4085         }
    4086     }
    4087 }
    4088 
    4089 /* XXX: better constant handling */
     5427        int t = 0;
     5428        for(;;) {
     5429            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
     5430                gen_cast_s(VT_BOOL);
     5431                if (!vtop->c.i) {
     5432                    vpop();
     5433                } else {
     5434                    nocode_wanted++;
     5435                    while (tok == TOK_LOR) {
     5436                        next();
     5437                        expr_land();
     5438                        vpop();
     5439                    }
     5440                    nocode_wanted--;
     5441                    if (t)
     5442                      gsym(t);
     5443                    gen_cast_s(VT_INT);
     5444                    break;
     5445                }
     5446            } else {
     5447                if (!t)
     5448                  save_regs(1);
     5449                t = gvtst(0, t);
     5450            }
     5451            if (tok != TOK_LOR) {
     5452                if (t)
     5453                  vseti(VT_JMP, t);
     5454                else
     5455                  vpushi(0);
     5456                break;
     5457            }
     5458            next();
     5459            expr_land();
     5460        }
     5461    }
     5462}
     5463
     5464/* Assuming vtop is a value used in a conditional context
     5465   (i.e. compared with zero) return 0 if it's false, 1 if
     5466   true and -1 if it can't be statically determined.  */
     5467static int condition_3way(void)
     5468{
     5469    int c = -1;
     5470    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
     5471        (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
     5472        vdup();
     5473        gen_cast_s(VT_BOOL);
     5474        c = vtop->c.i;
     5475        vpop();
     5476    }
     5477    return c;
     5478}
     5479
    40905480static void expr_cond(void)
    40915481{
    4092     int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
     5482    int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
    40935483    SValue sv;
    40945484    CType type, type1, type2;
    40955485
    4096     if (const_wanted) {
    4097         expr_lor_const();
    4098         if (tok == '?') {
    4099             CType boolean;
    4100             int c;
    4101             boolean.t = VT_BOOL;
    4102             vdup();
    4103             gen_cast(&boolean);
    4104             c = vtop->c.i;
    4105             vpop();
    4106             next();
    4107             if (tok != ':' || !gnu_ext) {
     5486    expr_lor();
     5487    if (tok == '?') {
     5488        next();
     5489        c = condition_3way();
     5490        g = (tok == ':' && gnu_ext);
     5491        if (c < 0) {
     5492            /* needed to avoid having different registers saved in
     5493               each branch */
     5494            if (is_float(vtop->type.t)) {
     5495                rc = RC_FLOAT;
     5496#ifdef TCC_TARGET_X86_64
     5497                if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
     5498                    rc = RC_ST0;
     5499                }
     5500#endif
     5501            } else
     5502                rc = RC_INT;
     5503            gv(rc);
     5504            save_regs(1);
     5505            if (g)
     5506                gv_dup();
     5507            tt = gvtst(1, 0);
     5508
     5509        } else {
     5510            if (!g)
    41085511                vpop();
     5512            tt = 0;
     5513        }
     5514
     5515        if (1) {
     5516            if (c == 0)
     5517                nocode_wanted++;
     5518            if (!g)
    41095519                gexpr();
    4110             }
    4111             if (!c)
    4112                 vpop();
    4113             skip(':');
    4114             expr_cond();
    4115             if (c)
    4116                 vpop();
    4117         }
    4118     } else {
    4119         expr_lor();
    4120         if (tok == '?') {
    4121             next();
    4122             if (vtop != vstack) {
    4123                 /* needed to avoid having different registers saved in
    4124                    each branch */
    4125                 if (is_float(vtop->type.t)) {
    4126                     rc = RC_FLOAT;
    4127 #ifdef TCC_TARGET_X86_64
    4128                     if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
    4129                         rc = RC_ST0;
    4130                     }
    4131 #endif
    4132                 }
    4133                 else
    4134                     rc = RC_INT;
    4135                     gv(rc);
    4136                     save_regs(1);
    4137             }
    4138             if (tok == ':' && gnu_ext) {
    4139                 gv_dup();
    4140                 tt = gtst(1, 0);
    4141             } else {
    4142                 tt = gtst(1, 0);
    4143                 gexpr();
    4144             }
     5520
    41455521            type1 = vtop->type;
    41465522            sv = *vtop; /* save value to handle it later */
    41475523            vtop--; /* no vpop so that FP stack is not flushed */
    41485524            skip(':');
    4149             u = gjmp(0);
     5525
     5526            u = 0;
     5527            if (c < 0)
     5528                u = gjmp(0);
    41505529            gsym(tt);
     5530
     5531            if (c == 0)
     5532                nocode_wanted--;
     5533            if (c == 1)
     5534                nocode_wanted++;
    41515535            expr_cond();
     5536            if (c == 1)
     5537                nocode_wanted--;
     5538
    41525539            type2 = vtop->type;
    4153 
    41545540            t1 = type1.t;
    41555541            bt1 = t1 & VT_BTYPE;
    41565542            t2 = type2.t;
    41575543            bt2 = t2 & VT_BTYPE;
     5544            type.ref = NULL;
     5545
    41585546            /* cast operands to correct type according to ISOC rules */
    41595547            if (is_float(bt1) || is_float(bt2)) {
    41605548                if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
    41615549                    type.t = VT_LDOUBLE;
     5550
    41625551                } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
    41635552                    type.t = VT_DOUBLE;
     
    41675556            } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
    41685557                /* cast to biggest op */
    4169                 type.t = VT_LLONG;
     5558                type.t = VT_LLONG | VT_LONG;
     5559                if (bt1 == VT_LLONG)
     5560                    type.t &= t1;
     5561                if (bt2 == VT_LLONG)
     5562                    type.t &= t2;
    41705563                /* convert to unsigned if it does not fit in a long long */
    4171                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
    4172                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
     5564                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
     5565                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
    41735566                    type.t |= VT_UNSIGNED;
    41745567            } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
     
    41945587            } else {
    41955588                /* integer operations */
    4196                 type.t = VT_INT;
     5589                type.t = VT_INT | (VT_LONG & (t1 | t2));
    41975590                /* convert to unsigned if it does not fit in an integer */
    4198                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
    4199                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
     5591                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
     5592                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
    42005593                    type.t |= VT_UNSIGNED;
    42015594            }
    4202                
     5595            /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
     5596               that `(expr ? a : b).mem` does not error  with "lvalue expected" */
     5597            islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
     5598            islv &= c < 0;
     5599
    42035600            /* now we convert second operand */
    4204             gen_cast(&type);
    4205             if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
    4206                 gaddrof();
     5601            if (c != 1) {
     5602                gen_cast(&type);
     5603                if (islv) {
     5604                    mk_pointer(&vtop->type);
     5605                    gaddrof();
     5606                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
     5607                    gaddrof();
     5608            }
     5609
    42075610            rc = RC_INT;
    42085611            if (is_float(type.t)) {
     
    42165619                /* for long longs, we use fixed registers to avoid having
    42175620                   to handle a complicated move */
    4218                 rc = RC_IRET;
    4219             }
    4220            
    4221             r2 = gv(rc);
     5621                rc = RC_IRET;
     5622            }
     5623
     5624            tt = r2 = 0;
     5625            if (c < 0) {
     5626                r2 = gv(rc);
     5627                tt = gjmp(0);
     5628            }
     5629            gsym(u);
     5630
    42225631            /* this is horrible, but we must also convert first
    42235632               operand */
    4224             tt = gjmp(0);
    4225             gsym(u);
    4226             /* put again first value and cast it */
    4227             *vtop = sv;
    4228             gen_cast(&type);
    4229             if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
    4230                 gaddrof();
    4231             r1 = gv(rc);
    4232             move_reg(r2, r1);
    4233             vtop->r = r2;
    4234             gsym(tt);
     5633            if (c != 0) {
     5634                *vtop = sv;
     5635                gen_cast(&type);
     5636                if (islv) {
     5637                    mk_pointer(&vtop->type);
     5638                    gaddrof();
     5639                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
     5640                    gaddrof();
     5641            }
     5642
     5643            if (c < 0) {
     5644                r1 = gv(rc);
     5645                move_reg(r2, r1, type.t);
     5646                vtop->r = r2;
     5647                gsym(tt);
     5648                if (islv)
     5649                    indir();
     5650            }
    42355651        }
    42365652    }
     
    42715687}
    42725688
    4273 /* parse an expression and return its type without any side effect. */
    4274 static void expr_type(CType *type)
    4275 {
    4276     int saved_nocode_wanted;
    4277 
    4278     saved_nocode_wanted = nocode_wanted;
    4279     nocode_wanted = 1;
    4280     gexpr();
    4281     *type = vtop->type;
    4282     vpop();
    4283     nocode_wanted = saved_nocode_wanted;
    4284 }
    4285 
    4286 /* parse a unary expression and return its type without any side
    4287    effect. */
    4288 static void unary_type(CType *type)
    4289 {
    4290     int a;
    4291 
    4292     a = nocode_wanted;
    4293     nocode_wanted = 1;
    4294     unary();
    4295     *type = vtop->type;
    4296     vpop();
    4297     nocode_wanted = a;
    4298 }
    4299 
    43005689/* parse a constant expression and return value in vtop.  */
    43015690static void expr_const1(void)
    43025691{
    4303     int a;
    4304     a = const_wanted;
    4305     const_wanted = 1;
     5692    const_wanted++;
     5693    nocode_wanted++;
    43065694    expr_cond();
    4307     const_wanted = a;
     5695    nocode_wanted--;
     5696    const_wanted--;
    43085697}
    43095698
    43105699/* parse an integer constant and return its value. */
    4311 ST_FUNC int expr_const(void)
    4312 {
    4313     int c;
     5700static inline int64_t expr_const64(void)
     5701{
     5702    int64_t c;
    43145703    expr_const1();
    43155704    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
     
    43175706    c = vtop->c.i;
    43185707    vpop();
     5708    return c;
     5709}
     5710
     5711/* parse an integer constant and return its value.
     5712   Complain if it doesn't fit 32bit (signed or unsigned).  */
     5713ST_FUNC int expr_const(void)
     5714{
     5715    int c;
     5716    int64_t wc = expr_const64();
     5717    c = wc;
     5718    if (c != wc && (unsigned)c != wc)
     5719        tcc_error("constant exceeds 32 bit");
    43195720    return c;
    43205721}
     
    43335734    next();
    43345735    if (tok == ':') {
    4335         next();
    43365736        return last_tok;
    43375737    } else {
     
    43415741}
    43425742
    4343 static void label_or_decl(int l)
    4344 {
    4345     int last_tok;
    4346 
    4347     /* fast test first */
    4348     if (tok >= TOK_UIDENT)
    4349       {
    4350         /* no need to save tokc because tok is an identifier */
    4351         last_tok = tok;
    4352         next();
    4353         if (tok == ':') {
    4354             unget_tok(last_tok);
    4355             return;
    4356         }
    4357         unget_tok(last_tok);
    4358       }
    4359     decl(l);
    4360 }
    4361 
    4362 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
    4363                   int case_reg, int is_expr)
    4364 {
    4365     int a, b, c, d;
    4366     Sym *s, *frame_bottom;
     5743#ifndef TCC_TARGET_ARM64
     5744static void gfunc_return(CType *func_type)
     5745{
     5746    if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
     5747        CType type, ret_type;
     5748        int ret_align, ret_nregs, regsize;
     5749        ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
     5750                               &ret_align, &regsize);
     5751        if (0 == ret_nregs) {
     5752            /* if returning structure, must copy it to implicit
     5753               first pointer arg location */
     5754            type = *func_type;
     5755            mk_pointer(&type);
     5756            vset(&type, VT_LOCAL | VT_LVAL, func_vc);
     5757            indir();
     5758            vswap();
     5759            /* copy structure value to pointer */
     5760            vstore();
     5761        } else {
     5762            /* returning structure packed into registers */
     5763            int r, size, addr, align;
     5764            size = type_size(func_type,&align);
     5765            if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
     5766                 (vtop->c.i & (ret_align-1)))
     5767                && (align & (ret_align-1))) {
     5768                loc = (loc - size) & -ret_align;
     5769                addr = loc;
     5770                type = *func_type;
     5771                vset(&type, VT_LOCAL | VT_LVAL, addr);
     5772                vswap();
     5773                vstore();
     5774                vpop();
     5775                vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
     5776            }
     5777            vtop->type = ret_type;
     5778            if (is_float(ret_type.t))
     5779                r = rc_fret(ret_type.t);
     5780            else
     5781                r = RC_IRET;
     5782
     5783            if (ret_nregs == 1)
     5784                gv(r);
     5785            else {
     5786                for (;;) {
     5787                    vdup();
     5788                    gv(r);
     5789                    vpop();
     5790                    if (--ret_nregs == 0)
     5791                      break;
     5792                    /* We assume that when a structure is returned in multiple
     5793                       registers, their classes are consecutive values of the
     5794                       suite s(n) = 2^n */
     5795                    r <<= 1;
     5796                    vtop->c.i += regsize;
     5797                }
     5798            }
     5799        }
     5800    } else if (is_float(func_type->t)) {
     5801        gv(rc_fret(func_type->t));
     5802    } else {
     5803        gv(RC_IRET);
     5804    }
     5805    vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
     5806}
     5807#endif
     5808
     5809static int case_cmp(const void *pa, const void *pb)
     5810{
     5811    int64_t a = (*(struct case_t**) pa)->v1;
     5812    int64_t b = (*(struct case_t**) pb)->v1;
     5813    return a < b ? -1 : a > b;
     5814}
     5815
     5816static void gcase(struct case_t **base, int len, int *bsym)
     5817{
     5818    struct case_t *p;
     5819    int e;
     5820    int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
     5821    gv(RC_INT);
     5822    while (len > 4) {
     5823        /* binary search */
     5824        p = base[len/2];
     5825        vdup();
     5826        if (ll)
     5827            vpushll(p->v2);
     5828        else
     5829            vpushi(p->v2);
     5830        gen_op(TOK_LE);
     5831        e = gtst(1, 0);
     5832        vdup();
     5833        if (ll)
     5834            vpushll(p->v1);
     5835        else
     5836            vpushi(p->v1);
     5837        gen_op(TOK_GE);
     5838        gtst_addr(0, p->sym); /* v1 <= x <= v2 */
     5839        /* x < v1 */
     5840        gcase(base, len/2, bsym);
     5841        if (cur_switch->def_sym)
     5842            gjmp_addr(cur_switch->def_sym);
     5843        else
     5844            *bsym = gjmp(*bsym);
     5845        /* x > v2 */
     5846        gsym(e);
     5847        e = len/2 + 1;
     5848        base += e; len -= e;
     5849    }
     5850    /* linear scan */
     5851    while (len--) {
     5852        p = *base++;
     5853        vdup();
     5854        if (ll)
     5855            vpushll(p->v2);
     5856        else
     5857            vpushi(p->v2);
     5858        if (p->v1 == p->v2) {
     5859            gen_op(TOK_EQ);
     5860            gtst_addr(0, p->sym);
     5861        } else {
     5862            gen_op(TOK_LE);
     5863            e = gtst(1, 0);
     5864            vdup();
     5865            if (ll)
     5866                vpushll(p->v1);
     5867            else
     5868                vpushi(p->v1);
     5869            gen_op(TOK_GE);
     5870            gtst_addr(0, p->sym);
     5871            gsym(e);
     5872        }
     5873    }
     5874}
     5875
     5876static void block(int *bsym, int *csym, int is_expr)
     5877{
     5878    int a, b, c, d, cond;
     5879    Sym *s;
    43675880
    43685881    /* generate line number info */
    4369     if (tcc_state->do_debug &&
    4370         (last_line_num != file->line_num || last_ind != ind)) {
    4371         put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
    4372         last_ind = ind;
    4373         last_line_num = file->line_num;
    4374     }
     5882    if (tcc_state->do_debug)
     5883        tcc_debug_line(tcc_state);
    43755884
    43765885    if (is_expr) {
     
    43825891    if (tok == TOK_IF) {
    43835892        /* if test */
     5893        int saved_nocode_wanted = nocode_wanted;
    43845894        next();
    43855895        skip('(');
    43865896        gexpr();
    43875897        skip(')');
    4388         a = gtst(1, 0);
    4389         block(bsym, csym, case_sym, def_sym, case_reg, 0);
     5898        cond = condition_3way();
     5899        if (cond == 1)
     5900            a = 0, vpop();
     5901        else
     5902            a = gvtst(1, 0);
     5903        if (cond == 0)
     5904            nocode_wanted |= 0x20000000;
     5905        block(bsym, csym, 0);
     5906        if (cond != 1)
     5907            nocode_wanted = saved_nocode_wanted;
    43905908        c = tok;
    43915909        if (c == TOK_ELSE) {
     
    43935911            d = gjmp(0);
    43945912            gsym(a);
    4395             block(bsym, csym, case_sym, def_sym, case_reg, 0);
     5913            if (cond == 1)
     5914                nocode_wanted |= 0x20000000;
     5915            block(bsym, csym, 0);
    43965916            gsym(d); /* patch else jmp */
     5917            if (cond != 0)
     5918                nocode_wanted = saved_nocode_wanted;
    43975919        } else
    43985920            gsym(a);
    43995921    } else if (tok == TOK_WHILE) {
     5922        int saved_nocode_wanted;
     5923        nocode_wanted &= ~0x20000000;
    44005924        next();
    44015925        d = ind;
     5926        vla_sp_restore();
    44025927        skip('(');
    44035928        gexpr();
    44045929        skip(')');
    4405         a = gtst(1, 0);
     5930        a = gvtst(1, 0);
    44065931        b = 0;
    4407         block(&a, &b, case_sym, def_sym, case_reg, 0);
     5932        ++local_scope;
     5933        saved_nocode_wanted = nocode_wanted;
     5934        block(&a, &b, 0);
     5935        nocode_wanted = saved_nocode_wanted;
     5936        --local_scope;
    44085937        gjmp_addr(d);
    44095938        gsym(a);
     
    44115940    } else if (tok == '{') {
    44125941        Sym *llabel;
    4413        
     5942        int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
     5943
    44145944        next();
    44155945        /* record local declaration stack position */
    44165946        s = local_stack;
    4417         frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
    4418         frame_bottom->next = scope_stack_bottom;
    4419         scope_stack_bottom = frame_bottom;
    44205947        llabel = local_label_stack;
     5948        ++local_scope;
     5949       
    44215950        /* handle local labels declarations */
    44225951        if (tok == TOK_LABEL) {
     
    44365965        }
    44375966        while (tok != '}') {
    4438             label_or_decl(VT_LOCAL);
     5967            if ((a = is_label()))
     5968                unget_tok(a);
     5969            else
     5970                decl(VT_LOCAL);
    44395971            if (tok != '}') {
    44405972                if (is_expr)
    44415973                    vpop();
    4442                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
     5974                block(bsym, csym, is_expr);
    44435975            }
    44445976        }
    44455977        /* pop locally defined labels */
    4446         label_pop(&local_label_stack, llabel);
    4447         if(is_expr) {
    4448             /* XXX: this solution makes only valgrind happy...
    4449                triggered by gcc.c-torture/execute/20000917-1.c */
    4450             Sym *p;
    4451             switch(vtop->type.t & VT_BTYPE) {
    4452             case VT_PTR:
    4453             case VT_STRUCT:
    4454             case VT_ENUM:
    4455             case VT_FUNC:
    4456                 for(p=vtop->type.ref;p;p=p->prev)
    4457                     if(p->prev==s)
    4458                         tcc_error("unsupported expression type");
    4459             }
    4460         }
     5978        label_pop(&local_label_stack, llabel, is_expr);
    44615979        /* pop locally defined symbols */
    4462         scope_stack_bottom = scope_stack_bottom->next;
    4463         sym_pop(&local_stack, s);
     5980        --local_scope;
     5981        /* In the is_expr case (a statement expression is finished here),
     5982           vtop might refer to symbols on the local_stack.  Either via the
     5983           type or via vtop->sym.  We can't pop those nor any that in turn
     5984           might be referred to.  To make it easier we don't roll back
     5985           any symbols in that case; some upper level call to block() will
     5986           do that.  We do have to remove such symbols from the lookup
     5987           tables, though.  sym_pop will do that.  */
     5988        sym_pop(&local_stack, s, is_expr);
     5989
     5990        /* Pop VLA frames and restore stack pointer if required */
     5991        if (vlas_in_scope > saved_vlas_in_scope) {
     5992            vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
     5993            vla_sp_restore();
     5994        }
     5995        vlas_in_scope = saved_vlas_in_scope;
     5996       
    44645997        next();
    44655998    } else if (tok == TOK_RETURN) {
     
    44686001            gexpr();
    44696002            gen_assign_cast(&func_vt);
    4470             if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
    4471                 CType type;
    4472                 /* if returning structure, must copy it to implicit
    4473                    first pointer arg location */
    4474 #ifdef TCC_ARM_EABI
    4475                 int align, size;
    4476                 size = type_size(&func_vt,&align);
    4477                 if(size <= 4)
    4478                 {
    4479                     if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
    4480                        && (align & 3))
    4481                     {
    4482                         int addr;
    4483                         loc = (loc - size) & -4;
    4484                         addr = loc;
    4485                         type = func_vt;
    4486                         vset(&type, VT_LOCAL | VT_LVAL, addr);
    4487                         vswap();
    4488                         vstore();
    4489                         vset(&int_type, VT_LOCAL | VT_LVAL, addr);
    4490                     }
    4491                     vtop->type = int_type;
    4492                     gv(RC_IRET);
    4493                 } else {
    4494 #endif
    4495                 type = func_vt;
    4496                 mk_pointer(&type);
    4497                 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
    4498                 indir();
    4499                 vswap();
    4500                 /* copy structure value to pointer */
    4501                 vstore();
    4502 #ifdef TCC_ARM_EABI
    4503                 }
    4504 #endif
    4505             } else if (is_float(func_vt.t)) {
    4506                 gv(rc_fret(func_vt.t));
    4507             } else {
    4508                 gv(RC_IRET);
    4509             }
    4510             vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
     6003            if ((func_vt.t & VT_BTYPE) == VT_VOID)
     6004                vtop--;
     6005            else
     6006                gfunc_return(&func_vt);
    45116007        }
    45126008        skip(';');
    4513         rsym = gjmp(rsym); /* jmp */
     6009        /* jump unless last stmt in top-level block */
     6010        if (tok != '}' || local_scope != 1)
     6011            rsym = gjmp(rsym);
     6012        nocode_wanted |= 0x20000000;
    45146013    } else if (tok == TOK_BREAK) {
    45156014        /* compute jump */
     
    45196018        next();
    45206019        skip(';');
     6020        nocode_wanted |= 0x20000000;
    45216021    } else if (tok == TOK_CONTINUE) {
    45226022        /* compute jump */
    45236023        if (!csym)
    45246024            tcc_error("cannot continue");
     6025        vla_sp_restore_root();
    45256026        *csym = gjmp(*csym);
    45266027        next();
     
    45286029    } else if (tok == TOK_FOR) {
    45296030        int e;
     6031        int saved_nocode_wanted;
     6032        nocode_wanted &= ~0x20000000;
    45306033        next();
    45316034        skip('(');
    45326035        s = local_stack;
    4533         frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
    4534         frame_bottom->next = scope_stack_bottom;
    4535         scope_stack_bottom = frame_bottom;
     6036        ++local_scope;
    45366037        if (tok != ';') {
    45376038            /* c99 for-loop init decl? */
    4538             if (!decl0(VT_LOCAL, 1)) {
     6039            if (!decl0(VT_LOCAL, 1, NULL)) {
    45396040                /* no, regular for-loop init expr */
    45406041                gexpr();
     
    45456046        d = ind;
    45466047        c = ind;
     6048        vla_sp_restore();
    45476049        a = 0;
    45486050        b = 0;
    45496051        if (tok != ';') {
    45506052            gexpr();
    4551             a = gtst(1, 0);
     6053            a = gvtst(1, 0);
    45526054        }
    45536055        skip(';');
     
    45556057            e = gjmp(0);
    45566058            c = ind;
     6059            vla_sp_restore();
    45576060            gexpr();
    45586061            vpop();
     
    45616064        }
    45626065        skip(')');
    4563         block(&a, &b, case_sym, def_sym, case_reg, 0);
     6066        saved_nocode_wanted = nocode_wanted;
     6067        block(&a, &b, 0);
     6068        nocode_wanted = saved_nocode_wanted;
    45646069        gjmp_addr(c);
    45656070        gsym(a);
    45666071        gsym_addr(b, c);
    4567         scope_stack_bottom = scope_stack_bottom->next;
    4568         sym_pop(&local_stack, s);
     6072        --local_scope;
     6073        sym_pop(&local_stack, s, 0);
     6074
    45696075    } else
    45706076    if (tok == TOK_DO) {
     6077        int saved_nocode_wanted;
     6078        nocode_wanted &= ~0x20000000;
    45716079        next();
    45726080        a = 0;
    45736081        b = 0;
    45746082        d = ind;
    4575         block(&a, &b, case_sym, def_sym, case_reg, 0);
     6083        vla_sp_restore();
     6084        saved_nocode_wanted = nocode_wanted;
     6085        block(&a, &b, 0);
    45766086        skip(TOK_WHILE);
    45776087        skip('(');
    45786088        gsym(b);
    4579         gexpr();
    4580         c = gtst(0, 0);
    4581         gsym_addr(c, d);
     6089        gexpr();
     6090        c = gvtst(0, 0);
     6091        gsym_addr(c, d);
     6092        nocode_wanted = saved_nocode_wanted;
    45826093        skip(')');
    45836094        gsym(a);
     
    45856096    } else
    45866097    if (tok == TOK_SWITCH) {
     6098        struct switch_t *saved, sw;
     6099        int saved_nocode_wanted = nocode_wanted;
     6100        SValue switchval;
    45876101        next();
    45886102        skip('(');
    45896103        gexpr();
    4590         /* XXX: other types than integer */
    4591         case_reg = gv(RC_INT);
    4592         vpop();
    45936104        skip(')');
     6105        switchval = *vtop--;
    45946106        a = 0;
    45956107        b = gjmp(0); /* jump to first case */
    4596         c = 0;
    4597         block(&a, csym, &b, &c, case_reg, 0);
    4598         /* if no default, jmp after switch */
    4599         if (c == 0)
    4600             c = ind;
    4601         /* default label */
    4602         gsym_addr(b, c);
     6108        sw.p = NULL; sw.n = 0; sw.def_sym = 0;
     6109        saved = cur_switch;
     6110        cur_switch = &sw;
     6111        block(&a, csym, 0);
     6112        nocode_wanted = saved_nocode_wanted;
     6113        a = gjmp(a); /* add implicit break */
     6114        /* case lookup */
     6115        gsym(b);
     6116        qsort(sw.p, sw.n, sizeof(void*), case_cmp);
     6117        for (b = 1; b < sw.n; b++)
     6118            if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
     6119                tcc_error("duplicate case value");
     6120        /* Our switch table sorting is signed, so the compared
     6121           value needs to be as well when it's 64bit.  */
     6122        if ((switchval.type.t & VT_BTYPE) == VT_LLONG)
     6123            switchval.type.t &= ~VT_UNSIGNED;
     6124        vpushv(&switchval);
     6125        gcase(sw.p, sw.n, &a);
     6126        vpop();
     6127        if (sw.def_sym)
     6128          gjmp_addr(sw.def_sym);
     6129        dynarray_reset(&sw.p, &sw.n);
     6130        cur_switch = saved;
    46036131        /* break label */
    46046132        gsym(a);
    46056133    } else
    46066134    if (tok == TOK_CASE) {
    4607         int v1, v2;
    4608         if (!case_sym)
     6135        struct case_t *cr = tcc_malloc(sizeof(struct case_t));
     6136        if (!cur_switch)
    46096137            expect("switch");
     6138        nocode_wanted &= ~0x20000000;
    46106139        next();
    4611         v1 = expr_const();
    4612         v2 = v1;
     6140        cr->v1 = cr->v2 = expr_const64();
    46136141        if (gnu_ext && tok == TOK_DOTS) {
    46146142            next();
    4615             v2 = expr_const();
    4616             if (v2 < v1)
     6143            cr->v2 = expr_const64();
     6144            if (cr->v2 < cr->v1)
    46176145                tcc_warning("empty case range");
    46186146        }
    4619         /* since a case is like a label, we must skip it with a jmp */
    4620         b = gjmp(0);
    4621         gsym(*case_sym);
    4622         vseti(case_reg, 0);
    4623         vpushi(v1);
    4624         if (v1 == v2) {
    4625             gen_op(TOK_EQ);
    4626             *case_sym = gtst(1, 0);
    4627         } else {
    4628             gen_op(TOK_GE);
    4629             *case_sym = gtst(1, 0);
    4630             vseti(case_reg, 0);
    4631             vpushi(v2);
    4632             gen_op(TOK_LE);
    4633             *case_sym = gtst(1, *case_sym);
    4634         }
    4635         gsym(b);
     6147        cr->sym = ind;
     6148        dynarray_add(&cur_switch->p, &cur_switch->n, cr);
    46366149        skip(':');
    46376150        is_expr = 0;
     
    46416154        next();
    46426155        skip(':');
    4643         if (!def_sym)
     6156        if (!cur_switch)
    46446157            expect("switch");
    4645         if (*def_sym)
     6158        if (cur_switch->def_sym)
    46466159            tcc_error("too many 'default'");
    4647         *def_sym = ind;
     6160        cur_switch->def_sym = ind;
    46486161        is_expr = 0;
    46496162        goto block_after_label;
     
    46676180                    s->r = LABEL_FORWARD;
    46686181            }
    4669             /* label already defined */
    4670             if (s->r & LABEL_FORWARD)
     6182            vla_sp_restore_root();
     6183            if (s->r & LABEL_FORWARD)
    46716184                s->jnext = gjmp(s->jnext);
    46726185            else
     
    46836196        if (b) {
    46846197            /* label case */
     6198            next();
    46856199            s = label_find(b);
    46866200            if (s) {
     
    46936207            }
    46946208            s->jnext = ind;
     6209            vla_sp_restore();
    46956210            /* we accept this, but it is a mistake */
    46966211        block_after_label:
     6212            nocode_wanted &= ~0x20000000;
    46976213            if (tok == '}') {
    46986214                tcc_warning("deprecated use of label at end of compound statement");
     
    47006216                if (is_expr)
    47016217                    vpop();
    4702                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
     6218                block(bsym, csym, is_expr);
    47036219            }
    47046220        } else {
     
    47186234}
    47196235
    4720 /* t is the array or struct type. c is the array or struct
    4721    address. cur_index/cur_field is the pointer to the current
    4722    value. 'size_only' is true if only size info is needed (only used
    4723    in arrays) */
    4724 static void decl_designator(CType *type, Section *sec, unsigned long c,
    4725                             int *cur_index, Sym **cur_field,
    4726                             int size_only)
    4727 {
    4728     Sym *s, *f;
    4729     int notfirst, index, index_last, align, l, nb_elems, elem_size;
    4730     CType type1;
    4731 
    4732     notfirst = 0;
    4733     elem_size = 0;
    4734     nb_elems = 1;
    4735     if (gnu_ext && (l = is_label()) != 0)
    4736         goto struct_field;
    4737     while (tok == '[' || tok == '.') {
    4738         if (tok == '[') {
    4739             if (!(type->t & VT_ARRAY))
    4740                 expect("array type");
    4741             s = type->ref;
    4742             next();
    4743             index = expr_const();
    4744             if (index < 0 || (s->c >= 0 && index >= s->c))
    4745                 expect("invalid index");
    4746             if (tok == TOK_DOTS && gnu_ext) {
    4747                 next();
    4748                 index_last = expr_const();
    4749                 if (index_last < 0 ||
    4750                     (s->c >= 0 && index_last >= s->c) ||
    4751                     index_last < index)
    4752                     expect("invalid index");
    4753             } else {
    4754                 index_last = index;
    4755             }
    4756             skip(']');
    4757             if (!notfirst)
    4758                 *cur_index = index_last;
    4759             type = pointed_type(type);
    4760             elem_size = type_size(type, &align);
    4761             c += index * elem_size;
    4762             /* NOTE: we only support ranges for last designator */
    4763             nb_elems = index_last - index + 1;
    4764             if (nb_elems != 1) {
    4765                 notfirst = 1;
    4766                 break;
    4767             }
    4768         } else {
    4769             next();
    4770             l = tok;
    4771             next();
    4772         struct_field:
    4773             if ((type->t & VT_BTYPE) != VT_STRUCT)
    4774                 expect("struct/union type");
    4775             s = type->ref;
    4776             l |= SYM_FIELD;
    4777             f = s->next;
    4778             while (f) {
    4779                 if (f->v == l)
    4780                     break;
    4781                 f = f->next;
    4782             }
    4783             if (!f)
    4784                 expect("field");
    4785             if (!notfirst)
    4786                 *cur_field = f;
    4787             /* XXX: fix this mess by using explicit storage field */
    4788             type1 = f->type;
    4789             type1.t |= (type->t & ~VT_TYPE);
    4790             type = &type1;
    4791             c += f->c;
    4792         }
    4793         notfirst = 1;
    4794     }
    4795     if (notfirst) {
    4796         if (tok == '=') {
    4797             next();
    4798         } else {
    4799             if (!gnu_ext)
    4800                 expect("=");
    4801         }
    4802     } else {
    4803         if (type->t & VT_ARRAY) {
    4804             index = *cur_index;
    4805             type = pointed_type(type);
    4806             c += index * type_size(type, &align);
    4807         } else {
    4808             f = *cur_field;
    4809             if (!f)
    4810                 tcc_error("too many field init");
    4811             /* XXX: fix this mess by using explicit storage field */
    4812             type1 = f->type;
    4813             type1.t |= (type->t & ~VT_TYPE);
    4814             type = &type1;
    4815             c += f->c;
    4816         }
    4817     }
    4818     decl_initializer(type, sec, c, 0, size_only);
    4819 
    4820     /* XXX: make it more general */
    4821     if (!size_only && nb_elems > 1) {
    4822         unsigned long c_end;
    4823         uint8_t *src, *dst;
    4824         int i;
    4825 
    4826         if (!sec)
    4827             tcc_error("range init not supported yet for dynamic storage");
    4828         c_end = c + nb_elems * elem_size;
    4829         if (c_end > sec->data_allocated)
    4830             section_realloc(sec, c_end);
    4831         src = sec->data + c;
    4832         dst = src;
    4833         for(i = 1; i < nb_elems; i++) {
    4834             dst += elem_size;
    4835             memcpy(dst, src, elem_size);
    4836         }
    4837     }
    4838 }
    4839 
    4840 #define EXPR_VAL   0
     6236/* This skips over a stream of tokens containing balanced {} and ()
     6237   pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
     6238   with a '{').  If STR then allocates and stores the skipped tokens
     6239   in *STR.  This doesn't check if () and {} are nested correctly,
     6240   i.e. "({)}" is accepted.  */
     6241static void skip_or_save_block(TokenString **str)
     6242{
     6243    int braces = tok == '{';
     6244    int level = 0;
     6245    if (str)
     6246      *str = tok_str_alloc();
     6247
     6248    while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
     6249        int t;
     6250        if (tok == TOK_EOF) {
     6251             if (str || level > 0)
     6252               tcc_error("unexpected end of file");
     6253             else
     6254               break;
     6255        }
     6256        if (str)
     6257          tok_str_add_tok(*str);
     6258        t = tok;
     6259        next();
     6260        if (t == '{' || t == '(') {
     6261            level++;
     6262        } else if (t == '}' || t == ')') {
     6263            level--;
     6264            if (level == 0 && braces && t == '}')
     6265              break;
     6266        }
     6267    }
     6268    if (str) {
     6269        tok_str_add(*str, -1);
     6270        tok_str_add(*str, 0);
     6271    }
     6272}
     6273
    48416274#define EXPR_CONST 1
    48426275#define EXPR_ANY   2
    48436276
    4844 /* store a value or an expression directly in global data or in local array */
    4845 static void init_putv(CType *type, Section *sec, unsigned long c,
    4846                       int v, int expr_type)
    4847 {
    4848     int saved_global_expr, bt, bit_pos, bit_size;
    4849     void *ptr;
    4850     unsigned long long bit_mask;
    4851     CType dtype;
    4852 
     6277static void parse_init_elem(int expr_type)
     6278{
     6279    int saved_global_expr;
    48536280    switch(expr_type) {
    4854     case EXPR_VAL:
    4855         vpushi(v);
    4856         break;
    48576281    case EXPR_CONST:
    48586282        /* compound literals must be allocated globally in this case */
     
    48616285        expr_const1();
    48626286        global_expr = saved_global_expr;
    4863         /* NOTE: symbols are accepted */
    4864         if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
     6287        /* NOTE: symbols are accepted, as well as lvalue for anon symbols
     6288           (compound literals).  */
     6289        if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
     6290             && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
     6291                 || vtop->sym->v < SYM_FIRST_ANOM))
     6292#ifdef TCC_TARGET_PE
     6293                 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
     6294#endif
     6295            )
    48656296            tcc_error("initializer element is not constant");
    48666297        break;
     
    48696300        break;
    48706301    }
    4871    
     6302}
     6303
     6304/* put zeros for variable based init */
     6305static void init_putz(Section *sec, unsigned long c, int size)
     6306{
     6307    if (sec) {
     6308        /* nothing to do because globals are already set to zero */
     6309    } else {
     6310        vpush_global_sym(&func_old_type, TOK_memset);
     6311        vseti(VT_LOCAL, c);
     6312#ifdef TCC_TARGET_ARM
     6313        vpushs(size);
     6314        vpushi(0);
     6315#else
     6316        vpushi(0);
     6317        vpushs(size);
     6318#endif
     6319        gfunc_call(3);
     6320    }
     6321}
     6322
     6323/* t is the array or struct type. c is the array or struct
     6324   address. cur_field is the pointer to the current
     6325   field, for arrays the 'c' member contains the current start
     6326   index.  'size_only' is true if only size info is needed (only used
     6327   in arrays).  al contains the already initialized length of the
     6328   current container (starting at c).  This returns the new length of that.  */
     6329static int decl_designator(CType *type, Section *sec, unsigned long c,
     6330                           Sym **cur_field, int size_only, int al)
     6331{
     6332    Sym *s, *f;
     6333    int index, index_last, align, l, nb_elems, elem_size;
     6334    unsigned long corig = c;
     6335
     6336    elem_size = 0;
     6337    nb_elems = 1;
     6338    if (gnu_ext && (l = is_label()) != 0)
     6339        goto struct_field;
     6340    /* NOTE: we only support ranges for last designator */
     6341    while (nb_elems == 1 && (tok == '[' || tok == '.')) {
     6342        if (tok == '[') {
     6343            if (!(type->t & VT_ARRAY))
     6344                expect("array type");
     6345            next();
     6346            index = index_last = expr_const();
     6347            if (tok == TOK_DOTS && gnu_ext) {
     6348                next();
     6349                index_last = expr_const();
     6350            }
     6351            skip(']');
     6352            s = type->ref;
     6353            if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
     6354                index_last < index)
     6355                tcc_error("invalid index");
     6356            if (cur_field)
     6357                (*cur_field)->c = index_last;
     6358            type = pointed_type(type);
     6359            elem_size = type_size(type, &align);
     6360            c += index * elem_size;
     6361            nb_elems = index_last - index + 1;
     6362        } else {
     6363            next();
     6364            l = tok;
     6365        struct_field:
     6366            next();
     6367            if ((type->t & VT_BTYPE) != VT_STRUCT)
     6368                expect("struct/union type");
     6369            f = find_field(type, l);
     6370            if (!f)
     6371                expect("field");
     6372            if (cur_field)
     6373                *cur_field = f;
     6374            type = &f->type;
     6375            c += f->c;
     6376        }
     6377        cur_field = NULL;
     6378    }
     6379    if (!cur_field) {
     6380        if (tok == '=') {
     6381            next();
     6382        } else if (!gnu_ext) {
     6383            expect("=");
     6384        }
     6385    } else {
     6386        if (type->t & VT_ARRAY) {
     6387            index = (*cur_field)->c;
     6388            if (type->ref->c >= 0 && index >= type->ref->c)
     6389                tcc_error("index too large");
     6390            type = pointed_type(type);
     6391            c += index * type_size(type, &align);
     6392        } else {
     6393            f = *cur_field;
     6394            while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
     6395                *cur_field = f = f->next;
     6396            if (!f)
     6397                tcc_error("too many field init");
     6398            type = &f->type;
     6399            c += f->c;
     6400        }
     6401    }
     6402    /* must put zero in holes (note that doing it that way
     6403       ensures that it even works with designators) */
     6404    if (!size_only && c - corig > al)
     6405        init_putz(sec, corig + al, c - corig - al);
     6406    decl_initializer(type, sec, c, 0, size_only);
     6407
     6408    /* XXX: make it more general */
     6409    if (!size_only && nb_elems > 1) {
     6410        unsigned long c_end;
     6411        uint8_t *src, *dst;
     6412        int i;
     6413
     6414        if (!sec) {
     6415            vset(type, VT_LOCAL|VT_LVAL, c);
     6416            for (i = 1; i < nb_elems; i++) {
     6417                vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
     6418                vswap();
     6419                vstore();
     6420            }
     6421            vpop();
     6422        } else if (!NODATA_WANTED) {
     6423            c_end = c + nb_elems * elem_size;
     6424            if (c_end > sec->data_allocated)
     6425                section_realloc(sec, c_end);
     6426            src = sec->data + c;
     6427            dst = src;
     6428            for(i = 1; i < nb_elems; i++) {
     6429                dst += elem_size;
     6430                memcpy(dst, src, elem_size);
     6431            }
     6432        }
     6433    }
     6434    c += nb_elems * type_size(type, &align);
     6435    if (c - corig > al)
     6436      al = c - corig;
     6437    return al;
     6438}
     6439
     6440/* store a value or an expression directly in global data or in local array */
     6441static void init_putv(CType *type, Section *sec, unsigned long c)
     6442{
     6443    int bt;
     6444    void *ptr;
     6445    CType dtype;
     6446
    48726447    dtype = *type;
    48736448    dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
    48746449
    48756450    if (sec) {
     6451        int size, align;
    48766452        /* XXX: not portable */
    48776453        /* XXX: generate error if incorrect relocation */
    48786454        gen_assign_cast(&dtype);
    48796455        bt = type->t & VT_BTYPE;
    4880         /* we'll write at most 12 bytes */
    4881         if (c + 12 > sec->data_allocated) {
    4882             section_realloc(sec, c + 12);
    4883         }
     6456
     6457        if ((vtop->r & VT_SYM)
     6458            && bt != VT_PTR
     6459            && bt != VT_FUNC
     6460            && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
     6461                || (type->t & VT_BITFIELD))
     6462            && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
     6463            )
     6464            tcc_error("initializer element is not computable at load time");
     6465
     6466        if (NODATA_WANTED) {
     6467            vtop--;
     6468            return;
     6469        }
     6470
     6471        size = type_size(type, &align);
     6472        section_reserve(sec, c + size);
    48846473        ptr = sec->data + c;
     6474
    48856475        /* XXX: make code faster ? */
    4886         if (!(type->t & VT_BITFIELD)) {
    4887             bit_pos = 0;
    4888             bit_size = 32;
    4889             bit_mask = -1LL;
    4890         } else {
    4891             bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
    4892             bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
    4893             bit_mask = (1LL << bit_size) - 1;
    4894         }
    4895         if ((vtop->r & VT_SYM) &&
    4896             (bt == VT_BYTE ||
    4897              bt == VT_SHORT ||
    4898              bt == VT_DOUBLE ||
    4899              bt == VT_LDOUBLE ||
    4900              bt == VT_LLONG ||
    4901              (bt == VT_INT && bit_size != 32)))
    4902             tcc_error("initializer element is not computable at load time");
    4903         switch(bt) {
    4904         case VT_BOOL:
    4905             vtop->c.i = (vtop->c.i != 0);
    4906         case VT_BYTE:
    4907             *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
    4908             break;
    4909         case VT_SHORT:
    4910             *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
    4911             break;
    4912         case VT_DOUBLE:
    4913             *(double *)ptr = vtop->c.d;
    4914             break;
    4915         case VT_LDOUBLE:
    4916             *(long double *)ptr = vtop->c.ld;
    4917             break;
    4918         case VT_LLONG:
    4919             *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
    4920             break;
    4921         default:
    4922             if (vtop->r & VT_SYM) {
    4923                 greloc(sec, vtop->sym, c, R_DATA_PTR);
    4924             }
    4925             *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
    4926             break;
    4927         }
     6476        if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
     6477            vtop->sym->v >= SYM_FIRST_ANOM &&
     6478            /* XXX This rejects compound literals like
     6479               '(void *){ptr}'.  The problem is that '&sym' is
     6480               represented the same way, which would be ruled out
     6481               by the SYM_FIRST_ANOM check above, but also '"string"'
     6482               in 'char *p = "string"' is represented the same
     6483               with the type being VT_PTR and the symbol being an
     6484               anonymous one.  That is, there's no difference in vtop
     6485               between '(void *){x}' and '&(void *){x}'.  Ignore
     6486               pointer typed entities here.  Hopefully no real code
     6487               will every use compound literals with scalar type.  */
     6488            (vtop->type.t & VT_BTYPE) != VT_PTR) {
     6489            /* These come from compound literals, memcpy stuff over.  */
     6490            Section *ssec;
     6491            ElfSym *esym;
     6492            ElfW_Rel *rel;
     6493            esym = elfsym(vtop->sym);
     6494            ssec = tcc_state->sections[esym->st_shndx];
     6495            memmove (ptr, ssec->data + esym->st_value, size);
     6496            if (ssec->reloc) {
     6497                /* We need to copy over all memory contents, and that
     6498                   includes relocations.  Use the fact that relocs are
     6499                   created it order, so look from the end of relocs
     6500                   until we hit one before the copied region.  */
     6501                int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
     6502                rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
     6503                while (num_relocs--) {
     6504                    rel--;
     6505                    if (rel->r_offset >= esym->st_value + size)
     6506                      continue;
     6507                    if (rel->r_offset < esym->st_value)
     6508                      break;
     6509                    /* Note: if the same fields are initialized multiple
     6510                       times (possible with designators) then we possibly
     6511                       add multiple relocations for the same offset here.
     6512                       That would lead to wrong code, the last reloc needs
     6513                       to win.  We clean this up later after the whole
     6514                       initializer is parsed.  */
     6515                    put_elf_reloca(symtab_section, sec,
     6516                                   c + rel->r_offset - esym->st_value,
     6517                                   ELFW(R_TYPE)(rel->r_info),
     6518                                   ELFW(R_SYM)(rel->r_info),
     6519#if PTR_SIZE == 8
     6520                                   rel->r_addend
     6521#else
     6522                                   0
     6523#endif
     6524                                  );
     6525                }
     6526            }
     6527        } else {
     6528            if (type->t & VT_BITFIELD) {
     6529                int bit_pos, bit_size, bits, n;
     6530                unsigned char *p, v, m;
     6531                bit_pos = BIT_POS(vtop->type.t);
     6532                bit_size = BIT_SIZE(vtop->type.t);
     6533                p = (unsigned char*)ptr + (bit_pos >> 3);
     6534                bit_pos &= 7, bits = 0;
     6535                while (bit_size) {
     6536                    n = 8 - bit_pos;
     6537                    if (n > bit_size)
     6538                        n = bit_size;
     6539                    v = vtop->c.i >> bits << bit_pos;
     6540                    m = ((1 << n) - 1) << bit_pos;
     6541                    *p = (*p & ~m) | (v & m);
     6542                    bits += n, bit_size -= n, bit_pos = 0, ++p;
     6543                }
     6544            } else
     6545            switch(bt) {
     6546                /* XXX: when cross-compiling we assume that each type has the
     6547                   same representation on host and target, which is likely to
     6548                   be wrong in the case of long double */
     6549            case VT_BOOL:
     6550                vtop->c.i = vtop->c.i != 0;
     6551            case VT_BYTE:
     6552                *(char *)ptr |= vtop->c.i;
     6553                break;
     6554            case VT_SHORT:
     6555                *(short *)ptr |= vtop->c.i;
     6556                break;
     6557            case VT_FLOAT:
     6558                *(float*)ptr = vtop->c.f;
     6559                break;
     6560            case VT_DOUBLE:
     6561                *(double *)ptr = vtop->c.d;
     6562                break;
     6563            case VT_LDOUBLE:
     6564#if defined TCC_IS_NATIVE_387
     6565                if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
     6566                    memcpy(ptr, &vtop->c.ld, 10);
     6567#ifdef __TINYC__
     6568                else if (sizeof (long double) == sizeof (double))
     6569                    __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
     6570#endif
     6571                else if (vtop->c.ld == 0.0)
     6572                    ;
     6573                else
     6574#endif
     6575                if (sizeof(long double) == LDOUBLE_SIZE)
     6576                    *(long double*)ptr = vtop->c.ld;
     6577                else if (sizeof(double) == LDOUBLE_SIZE)
     6578                    *(double *)ptr = (double)vtop->c.ld;
     6579                else
     6580                    tcc_error("can't cross compile long double constants");
     6581                break;
     6582#if PTR_SIZE != 8
     6583            case VT_LLONG:
     6584                *(long long *)ptr |= vtop->c.i;
     6585                break;
     6586#else
     6587            case VT_LLONG:
     6588#endif
     6589            case VT_PTR:
     6590                {
     6591                    addr_t val = vtop->c.i;
     6592#if PTR_SIZE == 8
     6593                    if (vtop->r & VT_SYM)
     6594                      greloca(sec, vtop->sym, c, R_DATA_PTR, val);
     6595                    else
     6596                      *(addr_t *)ptr |= val;
     6597#else
     6598                    if (vtop->r & VT_SYM)
     6599                      greloc(sec, vtop->sym, c, R_DATA_PTR);
     6600                    *(addr_t *)ptr |= val;
     6601#endif
     6602                    break;
     6603                }
     6604            default:
     6605                {
     6606                    int val = vtop->c.i;
     6607#if PTR_SIZE == 8
     6608                    if (vtop->r & VT_SYM)
     6609                      greloca(sec, vtop->sym, c, R_DATA_PTR, val);
     6610                    else
     6611                      *(int *)ptr |= val;
     6612#else
     6613                    if (vtop->r & VT_SYM)
     6614                      greloc(sec, vtop->sym, c, R_DATA_PTR);
     6615                    *(int *)ptr |= val;
     6616#endif
     6617                    break;
     6618                }
     6619            }
     6620        }
    49286621        vtop--;
    49296622    } else {
     
    49326625        vstore();
    49336626        vpop();
    4934     }
    4935 }
    4936 
    4937 /* put zeros for variable based init */
    4938 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
    4939 {
    4940     if (sec) {
    4941         /* nothing to do because globals are already set to zero */
    4942     } else {
    4943         vpush_global_sym(&func_old_type, TOK_memset);
    4944         vseti(VT_LOCAL, c);
    4945         vpushi(0);
    4946         vpushi(size);
    4947         gfunc_call(3);
    49486627    }
    49496628}
     
    49576636                             int first, int size_only)
    49586637{
    4959     int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
    4960     int size1, align1, expr_type;
     6638    int len, n, no_oblock, nb, i;
     6639    int size1, align1;
     6640    int have_elem;
    49616641    Sym *s, *f;
     6642    Sym indexsym;
    49626643    CType *t1;
    49636644
    4964     if (type->t & VT_VLA) {
    4965 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    4966         int a;
    4967         CValue retcval;
    4968 
    4969         vpush_global_sym(&func_old_type, TOK_alloca);
    4970         vla_runtime_type_size(type, &a);
    4971         gfunc_call(1);
    4972 
    4973         /* return value */
    4974         retcval.i = 0;
    4975         vsetc(type, REG_IRET, &retcval);
    4976         vset(type, VT_LOCAL|VT_LVAL, c);
    4977         vswap();
    4978         vstore();
    4979         vpop();
    4980 #else
    4981         tcc_error("variable length arrays unsupported for this target");
    4982 #endif
     6645    /* If we currently are at an '}' or ',' we have read an initializer
     6646       element in one of our callers, and not yet consumed it.  */
     6647    have_elem = tok == '}' || tok == ',';
     6648    if (!have_elem && tok != '{' &&
     6649        /* In case of strings we have special handling for arrays, so
     6650           don't consume them as initializer value (which would commit them
     6651           to some anonymous symbol).  */
     6652        tok != TOK_LSTR && tok != TOK_STR &&
     6653        !size_only) {
     6654        parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
     6655        have_elem = 1;
     6656    }
     6657
     6658    if (have_elem &&
     6659        !(type->t & VT_ARRAY) &&
     6660        /* Use i_c_parameter_t, to strip toplevel qualifiers.
     6661           The source type might have VT_CONSTANT set, which is
     6662           of course assignable to non-const elements.  */
     6663        is_compatible_unqualified_types(type, &vtop->type)) {
     6664        init_putv(type, sec, c);
    49836665    } else if (type->t & VT_ARRAY) {
    49846666        s = type->ref;
    49856667        n = s->c;
    4986         array_length = 0;
    49876668        t1 = pointed_type(type);
    49886669        size1 = type_size(t1, &align1);
     
    50076688#endif
    50086689            ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
     6690            len = 0;
    50096691            while (tok == TOK_STR || tok == TOK_LSTR) {
    50106692                int cstr_len, ch;
    5011                 CString *cstr;
    5012 
    5013                 cstr = tokc.cstr;
     6693
    50146694                /* compute maximum number of chars wanted */
    50156695                if (tok == TOK_STR)
    5016                     cstr_len = cstr->size;
     6696                    cstr_len = tokc.str.size;
    50176697                else
    5018                     cstr_len = cstr->size / sizeof(nwchar_t);
     6698                    cstr_len = tokc.str.size / sizeof(nwchar_t);
    50196699                cstr_len--;
    50206700                nb = cstr_len;
    5021                 if (n >= 0 && nb > (n - array_length))
    5022                     nb = n - array_length;
     6701                if (n >= 0 && nb > (n - len))
     6702                    nb = n - len;
    50236703                if (!size_only) {
    50246704                    if (cstr_len > nb)
     
    50286708                       specifically */
    50296709                    if (sec && tok == TOK_STR && size1 == 1) {
    5030                         memcpy(sec->data + c + array_length, cstr->data, nb);
     6710                        if (!NODATA_WANTED)
     6711                            memcpy(sec->data + c + len, tokc.str.data, nb);
    50316712                    } else {
    50326713                        for(i=0;i<nb;i++) {
    50336714                            if (tok == TOK_STR)
    5034                                 ch = ((unsigned char *)cstr->data)[i];
     6715                                ch = ((unsigned char *)tokc.str.data)[i];
    50356716                            else
    5036                                 ch = ((nwchar_t *)cstr->data)[i];
    5037                             init_putv(t1, sec, c + (array_length + i) * size1,
    5038                                       ch, EXPR_VAL);
     6717                                ch = ((nwchar_t *)tokc.str.data)[i];
     6718                            vpushi(ch);
     6719                            init_putv(t1, sec, c + (len + i) * size1);
    50396720                        }
    50406721                    }
    50416722                }
    5042                 array_length += nb;
     6723                len += nb;
    50436724                next();
    50446725            }
    50456726            /* only add trailing zero if enough storage (no
    50466727               warning in this case since it is standard) */
    5047             if (n < 0 || array_length < n) {
     6728            if (n < 0 || len < n) {
    50486729                if (!size_only) {
    5049                     init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
     6730                    vpushi(0);
     6731                    init_putv(t1, sec, c + (len * size1));
    50506732                }
    5051                 array_length++;
    5052             }
     6733                len++;
     6734            }
     6735            len *= size1;
    50536736        } else {
    5054             index = 0;
    5055             while (tok != '}') {
    5056                 decl_designator(type, sec, c, &index, NULL, size_only);
    5057                 if (n >= 0 && index >= n)
    5058                     tcc_error("index too large");
    5059                 /* must put zero in holes (note that doing it that way
    5060                    ensures that it even works with designators) */
    5061                 if (!size_only && array_length < index) {
    5062                     init_putz(t1, sec, c + array_length * size1,
    5063                               (index - array_length) * size1);
    5064                 }
    5065                 index++;
    5066                 if (index > array_length)
    5067                     array_length = index;
    5068                 /* special test for multi dimensional arrays (may not
    5069                    be strictly correct if designators are used at the
    5070                    same time) */
    5071                 if (index >= n && no_oblock)
    5072                     break;
    5073                 if (tok == '}')
    5074                     break;
    5075                 skip(',');
    5076             }
    5077         }
     6737            indexsym.c = 0;
     6738            f = &indexsym;
     6739
     6740          do_init_list:
     6741            len = 0;
     6742            while (tok != '}' || have_elem) {
     6743                len = decl_designator(type, sec, c, &f, size_only, len);
     6744                have_elem = 0;
     6745                if (type->t & VT_ARRAY) {
     6746                    ++indexsym.c;
     6747                    /* special test for multi dimensional arrays (may not
     6748                       be strictly correct if designators are used at the
     6749                       same time) */
     6750                    if (no_oblock && len >= n*size1)
     6751                        break;
     6752                } else {
     6753                    if (s->type.t == VT_UNION)
     6754                        f = NULL;
     6755                    else
     6756                        f = f->next;
     6757                    if (no_oblock && f == NULL)
     6758                        break;
     6759                }
     6760
     6761                if (tok == '}')
     6762                    break;
     6763                skip(',');
     6764            }
     6765        }
     6766        /* put zeros at the end */
     6767        if (!size_only && len < n*size1)
     6768            init_putz(sec, c + len, n*size1 - len);
    50786769        if (!no_oblock)
    50796770            skip('}');
    5080         /* put zeros at the end */
    5081         if (!size_only && n >= 0 && array_length < n) {
    5082             init_putz(t1, sec, c + array_length * size1,
    5083                       (n - array_length) * size1);
    5084         }
    5085         /* patch type size if needed */
     6771        /* patch type size if needed, which happens only for array types */
    50866772        if (n < 0)
    5087             s->c = array_length;
    5088     } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
    5089                (sec || !first || tok == '{')) {
    5090         int par_count;
    5091 
    5092         /* NOTE: the previous test is a specific case for automatic
    5093            struct/union init */
    5094         /* XXX: union needs only one init */
    5095 
    5096         /* XXX: this test is incorrect for local initializers
    5097            beginning with ( without {. It would be much more difficult
    5098            to do it correctly (ideally, the expression parser should
    5099            be used in all cases) */
    5100         par_count = 0;
    5101         if (tok == '(') {
    5102             AttributeDef ad1;
    5103             CType type1;
    5104             next();
    5105             while (tok == '(') {
    5106                 par_count++;
    5107                 next();
    5108             }
    5109             if (!parse_btype(&type1, &ad1))
    5110                 expect("cast");
    5111             type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
    5112 #if 0
    5113             if (!is_assignable_types(type, &type1))
    5114                 tcc_error("invalid type for cast");
    5115 #endif
    5116             skip(')');
    5117         }
     6773            s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
     6774    } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
     6775        size1 = 1;
    51186776        no_oblock = 1;
    51196777        if (first || tok == '{') {
     
    51236781        s = type->ref;
    51246782        f = s->next;
    5125         array_length = 0;
    5126         index = 0;
    51276783        n = s->c;
    5128         while (tok != '}') {
    5129             decl_designator(type, sec, c, NULL, &f, size_only);
    5130             index = f->c;
    5131             if (!size_only && array_length < index) {
    5132                 init_putz(type, sec, c + array_length,
    5133                           index - array_length);
    5134             }
    5135             index = index + type_size(&f->type, &align1);
    5136             if (index > array_length)
    5137                 array_length = index;
    5138 
    5139             /* gr: skip fields from same union - ugly. */
    5140             while (f->next) {
    5141                 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
    5142                 /* test for same offset */
    5143                 if (f->next->c != f->c)
    5144                     break;
    5145                 /* if yes, test for bitfield shift */
    5146                 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
    5147                     int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
    5148                     int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
    5149                     //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
    5150                     if (bit_pos_1 != bit_pos_2)
    5151                         break;
    5152                 }
    5153                 f = f->next;
    5154             }
    5155 
    5156             f = f->next;
    5157             if (no_oblock && f == NULL)
    5158                 break;
    5159             if (tok == '}')
    5160                 break;
    5161             skip(',');
    5162         }
    5163         /* put zeros at the end */
    5164         if (!size_only && array_length < n) {
    5165             init_putz(type, sec, c + array_length,
    5166                       n - array_length);
    5167         }
    5168         if (!no_oblock)
    5169             skip('}');
    5170         while (par_count) {
    5171             skip(')');
    5172             par_count--;
    5173         }
     6784        goto do_init_list;
    51746785    } else if (tok == '{') {
    51756786        next();
     
    51776788        skip('}');
    51786789    } else if (size_only) {
     6790        /* If we supported only ISO C we wouldn't have to accept calling
     6791           this on anything than an array size_only==1 (and even then
     6792           only on the outermost level, so no recursion would be needed),
     6793           because initializing a flex array member isn't supported.
     6794           But GNU C supports it, so we need to recurse even into
     6795           subfields of structs and arrays when size_only is set.  */
    51796796        /* just skip expression */
    5180         parlevel = parlevel1 = 0;
    5181         while ((parlevel > 0 || parlevel1 > 0 ||
    5182                 (tok != '}' && tok != ',')) &&  tok != -1) {
    5183             if (tok == '(')
    5184                 parlevel++;
    5185             else if (tok == ')')
    5186                 parlevel--;
    5187             else if (tok == '{')
    5188                 parlevel1++;
    5189             else if (tok == '}')
    5190                 parlevel1--;
    5191             next();
    5192         }
     6797        skip_or_save_block(NULL);
    51936798    } else {
    5194         /* currently, we always use constant expression for globals
    5195            (may change for scripting case) */
    5196         expr_type = EXPR_CONST;
    5197         if (!sec)
    5198             expr_type = EXPR_ANY;
    5199         init_putv(type, sec, c, 0, expr_type);
     6799        if (!have_elem) {
     6800            /* This should happen only when we haven't parsed
     6801               the init element above for fear of committing a
     6802               string constant to memory too early.  */
     6803            if (tok != TOK_STR && tok != TOK_LSTR)
     6804              expect("string constant");
     6805            parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
     6806        }
     6807        init_putv(type, sec, c);
    52006808    }
    52016809}
     
    52046812   allocate space in local or global data space ('r' is either
    52056813   VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
    5206    variable 'v' with an associated name represented by 'asm_label' of
    5207    scope 'scope' is declared before initializers are parsed. If 'v' is
    5208    zero, then a reference to the new object is put in the value stack.
    5209    If 'has_init' is 2, a special parsing is done to handle string
    5210    constants. */
     6814   variable 'v' of scope 'scope' is declared before initializers
     6815   are parsed. If 'v' is zero, then a reference to the new object
     6816   is put in the value stack. If 'has_init' is 2, a special parsing
     6817   is done to handle string constants. */
    52116818static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
    5212                                    int has_init, int v, char *asm_label,
    5213                                    int scope)
    5214 {
    5215     int size, align, addr, data_offset;
    5216     int level;
    5217     ParseState saved_parse_state = {0};
    5218     TokenString init_str;
     6819                                   int has_init, int v, int scope)
     6820{
     6821    int size, align, addr;
     6822    TokenString *init_str = NULL;
     6823
    52196824    Section *sec;
    52206825    Sym *flexible_array;
     6826    Sym *sym = NULL;
     6827    int saved_nocode_wanted = nocode_wanted;
     6828#ifdef CONFIG_TCC_BCHECK
     6829    int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
     6830#endif
     6831
     6832    if (type->t & VT_STATIC)
     6833        nocode_wanted |= NODATA_WANTED ? 0x40000000 : 0x80000000;
    52216834
    52226835    flexible_array = NULL;
    52236836    if ((type->t & VT_BTYPE) == VT_STRUCT) {
    5224         Sym *field;
    5225         field = type->ref;
    5226         while (field && field->next)
    5227             field = field->next;
    5228         if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
    5229             flexible_array = field;
     6837        Sym *field = type->ref->next;
     6838        if (field) {
     6839            while (field->next)
     6840                field = field->next;
     6841            if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
     6842                flexible_array = field;
     6843        }
    52306844    }
    52316845
     
    52376851       literals). It also simplifies local
    52386852       initializers handling */
    5239     tok_str_new(&init_str);
    52406853    if (size < 0 || (flexible_array && has_init)) {
    52416854        if (!has_init)
     
    52436856        /* get all init string */
    52446857        if (has_init == 2) {
     6858            init_str = tok_str_alloc();
    52456859            /* only get strings */
    52466860            while (tok == TOK_STR || tok == TOK_LSTR) {
    5247                 tok_str_add_tok(&init_str);
     6861                tok_str_add_tok(init_str);
    52486862                next();
    52496863            }
     6864            tok_str_add(init_str, -1);
     6865            tok_str_add(init_str, 0);
    52506866        } else {
    5251             level = 0;
    5252             while (level > 0 || (tok != ',' && tok != ';')) {
    5253                 if (tok < 0)
    5254                     tcc_error("unexpected end of file in initializer");
    5255                 tok_str_add_tok(&init_str);
    5256                 if (tok == '{')
    5257                     level++;
    5258                 else if (tok == '}') {
    5259                     level--;
    5260                     if (level <= 0) {
    5261                         next();
    5262                         break;
    5263                     }
    5264                 }
    5265                 next();
    5266             }
    5267         }
    5268         tok_str_add(&init_str, -1);
    5269         tok_str_add(&init_str, 0);
    5270        
     6867            skip_or_save_block(&init_str);
     6868        }
     6869        unget_tok(0);
     6870
    52716871        /* compute size */
    5272         save_parse_state(&saved_parse_state);
    5273 
    5274         macro_ptr = init_str.str;
     6872        begin_macro(init_str, 1);
    52756873        next();
    52766874        decl_initializer(type, NULL, 0, 1, 1);
    52776875        /* prepare second initializer parsing */
    5278         macro_ptr = init_str.str;
     6876        macro_ptr = init_str->str;
    52796877        next();
    52806878       
     
    52846882            tcc_error("unknown type size");
    52856883    }
    5286     if (flexible_array)
    5287         size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
     6884    /* If there's a flex member and it was used in the initializer
     6885       adjust size.  */
     6886    if (flexible_array &&
     6887        flexible_array->type.ref->c > 0)
     6888        size += flexible_array->type.ref->c
     6889                * pointed_size(&flexible_array->type);
    52886890    /* take into account specified alignment if bigger */
    5289     if (ad->aligned) {
    5290         if (ad->aligned > align)
    5291             align = ad->aligned;
    5292     } else if (ad->packed) {
     6891    if (ad->a.aligned) {
     6892        int speca = 1 << (ad->a.aligned - 1);
     6893        if (speca > align)
     6894            align = speca;
     6895    } else if (ad->a.packed) {
    52936896        align = 1;
    52946897    }
     6898
     6899    if (NODATA_WANTED)
     6900        size = 0, align = 1;
     6901
    52956902    if ((r & VT_VALMASK) == VT_LOCAL) {
    52966903        sec = NULL;
    52976904#ifdef CONFIG_TCC_BCHECK
    5298         if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
     6905        if (bcheck && (type->t & VT_ARRAY)) {
    52996906            loc--;
    53006907        }
     
    53066913        /* XXX: currently, since we do only one pass, we cannot track
    53076914           '&' operators, so we add only arrays */
    5308         if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
    5309             unsigned long *bounds_ptr;
     6915        if (bcheck && (type->t & VT_ARRAY)) {
     6916            addr_t *bounds_ptr;
    53106917            /* add padding between regions */
    53116918            loc--;
    53126919            /* then add local bound info */
    5313             bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
     6920            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
    53146921            bounds_ptr[0] = addr;
    53156922            bounds_ptr[1] = size;
     
    53186925        if (v) {
    53196926            /* local variable */
    5320             sym_push(v, type, r, addr);
     6927#ifdef CONFIG_TCC_ASM
     6928            if (ad->asm_label) {
     6929                int reg = asm_parse_regvar(ad->asm_label);
     6930                if (reg >= 0)
     6931                    r = (r & ~VT_VALMASK) | reg;
     6932            }
     6933#endif
     6934            sym = sym_push(v, type, r, addr);
     6935            sym->a = ad->a;
    53216936        } else {
    53226937            /* push local reference */
     
    53246939        }
    53256940    } else {
    5326         Sym *sym;
    5327 
    5328         sym = NULL;
    53296941        if (v && scope == VT_CONST) {
    53306942            /* see if the symbol was already defined */
    53316943            sym = sym_find(v);
    53326944            if (sym) {
    5333                 if (!is_compatible_types(&sym->type, type))
    5334                     tcc_error("incompatible types for redefinition of '%s'",
    5335                           get_tok_str(v, NULL));
    5336                 if (sym->type.t & VT_EXTERN) {
    5337                     /* if the variable is extern, it was not allocated */
    5338                     sym->type.t &= ~VT_EXTERN;
    5339                     /* set array size if it was ommited in extern
    5340                        declaration */
    5341                     if ((sym->type.t & VT_ARRAY) &&
    5342                         sym->type.ref->c < 0 &&
    5343                         type->ref->c >= 0)
    5344                         sym->type.ref->c = type->ref->c;
    5345                 } else {
    5346                     /* we accept several definitions of the same
    5347                        global variable. this is tricky, because we
    5348                        must play with the SHN_COMMON type of the symbol */
    5349                     /* XXX: should check if the variable was already
    5350                        initialized. It is incorrect to initialized it
    5351                        twice */
    5352                     /* no init data, we won't add more to the symbol */
    5353                     if (!has_init)
    5354                         goto no_alloc;
    5355                 }
     6945                patch_storage(sym, ad, type);
     6946                /* we accept several definitions of the same global variable. */
     6947                if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
     6948                    goto no_alloc;
    53566949            }
    53576950        }
     
    53656958                sec = bss_section;
    53666959        }
     6960
    53676961        if (sec) {
    5368             data_offset = sec->data_offset;
    5369             data_offset = (data_offset + align - 1) & -align;
    5370             addr = data_offset;
    5371             /* very important to increment global pointer at this time
    5372                because initializers themselves can create new initializers */
    5373             data_offset += size;
     6962            addr = section_add(sec, size, align);
    53746963#ifdef CONFIG_TCC_BCHECK
    53756964            /* add padding if bound check */
    5376             if (tcc_state->do_bounds_check)
    5377                 data_offset++;
    5378 #endif
    5379             sec->data_offset = data_offset;
    5380             /* allocate section space to put the data */
    5381             if (sec->sh_type != SHT_NOBITS &&
    5382                 data_offset > sec->data_allocated)
    5383                 section_realloc(sec, data_offset);
    5384             /* align section if needed */
    5385             if (align > sec->sh_addralign)
    5386                 sec->sh_addralign = align;
     6965            if (bcheck)
     6966                section_add(sec, 1, 1);
     6967#endif
    53876968        } else {
    5388             addr = 0; /* avoid warning */
     6969            addr = align; /* SHN_COMMON is special, symbol value is align */
     6970            sec = common_section;
    53896971        }
    53906972
    53916973        if (v) {
    5392             if (scope != VT_CONST || !sym) {
     6974            if (!sym) {
    53936975                sym = sym_push(v, type, r | VT_SYM, 0);
    5394                 sym->asm_label = asm_label;
    5395             }
     6976                patch_storage(sym, ad, NULL);
     6977            }
     6978            /* Local statics have a scope until now (for
     6979               warnings), remove it here.  */
     6980            sym->sym_scope = 0;
    53966981            /* update symbol definition */
    5397             if (sec) {
    5398                 put_extern_sym(sym, sec, addr, size);
    5399             } else {
    5400                 ElfW(Sym) *esym;
    5401                 /* put a common area */
    5402                 put_extern_sym(sym, NULL, align, size);
    5403                 /* XXX: find a nicer way */
    5404                 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
    5405                 esym->st_shndx = SHN_COMMON;
    5406             }
     6982            put_extern_sym(sym, sec, addr, size);
    54076983        } else {
    5408             CValue cval;
    5409 
    54106984            /* push global reference */
    54116985            sym = get_sym_ref(type, sec, addr, size);
    5412             cval.ul = 0;
    5413             vsetc(type, VT_CONST | VT_SYM, &cval);
    5414             vtop->sym = sym;
    5415         }
    5416         /* patch symbol weakness */
    5417         if (type->t & VT_WEAK)
    5418             weaken_symbol(sym);
     6986            vpushsym(type, sym);
     6987            vtop->r |= r;
     6988        }
     6989
    54196990#ifdef CONFIG_TCC_BCHECK
    54206991        /* handles bounds now because the symbol must be defined
    54216992           before for the relocation */
    5422         if (tcc_state->do_bounds_check) {
    5423             unsigned long *bounds_ptr;
    5424 
    5425             greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
     6993        if (bcheck) {
     6994            addr_t *bounds_ptr;
     6995
     6996            greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
    54266997            /* then add global bound info */
    5427             bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
     6998            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
    54286999            bounds_ptr[0] = 0; /* relocated */
    54297000            bounds_ptr[1] = size;
     
    54317002#endif
    54327003    }
    5433     if (has_init || (type->t & VT_VLA)) {
     7004
     7005    if (type->t & VT_VLA) {
     7006        int a;
     7007
     7008        if (NODATA_WANTED)
     7009            goto no_alloc;
     7010
     7011        /* save current stack pointer */
     7012        if (vlas_in_scope == 0) {
     7013            if (vla_sp_root_loc == -1)
     7014                vla_sp_root_loc = (loc -= PTR_SIZE);
     7015            gen_vla_sp_save(vla_sp_root_loc);
     7016        }
     7017
     7018        vla_runtime_type_size(type, &a);
     7019        gen_vla_alloc(type, a);
     7020#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
     7021        /* on _WIN64, because of the function args scratch area, the
     7022           result of alloca differs from RSP and is returned in RAX.  */
     7023        gen_vla_result(addr), addr = (loc -= PTR_SIZE);
     7024#endif
     7025        gen_vla_sp_save(addr);
     7026        vla_sp_loc = addr;
     7027        vlas_in_scope++;
     7028
     7029    } else if (has_init) {
     7030        size_t oldreloc_offset = 0;
     7031        if (sec && sec->reloc)
     7032          oldreloc_offset = sec->reloc->data_offset;
    54347033        decl_initializer(type, sec, addr, 1, 0);
    5435         /* restore parse state if needed */
    5436         if (init_str.str) {
    5437             tok_str_free(init_str.str);
    5438             restore_parse_state(&saved_parse_state);
    5439         }
     7034        if (sec && sec->reloc)
     7035          squeeze_multi_relocs(sec, oldreloc_offset);
    54407036        /* patch flexible array member size back to -1, */
    54417037        /* for possible subsequent similar declarations */
     
    54437039            flexible_array->type.ref->c = -1;
    54447040    }
    5445  no_alloc: ;
    5446 }
    5447 
    5448 static void put_func_debug(Sym *sym)
    5449 {
    5450     char buf[512];
    5451 
    5452     /* stabs info */
    5453     /* XXX: we put here a dummy type */
    5454     snprintf(buf, sizeof(buf), "%s:%c1",
    5455              funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
    5456     put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
    5457                 cur_text_section, sym->c);
    5458     /* //gr gdb wants a line at the function */
    5459     put_stabn(N_SLINE, 0, file->line_num, 0);
    5460     last_ind = 0;
    5461     last_line_num = 0;
    5462 }
    5463 
    5464 /* parse an old style function declaration list */
    5465 /* XXX: check multiple parameter */
    5466 static void func_decl_list(Sym *func_sym)
    5467 {
    5468     AttributeDef ad;
    5469     int v;
    5470     Sym *s;
    5471     CType btype, type;
    5472 
    5473     /* parse each declaration */
    5474     while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
    5475            tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
    5476         if (!parse_btype(&btype, &ad))
    5477             expect("declaration list");
    5478         if (((btype.t & VT_BTYPE) == VT_ENUM ||
    5479              (btype.t & VT_BTYPE) == VT_STRUCT) &&
    5480             tok == ';') {
    5481             /* we accept no variable after */
    5482         } else {
    5483             for(;;) {
    5484                 type = btype;
    5485                 type_decl(&type, &ad, &v, TYPE_DIRECT);
    5486                 /* find parameter in function parameter list */
    5487                 s = func_sym->next;
    5488                 while (s != NULL) {
    5489                     if ((s->v & ~SYM_FIELD) == v)
    5490                         goto found;
    5491                     s = s->next;
    5492                 }
    5493                 tcc_error("declaration for parameter '%s' but no such parameter",
    5494                       get_tok_str(v, NULL));
    5495             found:
    5496                 /* check that no storage specifier except 'register' was given */
    5497                 if (type.t & VT_STORAGE)
    5498                     tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
    5499                 convert_parameter_type(&type);
    5500                 /* we can add the type (NOTE: it could be local to the function) */
    5501                 s->type = type;
    5502                 /* accept other parameters */
    5503                 if (tok == ',')
    5504                     next();
    5505                 else
    5506                     break;
    5507             }
    5508         }
    5509         skip(';');
    5510     }
     7041
     7042 no_alloc:
     7043    /* restore parse state if needed */
     7044    if (init_str) {
     7045        end_macro();
     7046        next();
     7047    }
     7048
     7049    nocode_wanted = saved_nocode_wanted;
    55117050}
    55127051
     
    55157054static void gen_function(Sym *sym)
    55167055{
    5517     int saved_nocode_wanted = nocode_wanted;
    55187056    nocode_wanted = 0;
    55197057    ind = cur_text_section->data_offset;
     
    55227060    funcname = get_tok_str(sym->v, NULL);
    55237061    func_ind = ind;
     7062    /* Initialize VLA state */
     7063    vla_sp_loc = -1;
     7064    vla_sp_root_loc = -1;
    55247065    /* put debug symbol */
    5525     if (tcc_state->do_debug)
    5526         put_func_debug(sym);
     7066    tcc_debug_funcstart(tcc_state, sym);
    55277067    /* push a dummy symbol to enable local sym storage */
    55287068    sym_push2(&local_stack, SYM_FIELD, 0, 0);
     7069    local_scope = 1; /* for function parameters */
    55297070    gfunc_prolog(&sym->type);
     7071    local_scope = 0;
    55307072    rsym = 0;
    5531     block(NULL, NULL, NULL, NULL, 0, 0);
     7073    block(NULL, NULL, 0);
     7074    nocode_wanted = 0;
    55327075    gsym(rsym);
    55337076    gfunc_epilog();
    55347077    cur_text_section->data_offset = ind;
    5535     label_pop(&global_label_stack, NULL);
     7078    label_pop(&global_label_stack, NULL, 0);
    55367079    /* reset local stack */
    5537     scope_stack_bottom = NULL;
    5538     sym_pop(&local_stack, NULL);
     7080    local_scope = 0;
     7081    sym_pop(&local_stack, NULL, 0);
    55397082    /* end of function */
    55407083    /* patch symbol size */
    5541     ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
    5542         ind - func_ind;
    5543     /* patch symbol weakness (this definition overrules any prototype) */
    5544     if (sym->type.t & VT_WEAK)
    5545         weaken_symbol(sym);
    5546     if (tcc_state->do_debug) {
    5547         put_stabn(N_FUN, 0, 0, ind - func_ind);
    5548     }
     7084    elfsym(sym)->st_size = ind - func_ind;
     7085    tcc_debug_funcend(tcc_state, ind - func_ind);
    55497086    /* It's better to crash than to generate wrong code */
    55507087    cur_text_section = NULL;
    55517088    funcname = ""; /* for safety */
    55527089    func_vt.t = VT_VOID; /* for safety */
     7090    func_var = 0; /* for safety */
    55537091    ind = 0; /* for safety */
    5554     nocode_wanted = saved_nocode_wanted;
    5555 }
    5556 
    5557 ST_FUNC void gen_inline_functions(void)
     7092    nocode_wanted = 0x80000000;
     7093    check_vstack();
     7094}
     7095
     7096static void gen_inline_functions(TCCState *s)
    55587097{
    55597098    Sym *sym;
    5560     int *str, inline_generated, i;
     7099    int inline_generated, i, ln;
    55617100    struct InlineFunc *fn;
    55627101
     7102    ln = file->line_num;
    55637103    /* iterate while inline function are referenced */
    5564     for(;;) {
     7104    do {
    55657105        inline_generated = 0;
    5566         for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
    5567             fn = tcc_state->inline_fns[i];
     7106        for (i = 0; i < s->nb_inline_fns; ++i) {
     7107            fn = s->inline_fns[i];
    55687108            sym = fn->sym;
    55697109            if (sym && sym->c) {
    55707110                /* the function was used: generate its code and
    55717111                   convert it to a normal function */
    5572                 str = fn->token_str;
    55737112                fn->sym = NULL;
    55747113                if (file)
    55757114                    pstrcpy(file->filename, sizeof file->filename, fn->filename);
    5576                 sym->r = VT_SYM | VT_CONST;
    55777115                sym->type.t &= ~VT_INLINE;
    55787116
    5579                 macro_ptr = str;
     7117                begin_macro(fn->func_str, 1);
    55807118                next();
    55817119                cur_text_section = text_section;
    55827120                gen_function(sym);
    5583                 macro_ptr = NULL; /* fail safe */
     7121                end_macro();
    55847122
    55857123                inline_generated = 1;
    55867124            }
    55877125        }
    5588         if (!inline_generated)
    5589             break;
    5590     }
    5591     for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
    5592         fn = tcc_state->inline_fns[i];
    5593         str = fn->token_str;
    5594         tok_str_free(str);
    5595     }
    5596     dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
    5597 }
    5598 
    5599 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
    5600 static int decl0(int l, int is_for_loop_init)
     7126    } while (inline_generated);
     7127    file->line_num = ln;
     7128}
     7129
     7130ST_FUNC void free_inline_functions(TCCState *s)
     7131{
     7132    int i;
     7133    /* free tokens of unused inline functions */
     7134    for (i = 0; i < s->nb_inline_fns; ++i) {
     7135        struct InlineFunc *fn = s->inline_fns[i];
     7136        if (fn->sym)
     7137            tok_str_free(fn->func_str);
     7138    }
     7139    dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
     7140}
     7141
     7142/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
     7143   if parsing old style parameter decl list (and FUNC_SYM is set then) */
     7144static int decl0(int l, int is_for_loop_init, Sym *func_sym)
    56017145{
    56027146    int v, has_init, r;
     
    56097153            if (is_for_loop_init)
    56107154                return 0;
    5611             /* skip redundant ';' */
    5612             /* XXX: find more elegant solution */
    5613             if (tok == ';') {
     7155            /* skip redundant ';' if not in old parameter decl scope */
     7156            if (tok == ';' && l != VT_CMP) {
    56147157                next();
    56157158                continue;
    56167159            }
    5617             if (l == VT_CONST &&
    5618                 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
     7160            if (l != VT_CONST)
     7161                break;
     7162            if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
    56197163                /* global asm block */
    56207164                asm_global_instr();
    56217165                continue;
    56227166            }
    5623             /* special test for old K&R protos without explicit int
    5624                type. Only accepted when defining global data */
    5625             if (l == VT_LOCAL || tok < TOK_DEFINE)
     7167            if (tok >= TOK_UIDENT) {
     7168               /* special test for old K&R protos without explicit int
     7169                  type. Only accepted when defining global data */
     7170                btype.t = VT_INT;
     7171            } else {
     7172                if (tok != TOK_EOF)
     7173                    expect("declaration");
    56267174                break;
    5627             btype.t = VT_INT;
    5628         }
    5629         if (((btype.t & VT_BTYPE) == VT_ENUM ||
    5630              (btype.t & VT_BTYPE) == VT_STRUCT) &&
    5631             tok == ';') {
    5632             /* we accept no variable after */
    5633             next();
    5634             continue;
     7175            }
     7176        }
     7177        if (tok == ';') {
     7178            if ((btype.t & VT_BTYPE) == VT_STRUCT) {
     7179                int v = btype.ref->v;
     7180                if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
     7181                    tcc_warning("unnamed struct/union that defines no instances");
     7182                next();
     7183                continue;
     7184            }
     7185            if (IS_ENUM(btype.t)) {
     7186                next();
     7187                continue;
     7188            }
    56357189        }
    56367190        while (1) { /* iterate thru each declaration */
    5637             char *asm_label; // associated asm label
    56387191            type = btype;
     7192            /* If the base type itself was an array type of unspecified
     7193               size (like in 'typedef int arr[]; arr x = {1};') then
     7194               we will overwrite the unknown size by the real one for
     7195               this decl.  We need to unshare the ref symbol holding
     7196               that size.  */
     7197            if ((type.t & VT_ARRAY) && type.ref->c < 0) {
     7198                type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
     7199            }
    56397200            type_decl(&type, &ad, &v, TYPE_DIRECT);
    56407201#if 0
    56417202            {
    56427203                char buf[500];
    5643                 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
     7204                type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
    56447205                printf("type = '%s'\n", buf);
    56457206            }
     
    56527213                   declaration list */
    56537214                sym = type.ref;
    5654                 if (sym->c == FUNC_OLD)
    5655                     func_decl_list(sym);
    5656             }
    5657 
    5658             asm_label = NULL;
     7215                if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
     7216                    decl0(VT_CMP, 0, sym);
     7217            }
     7218
    56597219            if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
    5660                 CString astr;
    5661 
    5662                 asm_label_instr(&astr);
    5663                 asm_label = tcc_strdup(astr.data);
    5664                 cstr_free(&astr);
    5665                
     7220                ad.asm_label = asm_label_instr();
    56667221                /* parse one last attribute list, after asm label */
    56677222                parse_attribute(&ad);
    5668             }
    5669 
    5670             if (ad.weak)
    5671                 type.t |= VT_WEAK;
     7223                if (tok == '{')
     7224                    expect(";");
     7225            }
     7226
    56727227#ifdef TCC_TARGET_PE
    5673             if (ad.func_import)
    5674                 type.t |= VT_IMPORT;
    5675             if (ad.func_export)
    5676                 type.t |= VT_EXPORT;
     7228            if (ad.a.dllimport || ad.a.dllexport) {
     7229                if (type.t & (VT_STATIC|VT_TYPEDEF))
     7230                    tcc_error("cannot have dll linkage with static or typedef");
     7231                if (ad.a.dllimport) {
     7232                    if ((type.t & VT_BTYPE) == VT_FUNC)
     7233                        ad.a.dllimport = 0;
     7234                    else
     7235                        type.t |= VT_EXTERN;
     7236                }
     7237            }
    56777238#endif
    56787239            if (tok == '{') {
    5679                 if (l == VT_LOCAL)
     7240                if (l != VT_CONST)
    56807241                    tcc_error("cannot use local functions");
    56817242                if ((type.t & VT_BTYPE) != VT_FUNC)
    56827243                    expect("function definition");
    56837244
    5684                 /* reject abstract declarators in function definition */
     7245                /* reject abstract declarators in function definition
     7246                   make old style params without decl have int type */
    56857247                sym = type.ref;
    5686                 while ((sym = sym->next) != NULL)
     7248                while ((sym = sym->next) != NULL) {
    56877249                    if (!(sym->v & ~SYM_FIELD))
    5688                        expect("identifier");
     7250                        expect("identifier");
     7251                    if (sym->type.t == VT_VOID)
     7252                        sym->type = int_type;
     7253                }
    56897254               
    56907255                /* XXX: cannot do better now: convert extern line to static inline */
    56917256                if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
    56927257                    type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
    5693                
    5694                 sym = sym_find(v);
    5695                 if (sym) {
    5696                     if ((sym->type.t & VT_BTYPE) != VT_FUNC)
    5697                         goto func_error1;
    5698 
    5699                     r = sym->type.ref->r;
    5700                     /* use func_call from prototype if not defined */
    5701                     if (FUNC_CALL(r) != FUNC_CDECL
    5702                      && FUNC_CALL(type.ref->r) == FUNC_CDECL)
    5703                         FUNC_CALL(type.ref->r) = FUNC_CALL(r);
    5704 
    5705                     /* use export from prototype */
    5706                     if (FUNC_EXPORT(r))
    5707                         FUNC_EXPORT(type.ref->r) = 1;
    5708 
    5709                     /* use static from prototype */
    5710                     if (sym->type.t & VT_STATIC)
    5711                         type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
    5712 
    5713                     if (!is_compatible_types(&sym->type, &type)) {
    5714                     func_error1:
    5715                         tcc_error("incompatible types for redefinition of '%s'",
    5716                               get_tok_str(v, NULL));
    5717                     }
    5718                     /* if symbol is already defined, then put complete type */
    5719                     sym->type = type;
    5720                 } else {
    5721                     /* put function symbol */
    5722                     sym = global_identifier_push(v, type.t, 0);
    5723                     sym->type.ref = type.ref;
    5724                 }
     7258
     7259                /* put function symbol */
     7260                sym = external_global_sym(v, &type, 0);
     7261                type.t &= ~VT_EXTERN;
     7262                patch_storage(sym, &ad, &type);
    57257263
    57267264                /* static inline functions are just recorded as a kind
     
    57297267                if ((type.t & (VT_INLINE | VT_STATIC)) ==
    57307268                    (VT_INLINE | VT_STATIC)) {
    5731                     TokenString func_str;
    5732                     int block_level;
    57337269                    struct InlineFunc *fn;
    57347270                    const char *filename;
    57357271                           
    5736                     tok_str_new(&func_str);
    5737                    
    5738                     block_level = 0;
    5739                     for(;;) {
    5740                         int t;
    5741                         if (tok == TOK_EOF)
    5742                             tcc_error("unexpected end of file");
    5743                         tok_str_add_tok(&func_str);
    5744                         t = tok;
    5745                         next();
    5746                         if (t == '{') {
    5747                             block_level++;
    5748                         } else if (t == '}') {
    5749                             block_level--;
    5750                             if (block_level == 0)
    5751                                 break;
    5752                         }
    5753                     }
    5754                     tok_str_add(&func_str, -1);
    5755                     tok_str_add(&func_str, 0);
    57567272                    filename = file ? file->filename : "";
    57577273                    fn = tcc_malloc(sizeof *fn + strlen(filename));
    57587274                    strcpy(fn->filename, filename);
    57597275                    fn->sym = sym;
    5760                     fn->token_str = func_str.str;
    5761                     dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
    5762 
     7276                    skip_or_save_block(&fn->func_str);
     7277                    dynarray_add(&tcc_state->inline_fns,
     7278                                 &tcc_state->nb_inline_fns, fn);
    57637279                } else {
    57647280                    /* compute text section */
     
    57667282                    if (!cur_text_section)
    57677283                        cur_text_section = text_section;
    5768                     sym->r = VT_SYM | VT_CONST;
    57697284                    gen_function(sym);
    57707285                }
    57717286                break;
    57727287            } else {
    5773                 if (btype.t & VT_TYPEDEF) {
     7288                if (l == VT_CMP) {
     7289                    /* find parameter in function parameter list */
     7290                    for (sym = func_sym->next; sym; sym = sym->next)
     7291                        if ((sym->v & ~SYM_FIELD) == v)
     7292                            goto found;
     7293                    tcc_error("declaration for parameter '%s' but no such parameter",
     7294                              get_tok_str(v, NULL));
     7295found:
     7296                    if (type.t & VT_STORAGE) /* 'register' is okay */
     7297                        tcc_error("storage class specified for '%s'",
     7298                                  get_tok_str(v, NULL));
     7299                    if (sym->type.t != VT_VOID)
     7300                        tcc_error("redefinition of parameter '%s'",
     7301                                  get_tok_str(v, NULL));
     7302                    convert_parameter_type(&type);
     7303                    sym->type = type;
     7304                } else if (type.t & VT_TYPEDEF) {
    57747305                    /* save typedefed type  */
    57757306                    /* XXX: test storage specifiers ? */
    5776                     sym = sym_push(v, &type, INT_ATTR(&ad), 0);
    5777                     sym->type.t |= VT_TYPEDEF;
     7307                    sym = sym_find(v);
     7308                    if (sym && sym->sym_scope == local_scope) {
     7309                        if (!is_compatible_types(&sym->type, &type)
     7310                            || !(sym->type.t & VT_TYPEDEF))
     7311                            tcc_error("incompatible redefinition of '%s'",
     7312                                get_tok_str(v, NULL));
     7313                        sym->type = type;
     7314                    } else {
     7315                        sym = sym_push(v, &type, 0, 0);
     7316                    }
     7317                    sym->a = ad.a;
     7318                    sym->f = ad.f;
    57787319                } else {
    57797320                    r = 0;
     
    57817322                        /* external function definition */
    57827323                        /* specific case for func_call attribute */
    5783                         type.ref->r = INT_ATTR(&ad);
     7324                        type.ref->f = ad.f;
    57847325                    } else if (!(type.t & VT_ARRAY)) {
    57857326                        /* not lvalue if array */
     
    57887329                    has_init = (tok == '=');
    57897330                    if (has_init && (type.t & VT_VLA))
    5790                         tcc_error("Variable length array cannot be initialized");
    5791                     if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
     7331                        tcc_error("variable length array cannot be initialized");
     7332                    if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) ||
     7333                        ((type.t & VT_BTYPE) == VT_FUNC) ||
    57927334                        ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
    57937335                         !has_init && l == VT_CONST && type.ref->c < 0)) {
     
    57967338                           arrays of null size are considered as
    57977339                           extern */
    5798                         sym = external_sym(v, &type, r, asm_label);
    5799 
    5800                         if (type.t & VT_WEAK)
    5801                             weaken_symbol(sym);
    5802 
     7340                        type.t |= VT_EXTERN;
     7341                        sym = external_sym(v, &type, r, &ad);
    58037342                        if (ad.alias_target) {
    5804                             Section tsec;
    5805                             Elf32_Sym *esym;
     7343                            ElfSym *esym;
    58067344                            Sym *alias_target;
    5807 
    58087345                            alias_target = sym_find(ad.alias_target);
    5809                             if (!alias_target || !alias_target->c)
     7346                            esym = elfsym(alias_target);
     7347                            if (!esym)
    58107348                                tcc_error("unsupported forward __alias__ attribute");
    5811                             esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
    5812                             tsec.sh_num = esym->st_shndx;
    5813                             put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
     7349                            /* Local statics have a scope until now (for
     7350                               warnings), remove it here.  */
     7351                            sym->sym_scope = 0;
     7352                            put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
    58147353                        }
    58157354                    } else {
    5816                         type.t |= (btype.t & VT_STATIC); /* Retain "static". */
    58177355                        if (type.t & VT_STATIC)
    58187356                            r |= VT_CONST;
     
    58217359                        if (has_init)
    58227360                            next();
    5823                         decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
     7361                        else if (l == VT_CONST)
     7362                            /* uninitialized global variables may be overridden */
     7363                            type.t |= VT_EXTERN;
     7364                        decl_initializer_alloc(&type, &ad, r, has_init, v, l);
    58247365                    }
    58257366                }
     
    58327373                next();
    58337374            }
    5834             ad.aligned = 0;
     7375            ad.a.aligned = 0;
    58357376        }
    58367377    }
     
    58387379}
    58397380
    5840 ST_FUNC void decl(int l)
    5841 {
    5842     decl0(l, 0);
    5843 }
     7381static void decl(int l)
     7382{
     7383    decl0(l, 0, NULL);
     7384}
     7385
     7386/* ------------------------------------------------------------------------- */
Note: See TracChangeset for help on using the changeset viewer.