From e41730f11a993c64e50f4842b8aec3f888c801c1 Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 20 Aug 2022 12:58:56 +0200 Subject: [PATCH] - 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 1de025c13a5f499c8956412f36e1bffbe4c88b7b 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 c3e3a07ed413a6cb8c1a2b033eb2df07941fead7) - vla func params: use skip_or_save_block() and enable VT_LVAL (see 313855c232710378e1d3fad4fb4455991b9f45e9) - 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 --- libtcc.c | 40 ++++++------- tcc.c | 8 +-- tcc.h | 4 ++ tccdbg.c | 26 ++++----- tccelf.c | 11 +++- tccgen.c | 147 ++++++++++++++++++++++++++---------------------- tccpp.c | 1 + tests/tcctest.c | 8 +-- x86_64-gen.c | 3 +- 9 files changed, 137 insertions(+), 111 deletions(-) diff --git a/libtcc.c b/libtcc.c index c2ec5b61..5d06652b 100644 --- a/libtcc.c +++ b/libtcc.c @@ -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)); diff --git a/tcc.c b/tcc.c index ad9f636a..5850edb5 100644 --- a/tcc.c +++ b/tcc.c @@ -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); diff --git a/tcc.h b/tcc.h index a589ad3c..acdcd3d1 100644 --- a/tcc.h +++ b/tcc.h @@ -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" diff --git a/tccdbg.c b/tccdbg.c index 6cea40c9..9b2b527e 100644 --- a/tccdbg.c +++ b/tccdbg.c @@ -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; diff --git a/tccelf.c b/tccelf.c index 6260bb25..2edf6b83 100644 --- a/tccelf.c +++ b/tccelf.c @@ -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; diff --git a/tccgen.c b/tccgen.c index 2525a3c6..aae4c45c 100644 --- a/tccgen.c +++ b/tccgen.c @@ -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(); diff --git a/tccpp.c b/tccpp.c index 1e688f7c..8100f887 100644 --- a/tccpp.c +++ b/tccpp.c @@ -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) diff --git a/tests/tcctest.c b/tests/tcctest.c index 90e4de72..f5bd9aab 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -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) diff --git a/x86_64-gen.c b/x86_64-gen.c index 26435fa9..0fe9ceee 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -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 {