- 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 : revert1de025c13a
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() (fromc3e3a07ed4
) - vla func params: use skip_or_save_block() and enable VT_LVAL (see313855c232
) - 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:
parent
414c22c67b
commit
e41730f11a
9 changed files with 137 additions and 111 deletions
40
libtcc.c
40
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));
|
||||
|
|
8
tcc.c
8
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);
|
||||
|
|
4
tcc.h
4
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"
|
||||
|
|
26
tccdbg.c
26
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;
|
||||
|
|
11
tccelf.c
11
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;
|
||||
|
|
147
tccgen.c
147
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();
|
||||
|
|
1
tccpp.c
1
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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue