Revert "Implement C99 Variable Length Arrays"
This reverts commit a5a50eaafe.
			
			
This commit is contained in:
		
							parent
							
								
									38f6467c06
								
							
						
					
					
						commit
						db560e9439
					
				
					 6 changed files with 33 additions and 169 deletions
				
			
		| 
						 | 
				
			
			@ -12,7 +12,6 @@ not released:
 | 
			
		|||
- fix 32 to 64 bit casts, alignment and struct issues (Shinichiro Hamaji)
 | 
			
		||||
- mimic all GNU -option forms supported by ld (Kirill Smelkov)
 | 
			
		||||
- support indirect functions as externals (Thomas Preud'homme)
 | 
			
		||||
- Add support for C99 variable length arrays (Thomas Preud'homme)
 | 
			
		||||
 | 
			
		||||
version 0.9.25:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								TODO
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -48,6 +48,7 @@ Missing features:
 | 
			
		|||
- improve '-E' option.
 | 
			
		||||
- atexit (Nigel Horne)
 | 
			
		||||
- packed attribute
 | 
			
		||||
- C99: add variable size arrays (gcc 3.2 testsuite issue)
 | 
			
		||||
- C99: add complex types (gcc 3.2 testsuite issue)
 | 
			
		||||
- postfix compound literals (see 20010124-1.c)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								tcc-doc.texi
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								tcc-doc.texi
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -929,11 +929,7 @@ be the best solution.
 | 
			
		|||
#define VT_BTYPE      0x000f /* mask for basic type */
 | 
			
		||||
#define VT_UNSIGNED   0x0010  /* unsigned type */
 | 
			
		||||
#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
 | 
			
		||||
#define VT_VLA        0x10000 /* VLA type (also has VT_PTR and VT_ARRAY) */
 | 
			
		||||
#define VT_BITFIELD   0x0040  /* bitfield modifier */
 | 
			
		||||
#define VT_CONSTANT   0x0800  /* const modifier */
 | 
			
		||||
#define VT_VOLATILE   0x1000  /* volatile modifier */
 | 
			
		||||
#define VT_SIGNED     0x2000  /* signed type */
 | 
			
		||||
 | 
			
		||||
#define VT_STRUCT_SHIFT 18   /* structure/enum name shift (14 bits left) */
 | 
			
		||||
@end example
 | 
			
		||||
| 
						 | 
				
			
			@ -946,8 +942,7 @@ The @code{VT_UNSIGNED} flag can be set for chars, shorts, ints and long
 | 
			
		|||
longs.
 | 
			
		||||
 | 
			
		||||
Arrays are considered as pointers @code{VT_PTR} with the flag
 | 
			
		||||
@code{VT_ARRAY} set. Variable length arrays are considered as special
 | 
			
		||||
arrays and therefore also have flag @code{VT_VLA} set.
 | 
			
		||||
@code{VT_ARRAY} set.
 | 
			
		||||
 | 
			
		||||
The @code{VT_BITFIELD} flag can be set for chars, shorts, ints and long
 | 
			
		||||
longs. If it is set, then the bitfield position is stored from bits
 | 
			
		||||
| 
						 | 
				
			
			@ -963,10 +958,6 @@ integer:
 | 
			
		|||
#define VT_EXTERN  0x00000080  /* extern definition */
 | 
			
		||||
#define VT_STATIC  0x00000100  /* static variable */
 | 
			
		||||
#define VT_TYPEDEF 0x00000200  /* typedef definition */
 | 
			
		||||
#define VT_INLINE  0x00000400  /* inline definition */
 | 
			
		||||
#define VT_IMPORT  0x00004000  /* win32: extern data imported from dll */
 | 
			
		||||
#define VT_EXPORT  0x00008000  /* win32: data exported from dll */
 | 
			
		||||
#define VT_WEAK    0x00010000  /* win32: data exported from dll */
 | 
			
		||||
@end example
 | 
			
		||||
 | 
			
		||||
@section Symbols
 | 
			
		||||
| 
						 | 
				
			
			@ -978,10 +969,7 @@ contains @code{Sym} structures.
 | 
			
		|||
an idenfier is also a token, so a string is never necessary to store
 | 
			
		||||
it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually
 | 
			
		||||
the register in which the corresponding variable is stored. @code{Sym.c} is
 | 
			
		||||
usually a constant associated to the symbol like its address for normal
 | 
			
		||||
symbols, and the number of entries for symbols representing arrays.
 | 
			
		||||
Variable length arrays use @code{Sym.r} instead, which is a pointer to
 | 
			
		||||
a @code{SValue} holding its runtime size.
 | 
			
		||||
usually a constant associated to the symbol.
 | 
			
		||||
 | 
			
		||||
Four main symbol stacks are defined:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								tcc.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								tcc.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -224,7 +224,6 @@ typedef struct Sym {
 | 
			
		|||
    union {
 | 
			
		||||
        long c;    /* associated number */
 | 
			
		||||
        int *d;   /* define token stream */
 | 
			
		||||
        SValue *s; /* associated stack value */
 | 
			
		||||
    };
 | 
			
		||||
    CType type;    /* associated type */
 | 
			
		||||
    union {
 | 
			
		||||
| 
						 | 
				
			
			@ -617,7 +616,6 @@ struct TCCState {
 | 
			
		|||
#define VT_BTYPE      0x000f /* mask for basic type */
 | 
			
		||||
#define VT_UNSIGNED   0x0010  /* unsigned type */
 | 
			
		||||
#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
 | 
			
		||||
#define VT_VLA        0x10000 /* VLA type (also has VT_PTR and VT_ARRAY) */
 | 
			
		||||
#define VT_BITFIELD   0x0040  /* bitfield modifier */
 | 
			
		||||
#define VT_CONSTANT   0x0800  /* const modifier */
 | 
			
		||||
#define VT_VOLATILE   0x1000  /* volatile modifier */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										160
									
								
								tccgen.c
									
										
									
									
									
								
							
							
						
						
									
										160
									
								
								tccgen.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -78,7 +78,6 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_re
 | 
			
		|||
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
 | 
			
		||||
static void expr_eq(void);
 | 
			
		||||
static void unary_type(CType *type);
 | 
			
		||||
static void vla_runtime_type_size(CType *type, int *a);
 | 
			
		||||
static int is_compatible_parameter_types(CType *type1, CType *type2);
 | 
			
		||||
static void expr_type(CType *type);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1456,12 +1455,6 @@ static int pointed_size(CType *type)
 | 
			
		|||
    return type_size(pointed_type(type), &align);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void vla_runtime_pointed_size(CType *type)
 | 
			
		||||
{
 | 
			
		||||
    int align;
 | 
			
		||||
    vla_runtime_type_size(pointed_type(type), &align);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int is_null_pointer(SValue *p)
 | 
			
		||||
{
 | 
			
		||||
    if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
 | 
			
		||||
| 
						 | 
				
			
			@ -1550,20 +1543,11 @@ ST_FUNC void gen_op(int op)
 | 
			
		|||
        }
 | 
			
		||||
        /* if both pointers, then it must be the '-' op */
 | 
			
		||||
        if (bt1 == VT_PTR && bt2 == VT_PTR) {
 | 
			
		||||
            int ptr1_is_vla;
 | 
			
		||||
 | 
			
		||||
            ptr1_is_vla = 0;
 | 
			
		||||
            if (op != '-')
 | 
			
		||||
                error("cannot use pointers here");
 | 
			
		||||
            check_comparison_pointer_types(vtop - 1, vtop, op);
 | 
			
		||||
            /* XXX: check that types are compatible */
 | 
			
		||||
            if (vtop[-1].type.t & VT_VLA) {
 | 
			
		||||
                vla_runtime_pointed_size(&vtop[-1].type);
 | 
			
		||||
                vrott(3);
 | 
			
		||||
                ptr1_is_vla = 1;
 | 
			
		||||
            } else {
 | 
			
		||||
                u = pointed_size(&vtop[-1].type);
 | 
			
		||||
            }
 | 
			
		||||
            u = pointed_size(&vtop[-1].type);
 | 
			
		||||
            gen_opic(op);
 | 
			
		||||
            /* set to integer type */
 | 
			
		||||
#ifdef TCC_TARGET_X86_64
 | 
			
		||||
| 
						 | 
				
			
			@ -1571,10 +1555,7 @@ ST_FUNC void gen_op(int op)
 | 
			
		|||
#else
 | 
			
		||||
            vtop->type.t = VT_INT; 
 | 
			
		||||
#endif
 | 
			
		||||
            if (ptr1_is_vla)
 | 
			
		||||
                vswap();
 | 
			
		||||
            else
 | 
			
		||||
                vpushi(u);
 | 
			
		||||
            vpushi(u);
 | 
			
		||||
            gen_op(TOK_PDIV);
 | 
			
		||||
        } else {
 | 
			
		||||
            /* exactly one pointer : must be '+' or '-'. */
 | 
			
		||||
| 
						 | 
				
			
			@ -1586,20 +1567,16 @@ ST_FUNC void gen_op(int op)
 | 
			
		|||
                swap(&t1, &t2);
 | 
			
		||||
            }
 | 
			
		||||
            type1 = vtop[-1].type;
 | 
			
		||||
            type1.t &= ~(VT_ARRAY|VT_VLA);
 | 
			
		||||
            if (vtop[-1].type.t & VT_VLA)
 | 
			
		||||
                vla_runtime_pointed_size(&vtop[-1].type);
 | 
			
		||||
            else {
 | 
			
		||||
                u = pointed_size(&vtop[-1].type);
 | 
			
		||||
                if (u < 0)
 | 
			
		||||
                    error("unknown array element size");
 | 
			
		||||
            type1.t &= ~VT_ARRAY;
 | 
			
		||||
            u = pointed_size(&vtop[-1].type);
 | 
			
		||||
            if (u < 0)
 | 
			
		||||
                error("unknown array element size");
 | 
			
		||||
#ifdef TCC_TARGET_X86_64
 | 
			
		||||
                vpushll(u);
 | 
			
		||||
            vpushll(u);
 | 
			
		||||
#else
 | 
			
		||||
                /* XXX: cast to int ? (long long case) */
 | 
			
		||||
                vpushi(u);
 | 
			
		||||
            /* XXX: cast to int ? (long long case) */
 | 
			
		||||
            vpushi(u);
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
            gen_op('*');
 | 
			
		||||
#ifdef CONFIG_TCC_BCHECK
 | 
			
		||||
            /* if evaluating constant expression, no code should be
 | 
			
		||||
| 
						 | 
				
			
			@ -1955,7 +1932,7 @@ static void gen_cast(CType *type)
 | 
			
		|||
    vtop->type = *type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* return type size as known at compile time. Put alignment at 'a' */
 | 
			
		||||
/* return type size. Put alignment at 'a' */
 | 
			
		||||
ST_FUNC int type_size(CType *type, int *a)
 | 
			
		||||
{
 | 
			
		||||
    Sym *s;
 | 
			
		||||
| 
						 | 
				
			
			@ -1968,10 +1945,7 @@ ST_FUNC int type_size(CType *type, int *a)
 | 
			
		|||
        *a = s->r;
 | 
			
		||||
        return s->c;
 | 
			
		||||
    } else if (bt == VT_PTR) {
 | 
			
		||||
        if (type->t & VT_VLA) {
 | 
			
		||||
            *a = 1;
 | 
			
		||||
            return 0;
 | 
			
		||||
        } else if (type->t & VT_ARRAY) {
 | 
			
		||||
        if (type->t & VT_ARRAY) {
 | 
			
		||||
            int ts;
 | 
			
		||||
 | 
			
		||||
            s = type->ref;
 | 
			
		||||
| 
						 | 
				
			
			@ -2018,30 +1992,6 @@ ST_FUNC int type_size(CType *type, int *a)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* push type size as known at runtime time on top of value stack. Put
 | 
			
		||||
   alignment at 'a' */
 | 
			
		||||
ST_FUNC void vla_runtime_type_size(CType *type, int *a)
 | 
			
		||||
{
 | 
			
		||||
    if (type->t & VT_VLA) {
 | 
			
		||||
        Sym *s;
 | 
			
		||||
 | 
			
		||||
        s = type->ref;
 | 
			
		||||
        vla_runtime_type_size(&s->type, a);
 | 
			
		||||
        vpushv(s->s);
 | 
			
		||||
        if ((vtop->r & (VT_SYM|VT_LVAL|VT_VALMASK)) != VT_CONST) {
 | 
			
		||||
            gv_dup();
 | 
			
		||||
            vswap();
 | 
			
		||||
            vpop();
 | 
			
		||||
        }
 | 
			
		||||
        gen_op('*');
 | 
			
		||||
    } else {
 | 
			
		||||
        int size;
 | 
			
		||||
 | 
			
		||||
        size = type_size(type, a);
 | 
			
		||||
        vpushi(size);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* return the pointed type of t */
 | 
			
		||||
static inline CType *pointed_type(CType *type)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -3153,43 +3103,25 @@ static void post_type(CType *type, AttributeDef *ad)
 | 
			
		|||
        type->t = t1 | VT_FUNC;
 | 
			
		||||
        type->ref = s;
 | 
			
		||||
    } else if (tok == '[') {
 | 
			
		||||
        SValue *last_vtop = NULL;
 | 
			
		||||
 | 
			
		||||
        /* array definition */
 | 
			
		||||
        next();
 | 
			
		||||
        if (tok == TOK_RESTRICT1)
 | 
			
		||||
            next();
 | 
			
		||||
        n = -1;
 | 
			
		||||
        if (tok != ']') {
 | 
			
		||||
            gexpr();
 | 
			
		||||
            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
 | 
			
		||||
                n = vtop->c.i;
 | 
			
		||||
                last_vtop = vtop;
 | 
			
		||||
                if (n < 0)
 | 
			
		||||
                    error("invalid array size");
 | 
			
		||||
            } else {
 | 
			
		||||
                if (!is_integer_btype(vtop->type.t & VT_BTYPE))
 | 
			
		||||
                    error("size of variable length array should be an integer");
 | 
			
		||||
                type->t |= VT_VLA;
 | 
			
		||||
                last_vtop = vtop;
 | 
			
		||||
            }
 | 
			
		||||
            n = expr_const();
 | 
			
		||||
            if (n < 0)
 | 
			
		||||
                error("invalid array size");    
 | 
			
		||||
        }
 | 
			
		||||
        skip(']');
 | 
			
		||||
        /* parse next post type */
 | 
			
		||||
        t1 = type->t & (VT_STORAGE|VT_VLA);
 | 
			
		||||
        type->t &= ~(VT_STORAGE|VT_VLA);
 | 
			
		||||
        t1 = type->t & VT_STORAGE;
 | 
			
		||||
        type->t &= ~VT_STORAGE;
 | 
			
		||||
        post_type(type, ad);
 | 
			
		||||
        t1 |= type->t & VT_VLA;
 | 
			
		||||
        
 | 
			
		||||
        /* we push an anonymous symbol which will contain the array
 | 
			
		||||
        /* we push a anonymous symbol which will contain the array
 | 
			
		||||
           element type */
 | 
			
		||||
        s = sym_push(SYM_FIELD, type, 0, n);
 | 
			
		||||
        if (t1 & VT_VLA) {
 | 
			
		||||
            s->s = last_vtop; // That's ok, we don't need n with VLA
 | 
			
		||||
        } else {
 | 
			
		||||
            if (n >= 0)
 | 
			
		||||
                vpop();
 | 
			
		||||
        }
 | 
			
		||||
        type->t = t1 | VT_ARRAY | VT_PTR;
 | 
			
		||||
        type->ref = s;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -3558,18 +3490,11 @@ ST_FUNC void unary(void)
 | 
			
		|||
        next();
 | 
			
		||||
        in_sizeof++;
 | 
			
		||||
        unary_type(&type); // Perform a in_sizeof = 0;
 | 
			
		||||
        if ((t == TOK_SIZEOF) && (type.t & VT_VLA)) {
 | 
			
		||||
            vla_runtime_type_size(&type, &align);
 | 
			
		||||
            size = 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            size = type_size(&type, &align);
 | 
			
		||||
        }
 | 
			
		||||
        size = type_size(&type, &align);
 | 
			
		||||
        if (t == TOK_SIZEOF) {
 | 
			
		||||
            if (!(type.t & VT_VLA)) {
 | 
			
		||||
                if (size < 0)
 | 
			
		||||
                    error("sizeof applied to an incomplete type");
 | 
			
		||||
                vpushi(size);
 | 
			
		||||
            }
 | 
			
		||||
            if (size < 0)
 | 
			
		||||
                error("sizeof applied to an incomplete type");
 | 
			
		||||
            vpushi(size);
 | 
			
		||||
        } else {
 | 
			
		||||
            vpushi(align);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -3728,10 +3653,7 @@ ST_FUNC void unary(void)
 | 
			
		|||
        } else {
 | 
			
		||||
            r = s->r;
 | 
			
		||||
        }
 | 
			
		||||
        if (s->type.t & VT_VLA)
 | 
			
		||||
            vpushv(s->s);
 | 
			
		||||
        else
 | 
			
		||||
            vset(&s->type, r, s->c);
 | 
			
		||||
        vset(&s->type, r, s->c);
 | 
			
		||||
        /* if forward reference, we must point to s */
 | 
			
		||||
        if (vtop->r & VT_SYM) {
 | 
			
		||||
            vtop->sym = s;
 | 
			
		||||
| 
						 | 
				
			
			@ -4860,18 +4782,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
 | 
			
		|||
    Sym *s, *f;
 | 
			
		||||
    CType *t1;
 | 
			
		||||
 | 
			
		||||
    if (type->t & VT_VLA) {
 | 
			
		||||
        int a;
 | 
			
		||||
        CValue retcval;
 | 
			
		||||
 | 
			
		||||
        vpush_global_sym(&func_old_type, TOK_alloca);
 | 
			
		||||
        vla_runtime_type_size(type, &a);
 | 
			
		||||
        gfunc_call(1);
 | 
			
		||||
 | 
			
		||||
        /* return value */
 | 
			
		||||
        retcval.i = 0;
 | 
			
		||||
        vsetc(type, REG_IRET, &retcval);
 | 
			
		||||
    } else if (type->t & VT_ARRAY) {
 | 
			
		||||
    if (type->t & VT_ARRAY) {
 | 
			
		||||
        s = type->ref;
 | 
			
		||||
        n = s->c;
 | 
			
		||||
        array_length = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -5102,7 +5013,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
 | 
			
		|||
    ParseState saved_parse_state = {0};
 | 
			
		||||
    TokenString init_str;
 | 
			
		||||
    Section *sec;
 | 
			
		||||
    Sym *vla = NULL;
 | 
			
		||||
 | 
			
		||||
    size = type_size(type, &align);
 | 
			
		||||
    /* If unknown size, we must evaluate it before
 | 
			
		||||
| 
						 | 
				
			
			@ -5168,12 +5078,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
 | 
			
		|||
    if ((r & VT_VALMASK) == VT_LOCAL) {
 | 
			
		||||
        sec = NULL;
 | 
			
		||||
#ifdef CONFIG_TCC_BCHECK
 | 
			
		||||
        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
 | 
			
		||||
            if (type->t & VT_VLA)
 | 
			
		||||
                warning("Array bound check don't work for VLA");
 | 
			
		||||
            else
 | 
			
		||||
                loc--;
 | 
			
		||||
        }
 | 
			
		||||
        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
 | 
			
		||||
            loc--;
 | 
			
		||||
#endif
 | 
			
		||||
        loc = (loc - size) & -align;
 | 
			
		||||
        addr = loc;
 | 
			
		||||
| 
						 | 
				
			
			@ -5181,8 +5087,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
 | 
			
		|||
        /* handles bounds */
 | 
			
		||||
        /* XXX: currently, since we do only one pass, we cannot track
 | 
			
		||||
           '&' operators, so we add only arrays */
 | 
			
		||||
        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY) &&
 | 
			
		||||
            !(type->t & VT_VLA)) {
 | 
			
		||||
        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
 | 
			
		||||
            unsigned long *bounds_ptr;
 | 
			
		||||
            /* add padding between regions */
 | 
			
		||||
            loc--;
 | 
			
		||||
| 
						 | 
				
			
			@ -5194,7 +5099,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
 | 
			
		|||
#endif
 | 
			
		||||
        if (v) {
 | 
			
		||||
            /* local variable */
 | 
			
		||||
            vla = sym_push(v, type, r, addr);
 | 
			
		||||
            sym_push(v, type, r, addr);
 | 
			
		||||
        } else {
 | 
			
		||||
            /* push local reference */
 | 
			
		||||
            vset(type, r, addr);
 | 
			
		||||
| 
						 | 
				
			
			@ -5309,10 +5214,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
 | 
			
		|||
        }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    if (has_init || (type->t & VT_VLA)) {
 | 
			
		||||
    if (has_init) {
 | 
			
		||||
        decl_initializer(type, sec, addr, 1, 0);
 | 
			
		||||
        if (type->t & VT_VLA)
 | 
			
		||||
            vla->s = vtop;
 | 
			
		||||
        /* restore parse state if needed */
 | 
			
		||||
        if (init_str.str) {
 | 
			
		||||
            tok_str_free(init_str.str);
 | 
			
		||||
| 
						 | 
				
			
			@ -5681,12 +5584,9 @@ ST_FUNC void decl(int l)
 | 
			
		|||
                    if (!(type.t & VT_ARRAY))
 | 
			
		||||
                        r |= lvalue_type(type.t);
 | 
			
		||||
                    has_init = (tok == '=');
 | 
			
		||||
                    if (has_init && (type.t & VT_VLA))
 | 
			
		||||
                        error("Variable length array cannot be initialized");
 | 
			
		||||
                    if ((btype.t & VT_EXTERN) ||
 | 
			
		||||
                        ((type.t & VT_ARRAY) && (!(type.t & VT_VLA)) &&
 | 
			
		||||
                        (type.t & VT_STATIC) && !has_init && l == VT_CONST &&
 | 
			
		||||
                        type.ref->c < 0)) {
 | 
			
		||||
                        ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
 | 
			
		||||
                         !has_init && l == VT_CONST && type.ref->c < 0)) {
 | 
			
		||||
                        /* external variable */
 | 
			
		||||
                        /* NOTE: as GCC, uninitialized global static
 | 
			
		||||
                           arrays of null size are considered as
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,6 @@ void whitespace_test(void);
 | 
			
		|||
void relocation_test(void);
 | 
			
		||||
void old_style_function(void);
 | 
			
		||||
void alloca_test(void);
 | 
			
		||||
void c99_vla_test(int size1, int size2);
 | 
			
		||||
void sizeof_test(void);
 | 
			
		||||
void typeof_test(void);
 | 
			
		||||
void local_label_test(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -564,7 +563,6 @@ int main(int argc, char **argv)
 | 
			
		|||
    relocation_test();
 | 
			
		||||
    old_style_function();
 | 
			
		||||
    alloca_test();
 | 
			
		||||
    c99_vla_test(5, 2);
 | 
			
		||||
    sizeof_test();
 | 
			
		||||
    typeof_test();
 | 
			
		||||
    statement_expr_test();
 | 
			
		||||
| 
						 | 
				
			
			@ -2020,26 +2018,6 @@ void alloca_test()
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void c99_vla_test(int size1, int size2)
 | 
			
		||||
{
 | 
			
		||||
#if defined __i386__ || defined __x86_64__
 | 
			
		||||
    int tab1[size1 * size2][2], tab2[10][2];
 | 
			
		||||
    void *tab1_ptr, *tab2_ptr;
 | 
			
		||||
 | 
			
		||||
    printf("Test C99 VLA 1 (sizeof): ");
 | 
			
		||||
    printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
 | 
			
		||||
    tab1_ptr = tab1;
 | 
			
		||||
    tab2_ptr = tab2;
 | 
			
		||||
    printf("Test C99 VLA 2 (ptrs substract): ");
 | 
			
		||||
    printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
 | 
			
		||||
    printf("Test C99 VLA 3 (ptr add): ");
 | 
			
		||||
    printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
 | 
			
		||||
    printf("Test C99 VLA 4 (ptr access): ");
 | 
			
		||||
    tab1[size1][1] = 42;
 | 
			
		||||
    printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sizeof_test(void)
 | 
			
		||||
{
 | 
			
		||||
    int a;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue