- tcc -vv: show cross-libtcc1.a correctly (and more)

(As long as it is in the default install location and was not
moved elsewhere into the library search path manually)

Also:
- libtcc.c:
  - error1(): show correct line with "In file included from ..."
  - support "tcc -Bxxx -vv"
  - tcc_new()/tcc_compile(): Don't create elf sections for tcc -E
- tccdbg.c:
  - tcc -E -g : revert 1de025c13a
    Let's keep things simple, everybody understands 'do_debug'
    and dState is set by tcov too (but no debug sections).
- tccgen.c:
  - avoid the extra parameter for gind()
    (from c3e3a07ed4)
  - vla func params: use skip_or_save_block() and enable
    VT_LVAL (see 313855c232)
  - cleanup nocode_wanted a bit
- tccelf.c:
  - tccelf_end_file(): don't try to translate zero-sym relocs
    (seems to happen with asm "jmp 0x1000")
  - version_add(): do not make "ld-linux.so" DT_NEEDED
This commit is contained in:
grischka 2022-08-20 12:58:56 +02:00
parent 414c22c67b
commit e41730f11a
9 changed files with 137 additions and 111 deletions

View file

@ -572,7 +572,7 @@ static void error1(int mode, const char *fmt, va_list ap)
if (f) {
for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
cstr_printf(&cs, "In file included from %s:%d:\n",
(*pf)->filename, (*pf)->line_num);
(*pf)->filename, (*pf)->line_num - 1);
cstr_printf(&cs, "%s:%d: ",
f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
} else if (s1->current_filename) {
@ -733,24 +733,25 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
file->fd = fd;
}
tccelf_begin_file(s1);
preprocess_start(s1, filetype);
tccgen_init(s1);
if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
tcc_preprocess(s1);
} else if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) {
tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP));
} else {
tccgen_compile(s1);
tccelf_begin_file(s1);
if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) {
tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP));
} else {
tccgen_compile(s1);
}
tccelf_end_file(s1);
}
}
tccgen_finish(s1);
preprocess_end(s1);
s1->error_set_jmp_enabled = 0;
tcc_exit_state(s1);
tccelf_end_file(s1);
return s1->nb_errors != 0 ? -1 : 0;
}
@ -819,8 +820,6 @@ LIBTCCAPI TCCState *tcc_new(void)
/* might be used in error() before preprocess_start() */
s->include_stack_ptr = s->include_stack;
tccelf_new(s);
tcc_set_lib_path(s, CONFIG_TCCDIR);
return s;
}
@ -879,19 +878,23 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
}
if (output_type == TCC_OUTPUT_PREPROCESS)
if (output_type == TCC_OUTPUT_PREPROCESS) {
s->do_debug = 0;
return 0;
}
tccelf_new(s);
if (s->do_debug) {
/* add debug sections */
tcc_debug_new(s);
}
#ifdef CONFIG_TCC_BCHECK
if (s->do_bounds_check) {
/* if bound checking, then add corresponding sections */
tccelf_bounds_new(s);
}
#endif
if (s->do_debug) {
/* add debug sections */
tcc_debug_new(s);
}
if (output_type == TCC_OUTPUT_OBJ) {
/* always elf for objects */
s->output_format = TCC_OUTPUT_FORMAT_ELF;
@ -1195,11 +1198,9 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
/* find [cross-]libtcc1.a and tcc helper objects in library path */
ST_FUNC void tcc_add_support(TCCState *s1, const char *filename)
{
#ifdef CONFIG_TCC_CROSSPREFIX
char buf[100];
snprintf(buf, sizeof buf, "%s%s", CONFIG_TCC_CROSSPREFIX, filename);
filename = buf;
#endif
if (CONFIG_TCC_CROSSPREFIX[0])
filename = strcat(strcpy(buf, CONFIG_TCC_CROSSPREFIX), filename);
if (tcc_add_dll(s1, filename, 0) < 0)
tcc_error_noabort("%s not found", filename);
}
@ -1838,6 +1839,7 @@ reparse:
case TCC_OPTION_B:
/* set tcc utilities path (mainly for tcc development) */
tcc_set_lib_path(s, optarg);
++noaction;
break;
case TCC_OPTION_l:
args_parser_add_file(s, optarg, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));

8
tcc.c
View file

@ -206,10 +206,8 @@ static void print_search_dirs(TCCState *s)
/* print_dirs("programs", NULL, 0); */
print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
print_dirs("libraries", s->library_paths, s->nb_library_paths);
#ifdef TCC_TARGET_PE
printf("libtcc1:\n %s/lib/"TCC_LIBTCC1"\n", s->tcc_lib_path);
#else
printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
printf("libtcc1:\n %s/%s\n", s->library_paths[0], CONFIG_TCC_CROSSPREFIX TCC_LIBTCC1);
#ifndef TCC_TARGET_PE
print_dirs("crt", s->crt_paths, s->nb_crt_paths);
printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
#endif
@ -281,7 +279,7 @@ int main(int argc0, char **argv0)
redo:
argc = argc0, argv = argv0;
s = s1 = tcc_new();
#ifdef CONFIG_TCC_SWITCHES
#ifdef CONFIG_TCC_SWITCHES /* predefined options */
tcc_set_options(s, CONFIG_TCC_SWITCHES);
#endif
opt = tcc_parse_args(s, &argc, &argv, 1);

4
tcc.h
View file

@ -361,6 +361,10 @@ extern long double strtold (const char *__nptr, char **__endptr);
# define TCC_LIBTCC1 "libtcc1.a"
#endif
#ifndef CONFIG_TCC_CROSSPREFIX
# define CONFIG_TCC_CROSSPREFIX ""
#endif
/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC
#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"

View file

@ -666,7 +666,7 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
SHN_ABS, filename);
if (s1->dState) {
if (s1->do_debug) {
new_file = last_line_num = 0;
debug_next_type = N_DEFAULT_DEBUG;
@ -835,7 +835,7 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
/* put end of translation unit info */
ST_FUNC void tcc_debug_end(TCCState *s1)
{
if (!s1->dState)
if (!s1->do_debug)
return;
if (s1->dwarf) {
int i, j;
@ -992,7 +992,7 @@ ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
if (0 == strcmp(file->filename, filename))
return;
pstrcpy(file->filename, sizeof(file->filename), filename);
if (!s1->dState)
if (!s1->do_debug)
return;
if (s1->dwarf)
dwarf_file(s1);
@ -1002,7 +1002,7 @@ ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
/* begin of #include */
ST_FUNC void tcc_debug_bincl(TCCState *s1)
{
if (!s1->dState)
if (!s1->do_debug)
return;
if (s1->dwarf) {
int i, j;
@ -1059,7 +1059,7 @@ ST_FUNC void tcc_debug_bincl(TCCState *s1)
/* end of #include */
ST_FUNC void tcc_debug_eincl(TCCState *s1)
{
if (!s1->dState)
if (!s1->do_debug)
return;
if (s1->dwarf)
dwarf_file(s1);
@ -1073,7 +1073,7 @@ ST_FUNC void tcc_debug_line(TCCState *s1)
{
BufferedFile *f;
if (!s1->dState)
if (!s1->do_debug)
return;
if (cur_text_section != text_section)
return;
@ -1161,7 +1161,7 @@ static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned l
ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value)
{
if (!s1->dState)
if (!s1->do_debug)
return;
if (type == N_LBRAC) {
struct _debug_info *info =
@ -1234,7 +1234,7 @@ ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t)
{
int i, j, debug_type;
if (!s1->dState || !s1->dwarf || debug_info)
if (!s1->do_debug || !s1->dwarf || debug_info)
return;
if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1)
for (i = 0; i < n_debug_anon_hash; i++)
@ -1747,7 +1747,7 @@ static void tcc_debug_finish (TCCState *s1, struct _debug_info *cur)
ST_FUNC void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
{
CString debug_str;
if (!s1->dState)
if (!s1->do_debug)
return;
cstr_new (&debug_str);
for (; s != e; s = s->prev) {
@ -1777,7 +1777,7 @@ ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
CString debug_str;
BufferedFile *f;
if (!s1->dState)
if (!s1->do_debug)
return;
debug_info_root = NULL;
debug_info = NULL;
@ -1816,7 +1816,7 @@ ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
/* put function size */
ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
{
if (!s1->dState)
if (!s1->do_debug)
return;
tcc_debug_line(s1);
tcc_debug_stabn(s1, N_RBRAC, size);
@ -1873,7 +1873,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind, int sym_type)
{
if (!s1->dState)
if (!s1->do_debug)
return;
if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM)
return;
@ -1925,7 +1925,7 @@ ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bi
ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym)
{
if (!s1->dState)
if (!s1->do_debug)
return;
if (s1->dwarf) {
int debug_type;

View file

@ -187,7 +187,8 @@ ST_FUNC void tccelf_end_file(TCCState *s1)
ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
for (; rel < rel_end; ++rel) {
int n = ELFW(R_SYM)(rel->r_info) - first_sym;
//if (n < 0) tcc_error("internal: invalid symbol index in relocation");
if (n < 0) /* zero sym_index in reloc (can happen with asm) */
continue;
rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
}
}
@ -596,8 +597,14 @@ version_add (TCCState *s1)
ElfW(Vernaux) *vna = 0;
if (sv->out_index < 1)
continue;
/* make sure that a DT_NEEDED tag is put */
tcc_add_dllref(s1, sv->lib, 0);
/* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
realloc: Assertion `ptr == alloc_last_block' failed! */
if (strcmp(sv->lib, "ld-linux.so.2"))
tcc_add_dllref(s1, sv->lib, 0);
vnofs = section_add(verneed_section, sizeof(*vn), 1);
vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
vn->vn_version = 1;

147
tccgen.c
View file

@ -54,33 +54,10 @@ ST_DATA int const_wanted; /* true if constant wanted */
ST_DATA int nocode_wanted; /* no code generation wanted */
#define unevalmask 0xffff /* unevaluated subexpression */
#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
/* Automagical code suppression ----> */
#define DATA_ONLY_WANTED 0x80000000 /* ON outside of functions and for static initializers */
#define CODE_OFF() (nocode_wanted |= 0x20000000)
#define CODE_ON() (nocode_wanted &= ~0x20000000)
/* Clear 'nocode_wanted' at label if it was used */
ST_FUNC void gsym(int t) { if (t) { gsym_addr(t, ind); CODE_ON(); }}
static int gind(int known_unreachable)
{
int t = ind;
if (!known_unreachable)
CODE_ON();
if (debug_modes)
tcc_tcov_block_begin(tcc_state);
return t;
}
/* Set 'nocode_wanted' after unconditional jumps */
static void gjmp_addr_acs(int t) { gjmp_addr(t); CODE_OFF(); }
static int gjmp_acs(int t) { t = gjmp(t); CODE_OFF(); return t; }
/* These are #undef'd at the end of this file */
#define gjmp_addr gjmp_addr_acs
#define gjmp gjmp_acs
/* <---- */
ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
ST_DATA CType func_vt; /* current function return type (used by return instruction) */
ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
@ -170,6 +147,46 @@ static int get_temp_local_var(int size,int align);
static void clear_temp_local_var_list();
static void cast_error(CType *st, CType *dt);
/* ------------------------------------------------------------------------- */
/* Automagical code suppression */
/* Clear 'nocode_wanted' at forward label if it was used */
ST_FUNC void gsym(int t)
{
if (t) {
gsym_addr(t, ind);
CODE_ON();
}
}
/* Clear 'nocode_wanted' if current pc is a label */
static int gind()
{
int t = ind;
CODE_ON();
if (debug_modes)
tcc_tcov_block_begin(tcc_state);
return t;
}
/* Set 'nocode_wanted' after unconditional (backwards) jump */
static void gjmp_addr_acs(int t)
{
gjmp_addr(t);
CODE_OFF();
}
/* Set 'nocode_wanted' after unconditional (forwards) jump */
static int gjmp_acs(int t)
{
t = gjmp(t);
CODE_OFF();
return t;
}
/* These are #undef'd at the end of this file */
#define gjmp_addr gjmp_addr_acs
#define gjmp gjmp_acs
/* ------------------------------------------------------------------------- */
ST_INLN int is_float(int t)
@ -358,7 +375,7 @@ ST_FUNC int tccgen_compile(TCCState *s1)
func_ind = -1;
anon_sym = SYM_FIRST_ANOM;
const_wanted = 0;
nocode_wanted = 0x80000000;
nocode_wanted = DATA_ONLY_WANTED; /* no code outside of functions */
local_scope = 0;
debug_modes = (s1->do_debug ? 1 : 0) | s1->test_coverage << 1;
@ -3126,7 +3143,7 @@ error:
}
/* cannot generate code for global or static initializers */
if (STATIC_DATA_WANTED)
if (nocode_wanted & DATA_ONLY_WANTED)
goto done;
/* non constant case: generate code */
@ -4728,7 +4745,7 @@ static int asm_label_instr(void)
static int post_type(CType *type, AttributeDef *ad, int storage, int td)
{
int n, l, t1, arg_size, align, unused_align;
int n, l, t1, arg_size, align;
Sym **plast, *s, *first;
AttributeDef ad1;
CType pt;
@ -4775,7 +4792,10 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
expect("identifier");
convert_parameter_type(&pt);
arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
s = sym_push(n, &pt, 0, 0);
/* these symbols may be evaluated for VLArrays (see below, under
nocode_wanted) which is why we push them here as normal symbols
temporarily. Example: int func(int a, int b[++a]); */
s = sym_push(n, &pt, VT_LOCAL|VT_LVAL, 0);
*plast = s;
plast = &s->next;
if (tok == ')')
@ -4842,26 +4862,11 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
break;
}
if (tok != ']') {
int nest = 1;
/* Code generation is not done now but has to be done
at start of function. Save code here for later use. */
nocode_wanted = 1;
vla_array_tok = tok_str_alloc();
for (;;) {
if (tok == ']') {
nest--;
if (nest == 0)
break;
}
if (tok == '[')
nest++;
tok_str_add_tok(vla_array_tok);
next();
}
skip_or_save_block(&vla_array_tok);
unget_tok(0);
tok_str_add(vla_array_tok, -1);
tok_str_add(vla_array_tok, 0);
vla_array_str = vla_array_tok->str;
begin_macro(vla_array_tok, 2);
next();
@ -4902,7 +4907,7 @@ check:
if ((type->t & VT_BTYPE) == VT_FUNC)
tcc_error("declaration of an array of functions");
if ((type->t & VT_BTYPE) == VT_VOID
|| type_size(type, &unused_align) < 0)
|| type_size(type, &align) < 0)
tcc_error("declaration of an array of incomplete type elements");
t1 |= type->t & VT_VLA;
@ -4933,7 +4938,8 @@ check:
s = sym_push(SYM_FIELD, type, 0, n);
type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
type->ref = s;
if (vla_array_str) {
if (vla_array_str) {
if (t1 & VT_VLA)
s->vla_array_str = vla_array_str;
else
@ -6783,7 +6789,7 @@ again:
}
} else if (t == TOK_WHILE) {
d = gind(0);
d = gind();
skip('(');
gexpr();
skip(')');
@ -6883,7 +6889,7 @@ again:
}
skip(';');
a = b = 0;
c = d = gind(0);
c = d = gind();
if (tok != ';') {
gexpr();
a = gvtst(1, 0);
@ -6891,7 +6897,7 @@ again:
skip(';');
if (tok != ')') {
e = gjmp(0);
d = gind(0);
d = gind();
gexpr();
vpop();
gjmp_addr(c);
@ -6906,7 +6912,7 @@ again:
} else if (t == TOK_DO) {
a = b = 0;
d = gind(0);
d = gind();
lblock(&a, &b);
gsym(b);
skip(TOK_WHILE);
@ -6940,17 +6946,17 @@ again:
/* case lookup */
gsym(b);
if (sw->nocode_wanted)
goto skip_switch;
if (sw->sv.type.t & VT_UNSIGNED)
qsort(sw->p, sw->n, sizeof(void*), case_cmpu);
else
qsort(sw->p, sw->n, sizeof(void*), case_cmpi);
for (b = 1; b < sw->n; b++)
if (sw->sv.type.t & VT_UNSIGNED
? (uint64_t)sw->p[b - 1]->v2 >= (uint64_t)sw->p[b]->v1
: sw->p[b - 1]->v2 >= sw->p[b]->v1)
tcc_error("duplicate case value");
vpushv(&sw->sv);
gv(RC_INT);
d = 0, gcase(sw->p, sw->n, &d);
@ -6959,6 +6965,7 @@ again:
gsym_addr(d, sw->def_sym);
else
gsym(d);
skip_switch:
/* break label */
gsym(a);
@ -6978,9 +6985,9 @@ again:
|| (cur_switch->sv.type.t & VT_UNSIGNED && (uint64_t)cr->v2 < (uint64_t)cr->v1))
tcc_warning("empty case range");
}
if (debug_modes)
tcc_tcov_reset_ind(tcc_state);
cr->sym = gind(cur_switch->nocode_wanted);
/* case and default are unreachable from a switch under nocode_wanted */
if (!cur_switch->nocode_wanted)
cr->sym = gind();
dynarray_add(&cur_switch->p, &cur_switch->n, cr);
skip(':');
is_expr = 0;
@ -6991,9 +6998,7 @@ again:
expect("switch");
if (cur_switch->def_sym)
tcc_error("too many 'default'");
if (debug_modes)
tcc_tcov_reset_ind(tcc_state);
cur_switch->def_sym = gind(cur_switch->nocode_wanted);
cur_switch->def_sym = cur_switch->nocode_wanted ? 1 : gind();
skip(':');
is_expr = 0;
goto block_after_label;
@ -7059,7 +7064,7 @@ again:
} else {
s = label_push(&global_label_stack, t, LABEL_DEFINED);
}
s->jnext = gind(0);
s->jnext = gind();
s->cleanupstate = cur_scope->cl.s;
block_after_label:
@ -7068,6 +7073,8 @@ again:
AttributeDef ad_tmp;
parse_attribute(&ad_tmp);
}
if (debug_modes)
tcc_tcov_reset_ind(tcc_state);
vla_restore(cur_scope->vla.loc);
if (tok != '}')
goto again;
@ -7107,9 +7114,16 @@ static void skip_or_save_block(TokenString **str)
if (str)
*str = tok_str_alloc();
while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
int t;
if (tok == TOK_EOF) {
while (1) {
int t = tok;
if (level == 0
&& (t == ','
|| t == ';'
|| t == '}'
|| t == ')'
|| t == ']'))
break;
if (t == TOK_EOF) {
if (str || level > 0)
tcc_error("unexpected end of file");
else
@ -7117,11 +7131,10 @@ static void skip_or_save_block(TokenString **str)
}
if (str)
tok_str_add_tok(*str);
t = tok;
next();
if (t == '{' || t == '(') {
if (t == '{' || t == '(' || t == '[') {
level++;
} else if (t == '}' || t == ')') {
} else if (t == '}' || t == ')' || t == ']') {
level--;
if (level == 0 && braces && t == '}')
break;
@ -7798,7 +7811,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
/* Always allocate static or global variables */
if (v && (r & VT_VALMASK) == VT_CONST)
nocode_wanted |= 0x80000000;
nocode_wanted |= DATA_ONLY_WANTED;
flexible_array = NULL;
size = type_size(type, &align);
@ -8136,7 +8149,7 @@ static void gen_function(Sym *sym)
func_var = 0; /* for safety */
ind = 0; /* for safety */
func_ind = -1;
nocode_wanted = 0x80000000;
nocode_wanted = DATA_ONLY_WANTED;
check_vstack();
/* do this after funcend debug info */
next();

View file

@ -838,6 +838,7 @@ static uint8_t *parse_pp_string(uint8_t *p, int sep, CString *str)
if (c == CH_EOF) {
unterminated_string:
/* XXX: indicate line number of start of string */
tok_flags &= ~TOK_FLAG_BOL;
tcc_error("missing terminating %c character", sep);
} else if (c == '\\') {
if (str)

View file

@ -3032,9 +3032,9 @@ void c99_vla_test_3d(int s, int arr[2][3][s])
printf ("%d\n", arr[1][2][3]);
}
void c99_vla_test_3e(int s, int arr[][3][s])
void c99_vla_test_3e(int s, int arr[][3][--s])
{
printf ("%d\n", arr[1][2][3]);
printf ("%d %d\n", s, arr[1][2][3]);
}
void c99_vla_test_3(void)
@ -3042,12 +3042,12 @@ void c99_vla_test_3(void)
int a[2][3][4];
memset (a, 0, sizeof(a));
a[1][2][3] = 2;
a[1][2][3] = 123;
c99_vla_test_3a(a);
c99_vla_test_3b(2, a);
c99_vla_test_3c(3, a);
c99_vla_test_3d(4, a);
c99_vla_test_3e(4, a);
c99_vla_test_3e(5, a);
}
void c99_vla_test(void)

View file

@ -1150,7 +1150,8 @@ static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *p
size = type_size(ty, &align);
*psize = (size + 7) & ~7;
*palign = (align + 7) & ~7;
*reg_count = 0; /* avoid compiler warning */
if (size > 16) {
mode = x86_64_mode_memory;
} else {