aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libtcc.c117
-rw-r--r--tcc.c40
-rw-r--r--tcc.h31
-rw-r--r--tccasm.c38
-rw-r--r--tccgen.c92
-rw-r--r--tccpp.c136
-rw-r--r--tccrun.c2
-rw-r--r--tcctools.c107
-rw-r--r--tests/tests2/56_btype_excess-1.c1
-rw-r--r--tests/tests2/56_btype_excess-1.expect1
-rw-r--r--tests/tests2/57_btype_excess-2.c1
-rw-r--r--tests/tests2/57_btype_excess-2.expect1
-rw-r--r--tests/tests2/58_function_redefinition.c9
-rw-r--r--tests/tests2/58_function_redefinition.expect1
-rw-r--r--tests/tests2/59_function_array.c1
-rw-r--r--tests/tests2/59_function_array.expect1
-rw-r--r--tests/tests2/60_enum_redefinition.c4
-rw-r--r--tests/tests2/60_enum_redefinition.expect1
-rw-r--r--tests/tests2/60_errors_and_warnings.c51
-rw-r--r--tests/tests2/60_errors_and_warnings.expect28
-rw-r--r--tests/tests2/61_undefined_enum.c1
-rw-r--r--tests/tests2/61_undefined_enum.expect1
-rw-r--r--tests/tests2/62_enumerator_redefinition.c4
-rw-r--r--tests/tests2/62_enumerator_redefinition.expect1
-rw-r--r--tests/tests2/63_local_enumerator_redefinition.c14
-rw-r--r--tests/tests2/63_local_enumerator_redefinition.expect0
-rw-r--r--tests/tests2/74_nocode_wanted.c1
-rw-r--r--tests/tests2/74_nocode_wanted.expect1
-rw-r--r--tests/tests2/96_nodata_wanted.c46
-rw-r--r--tests/tests2/96_nodata_wanted.expect26
-rw-r--r--tests/tests2/Makefile11
31 files changed, 323 insertions, 446 deletions
diff --git a/libtcc.c b/libtcc.c
index bf13724..c00a909 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -508,8 +508,9 @@ static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
if (!s1->error_func) {
/* default case: stderr */
- if (s1->ppfp) /* print a newline during tcc -E */
- fprintf(s1->ppfp, "\n"), fflush(s1->ppfp);
+ if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
+ /* print a newline during tcc -E */
+ printf("\n"), fflush(stdout);
fflush(stdout); /* flush -v output */
fprintf(stderr, "%s\n", buf);
fflush(stderr); /* print error/warning now (win32) */
@@ -587,6 +588,7 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
bf->fd = -1;
bf->prev = file;
file = bf;
+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
}
ST_FUNC void tcc_close(void)
@@ -622,36 +624,36 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename)
return fd;
}
-/* compile the C file opened in 'file'. Return non zero if errors. */
+/* compile the file opened in 'file'. Return non zero if errors. */
static int tcc_compile(TCCState *s1)
{
Sym *define_start;
+ int filetype, is_asm;
define_start = define_stack;
+ filetype = s1->filetype;
+ is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
+
if (setjmp(s1->error_jmp_buf) == 0) {
s1->nb_errors = 0;
s1->error_set_jmp_enabled = 1;
- preprocess_start(s1);
- tccgen_start(s1);
-#ifdef INC_DEBUG
- printf("%s: **** new file\n", file->filename);
+ preprocess_start(s1, is_asm);
+ if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
+ tcc_preprocess(s1);
+ } else if (is_asm) {
+#ifdef CONFIG_TCC_ASM
+ tcc_assemble(s1, filetype == AFF_TYPE_ASMPP);
+#else
+ tcc_error_noabort("asm not supported");
#endif
- ch = file->buf_ptr[0];
- tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
- parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
- next();
- decl(VT_CONST);
- if (tok != TOK_EOF)
- expect("declaration");
- /* free defines here already on behalf of of M.M.'s possibly existing
- experimental preprocessor implementation. The normal call below
- is still there to free after error-longjmp */
- free_defines(define_start);
- tccgen_end(s1);
+ } else {
+ tccgen_compile(s1);
+ }
}
s1->error_set_jmp_enabled = 0;
+ preprocess_end(s1);
free_inline_functions(s1);
/* reset define stack, but keep -D and built-ins */
free_defines(define_start);
@@ -689,10 +691,8 @@ LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *valu
memcpy(file->buffer + len1 + 1, value, len2);
/* parse with define parser */
- ch = file->buf_ptr[0];
next_nomacro();
parse_define();
-
tcc_close();
}
@@ -713,6 +713,8 @@ static void tcc_cleanup(void)
{
if (NULL == tcc_state)
return;
+ while (file)
+ tcc_close();
tccpp_delete(tcc_state);
tcc_state = NULL;
/* free sym_pools */
@@ -993,26 +995,7 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
{
- int ret, filetype;
-
- filetype = flags & 0x0F;
- if (filetype == 0) {
- /* use a file extension to detect a filetype */
- const char *ext = tcc_fileextension(filename);
- if (ext[0]) {
- ext++;
- if (!strcmp(ext, "S"))
- filetype = AFF_TYPE_ASMPP;
- else if (!strcmp(ext, "s"))
- filetype = AFF_TYPE_ASM;
- else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
- filetype = AFF_TYPE_C;
- else
- filetype = AFF_TYPE_BIN;
- } else {
- filetype = AFF_TYPE_C;
- }
- }
+ int ret;
/* open the file */
ret = tcc_open(s1, filename);
@@ -1026,26 +1009,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
tcc_strdup(filename));
- parse_flags = 0;
- /* if .S file, define __ASSEMBLER__ like gcc does */
- if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) {
- tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
- parse_flags = PARSE_FLAG_ASM_FILE;
- }
-
- if (flags & AFF_PREPROCESS) {
- ret = tcc_preprocess(s1);
- } else if (filetype == AFF_TYPE_C) {
- ret = tcc_compile(s1);
-#ifdef CONFIG_TCC_ASM
- } else if (filetype == AFF_TYPE_ASMPP) {
- /* non preprocessed assembler */
- ret = tcc_assemble(s1, 1);
- } else if (filetype == AFF_TYPE_ASM) {
- /* preprocessed assembler */
- ret = tcc_assemble(s1, 0);
-#endif
- } else {
+ if (flags & AFF_TYPE_BIN) {
ElfW(Ehdr) ehdr;
int fd, obj_type;
@@ -1098,6 +1062,8 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
tcc_error_noabort("unrecognized file type");
break;
}
+ } else {
+ ret = tcc_compile(s1);
}
tcc_close();
return ret;
@@ -1105,10 +1071,27 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
{
- if (s->output_type == TCC_OUTPUT_PREPROCESS)
- return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS | s->filetype);
- else
- return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | s->filetype);
+ int filetype = s->filetype;
+ int flags = AFF_PRINT_ERROR;
+ if (filetype == 0) {
+ /* use a file extension to detect a filetype */
+ const char *ext = tcc_fileextension(filename);
+ if (ext[0]) {
+ ext++;
+ if (!strcmp(ext, "S"))
+ filetype = AFF_TYPE_ASMPP;
+ else if (!strcmp(ext, "s"))
+ filetype = AFF_TYPE_ASM;
+ else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
+ filetype = AFF_TYPE_C;
+ else
+ flags |= AFF_TYPE_BIN;
+ } else {
+ filetype = AFF_TYPE_C;
+ }
+ s->filetype = filetype;
+ }
+ return tcc_add_file_internal(s, filename, flags);
}
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
@@ -1799,8 +1782,8 @@ reparse:
s->dflag = 3;
else if (*optarg == 'M')
s->dflag = 7;
- else if (*optarg == 'T')
- s->do_test = argc;
+ else if (*optarg == 't')
+ s->dflag = 16;
else if (isnum(*optarg))
g_debug = atoi(optarg);
else
diff --git a/tcc.c b/tcc.c
index 769501f..bef02e7 100644
--- a/tcc.c
+++ b/tcc.c
@@ -91,6 +91,7 @@ static const char help2[] =
" -static link to static libraries (not recommended)\n"
" -dumpversion print version\n"
" -print-search-dirs print search paths\n"
+ " -dt with -run/-E: auto-define 'test_...' macros\n"
"Ignored options:\n"
" --param -pedantic -pipe -s -std -traditional\n"
"-W... warnings:\n"
@@ -244,18 +245,21 @@ static unsigned getclock_ms(void)
#endif
}
-int main(int argc, char **argv)
+int main(int argc0, char **argv0)
{
TCCState *s;
- int ret, opt, n = 0;
+ int ret, opt, n = 0, t = 0;
unsigned start_time = 0;
const char *first_file;
+ int argc; char **argv;
+ FILE *ppfp = stdout;
redo:
+ argc = argc0, argv = argv0;
s = tcc_new();
opt = tcc_parse_args(s, &argc, &argv, 1);
- if (n == 0) {
+ if ((n | t) == 0) {
if (opt == OPT_HELP)
return printf(help), 1;
if (opt == OPT_HELP2)
@@ -282,17 +286,11 @@ redo:
n = s->nb_files;
if (n == 0)
tcc_error("no input files\n");
-#ifdef TCC_IS_NATIVE
- if (s->do_test)
- tcc_tool_test(s, argc, argv); /* maybe never returns */
-#endif
if (s->output_type == TCC_OUTPUT_PREPROCESS) {
- if (!s->outfile) {
- s->ppfp = stdout;
- } else {
- s->ppfp = fopen(s->outfile, "w");
- if (!s->ppfp)
+ if (s->outfile) {
+ ppfp = fopen(s->outfile, "w");
+ if (!ppfp)
tcc_error("could not write '%s'", s->outfile);
}
} else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
@@ -313,6 +311,11 @@ redo:
if (s->output_type == 0)
s->output_type = TCC_OUTPUT_EXE;
tcc_set_output_type(s, s->output_type);
+ s->ppfp = ppfp;
+
+ if ((s->output_type == TCC_OUTPUT_MEMORY
+ || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16))
+ s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files;
/* compile or add each files or library */
for (first_file = NULL, ret = 0;;) {
@@ -338,8 +341,7 @@ redo:
}
if (s->output_type == TCC_OUTPUT_PREPROCESS) {
- if (s->outfile)
- fclose(s->ppfp);
+ ;
} else if (0 == ret) {
if (s->output_type == TCC_OUTPUT_MEMORY) {
#ifdef TCC_IS_NATIVE
@@ -355,10 +357,18 @@ redo:
}
}
- if (s->do_bench && ret == 0 && n == 0)
+ if (t)
+ ret = 0;
+ if (s->run_test)
+ t = 0;
+ if (s->do_bench && (n | t | ret) == 0)
tcc_print_stats(s, getclock_ms() - start_time);
tcc_delete(s);
if (ret == 0 && n)
goto redo; /* compile more files with -c */
+ if (t)
+ goto redo; /* run more tests with -dt -run */
+ if (ppfp && ppfp != stdout)
+ fclose(ppfp);
return ret;
}
diff --git a/tcc.h b/tcc.h
index 4113028..4b272f5 100644
--- a/tcc.h
+++ b/tcc.h
@@ -556,15 +556,6 @@ typedef struct BufferedFile {
#define CH_EOB '\\' /* end of buffer or '\0' char in file */
#define CH_EOF (-1) /* end of file */
-/* parsing state (used to save parser state to reparse part of the
- source several times) */
-typedef struct ParseState {
- const int *macro_ptr;
- int line_num;
- int tok;
- CValue tokc;
-} ParseState;
-
/* used to record tokens */
typedef struct TokenString {
int *str;
@@ -572,6 +563,7 @@ typedef struct TokenString {
int lastlen;
int allocated_len;
int last_line_num;
+ int save_line_num;
/* used to chain token-strings with begin/end_macro() */
struct TokenString *prev;
const int *prev_ptr;
@@ -675,6 +667,7 @@ struct TCCState {
#ifdef TCC_TARGET_ARM
enum float_abi float_abi; /* float ABI of the generated code*/
#endif
+ int run_test; /* nth test to run with -dt -run */
addr_t text_addr; /* address of text section */
int has_text_addr;
@@ -813,7 +806,6 @@ struct TCCState {
int option_pthread; /* -pthread option */
int argc;
char **argv;
- int do_test;
};
struct filespec {
@@ -1145,14 +1137,13 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
/* flags: */
#define AFF_PRINT_ERROR 0x10 /* print error if file not found */
#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */
-#define AFF_PREPROCESS 0x40 /* preprocess file */
-/* combined with: */
+#define AFF_TYPE_BIN 0x40 /* file to add is binary */
+/* s->filetype: */
#define AFF_TYPE_NONE 0
#define AFF_TYPE_C 1
#define AFF_TYPE_ASM 2
#define AFF_TYPE_ASMPP 3
-#define AFF_TYPE_BIN 4
-#define AFF_TYPE_LIB 5
+#define AFF_TYPE_LIB 4
/* values from tcc_object_type(...) */
#define AFF_BINTYPE_REL 1
#define AFF_BINTYPE_DYN 2
@@ -1220,9 +1211,7 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len);
ST_FUNC const char *get_tok_str(int v, CValue *cv);
ST_FUNC void begin_macro(TokenString *str, int alloc);
ST_FUNC void end_macro(void);
-ST_FUNC void set_idnum(int c, int val);
-ST_FUNC void save_parse_state(ParseState *s);
-ST_FUNC void restore_parse_state(ParseState *s);
+ST_FUNC int set_idnum(int c, int val);
ST_INLN void tok_str_new(TokenString *s);
ST_FUNC TokenString *tok_str_alloc(void);
ST_FUNC void tok_str_free(TokenString *s);
@@ -1241,7 +1230,8 @@ ST_FUNC void preprocess(int is_bof);
ST_FUNC void next_nomacro(void);
ST_FUNC void next(void);
ST_INLN void unget_tok(int last_tok);
-ST_FUNC void preprocess_start(TCCState *s1);
+ST_FUNC void preprocess_start(TCCState *s1, int is_asm);
+ST_FUNC void preprocess_end(TCCState *s1);
ST_FUNC void tccpp_new(TCCState *s);
ST_FUNC void tccpp_delete(TCCState *s);
ST_FUNC int tcc_preprocess(TCCState *s1);
@@ -1298,9 +1288,7 @@ ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym);
ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
ST_FUNC void tcc_debug_line(TCCState *s1);
-ST_FUNC void tccgen_start(TCCState *s1);
-ST_FUNC void tccgen_end(TCCState *s1);
-
+ST_FUNC int tccgen_compile(TCCState *s1);
ST_FUNC void free_inline_functions(TCCState *s);
ST_FUNC void check_vstack(void);
@@ -1342,7 +1330,6 @@ ST_FUNC void expr_prod(void);
ST_FUNC void expr_sum(void);
ST_FUNC void gexpr(void);
ST_FUNC int expr_const(void);
-ST_FUNC void decl(int l);
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
#endif
diff --git a/tccasm.c b/tccasm.c
index 59264ce..1e20dc6 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -628,20 +628,16 @@ static void asm_parse_directive(TCCState *s1, int global)
{
int repeat;
TokenString *init_str;
- ParseState saved_parse_state = {0};
next();
repeat = asm_int_expr(s1);
init_str = tok_str_alloc();
- next();
- while ((tok != TOK_ASMDIR_endr) && (tok != CH_EOF)) {
+ while (next(), tok != TOK_ASMDIR_endr) {
+ if (tok == CH_EOF)
+ tcc_error("we at end of file, .endr not found");
tok_str_add_tok(init_str);
- next();
}
- if (tok == CH_EOF) tcc_error("we at end of file, .endr not found");
- next();
tok_str_add(init_str, -1);
tok_str_add(init_str, 0);
- save_parse_state(&saved_parse_state);
begin_macro(init_str, 1);
while (repeat-- > 0) {
tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
@@ -649,7 +645,7 @@ static void asm_parse_directive(TCCState *s1, int global)
macro_ptr = init_str->str;
}
end_macro();
- restore_parse_state(&saved_parse_state);
+ next();
break;
}
case TOK_ASMDIR_org:
@@ -917,13 +913,10 @@ static void asm_parse_directive(TCCState *s1, int global)
static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
{
int opcode;
+ int saved_parse_flags = parse_flags;
/* XXX: undefine C labels */
-
- ch = file->buf_ptr[0];
- tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
- set_idnum('.', IS_ID);
if (do_preprocess)
parse_flags |= PARSE_FLAG_PREPROCESS;
for(;;) {
@@ -990,30 +983,22 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
}
asm_free_labels(s1);
+ parse_flags = saved_parse_flags;
return 0;
}
/* Assemble the current file */
ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
{
- Sym *define_start;
int ret;
-
- define_start = define_stack;
- preprocess_start(s1);
tcc_debug_start(s1);
-
/* default section is text */
cur_text_section = text_section;
ind = cur_text_section->data_offset;
nocode_wanted = 0;
-
ret = tcc_assemble_internal(s1, do_preprocess, 1);
-
cur_text_section->data_offset = ind;
-
tcc_debug_end(s1);
- free_defines(define_start);
return ret;
}
@@ -1025,21 +1010,16 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
end */
static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
{
- int saved_parse_flags;
- const int *saved_macro_ptr;
-
- saved_parse_flags = parse_flags;
- saved_macro_ptr = macro_ptr;
+ const int *saved_macro_ptr = macro_ptr;
+ int dotid = set_idnum('.', IS_ID);
tcc_open_bf(s1, ":asm:", len);
memcpy(file->buffer, str, len);
-
macro_ptr = NULL;
tcc_assemble_internal(s1, 0, global);
tcc_close();
- parse_flags = saved_parse_flags;
- set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
+ set_idnum('.', dotid);
macro_ptr = saved_macro_ptr;
}
diff --git a/tccgen.c b/tccgen.c
index acba740..d53c6b7 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -84,6 +84,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c);
static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
static void block(int *bsym, int *csym, int is_expr);
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
+static void decl(int l);
static int decl0(int l, int is_for_loop_init, Sym *);
static void expr_eq(void);
static void vla_runtime_type_size(CType *type, int *a);
@@ -91,9 +92,9 @@ static void vla_sp_restore(void);
static void vla_sp_restore_root(void);
static int is_compatible_unqualified_types(CType *type1, CType *type2);
static inline int64_t expr_const64(void);
-ST_FUNC void vpush64(int ty, unsigned long long v);
-ST_FUNC void vpush(CType *type);
-ST_FUNC int gvtst(int inv, int t);
+static void vpush64(int ty, unsigned long long v);
+static void vpush(CType *type);
+static int gvtst(int inv, int t);
static void gen_inline_functions(TCCState *s);
static void skip_or_save_block(TokenString **str);
static void gv_dup(void);
@@ -225,7 +226,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
}
/* ------------------------------------------------------------------------- */
-ST_FUNC void tccgen_start(TCCState *s1)
+ST_FUNC int tccgen_compile(TCCState *s1)
{
cur_text_section = NULL;
funcname = "";
@@ -253,14 +254,22 @@ ST_FUNC void tccgen_start(TCCState *s1)
#ifdef TCC_TARGET_ARM
arm_init(s1);
#endif
-}
-ST_FUNC void tccgen_end(TCCState *s1)
-{
+#ifdef INC_DEBUG
+ printf("%s: **** new file\n", file->filename);
+#endif
+
+ parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
+ next();
+ decl(VT_CONST);
+ if (tok != TOK_EOF)
+ expect("declaration");
+
gen_inline_functions(s1);
check_vstack();
/* end of translation unit info */
tcc_debug_end(s1);
+ return 0;
}
/* ------------------------------------------------------------------------- */
@@ -4441,15 +4450,11 @@ static void gfunc_param_typed(Sym *func, Sym *arg)
}
}
-/* parse an expression and return its type without any side effect.
- If UNRY we parse an unary expression, otherwise a full one. */
-static void expr_type(CType *type, int unry)
+/* parse an expression and return its type without any side effect. */
+static void expr_type(CType *type, void (*expr_fn)(void))
{
nocode_wanted++;
- if (unry)
- unary();
- else
- gexpr();
+ expr_fn();
*type = vtop->type;
vpop();
nocode_wanted--;
@@ -4466,7 +4471,7 @@ static void parse_expr_type(CType *type)
if (parse_btype(type, &ad)) {
type_decl(type, &ad, &n, TYPE_ABSTRACT);
} else {
- expr_type(type, 0);
+ expr_type(type, gexpr);
}
skip(')');
}
@@ -4694,7 +4699,7 @@ ST_FUNC void unary(void)
t = tok;
next();
in_sizeof++;
- expr_type(&type, 1); // Perform a in_sizeof = 0;
+ expr_type(&type, unary); /* Perform a in_sizeof = 0; */
s = vtop[1].sym; /* hack: accessing previous vtop */
size = type_size(&type, &align);
if (s && s->a.aligned)
@@ -4896,70 +4901,60 @@ ST_FUNC void unary(void)
CType controlling_type;
int has_default = 0;
int has_match = 0;
- CType cur_type;
- AttributeDef ad_tmp;
int learn = 0;
TokenString *str = NULL;
- ParseState saved_parse_state;
next();
skip('(');
- expr_type(&controlling_type, 1);
- if (controlling_type.t & VT_ARRAY)
- controlling_type.t = VT_PTR;
- controlling_type.t &= ~VT_CONSTANT;
- controlling_type.t &= ~VT_VOLATILE;
+ expr_type(&controlling_type, expr_eq);
+ controlling_type.t &= ~(VT_CONSTANT|VT_VOLATILE|VT_ARRAY);
for (;;) {
learn = 0;
skip(',');
if (tok == TOK_DEFAULT) {
if (has_default)
tcc_error("too many 'default'");
- if (!has_match) {
- has_default = 1;
+ has_default = 1;
+ if (!has_match)
learn = 1;
- }
next();
} else {
+ AttributeDef ad_tmp;
int itmp;
-
+ CType cur_type;
parse_btype(&cur_type, &ad_tmp);
type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
if (compare_types(&controlling_type, &cur_type, 0)) {
if (has_match) {
// tcc_error("type match twice");
}
- if (str)
- tok_str_free(str);
has_match = 1;
learn = 1;
}
}
skip(':');
if (learn) {
+ if (str)
+ tok_str_free(str);
skip_or_save_block(&str);
} else {
skip_or_save_block(NULL);
}
- if (tok == ',')
- continue;
- else if (tok == ')')
+ if (tok == ')')
break;
}
- if (!has_match && !has_default) {
- char buf[256];
-
- type_to_str(buf, 256, &controlling_type, NULL);
- tcc_error("_Generic selector of type '%s' is not compatible with any assosiation",
- buf);
+ if (!str) {
+ char buf[60];
+ type_to_str(buf, sizeof buf, &controlling_type, NULL);
+ tcc_error("type '%s' does not match any association", buf);
}
- skip(')');
- save_parse_state(&saved_parse_state);
begin_macro(str, 1);
next();
expr_eq();
+ if (tok != TOK_EOF)
+ expect(",");
end_macro();
- restore_parse_state(&saved_parse_state);
+ next();
break;
}
// special qnan , snan and infinity values
@@ -5599,7 +5594,9 @@ ST_FUNC void gexpr(void)
static void expr_const1(void)
{
const_wanted++;
+ nocode_wanted++;
expr_cond();
+ nocode_wanted--;
const_wanted--;
}
@@ -6721,8 +6718,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
int has_init, int v, int scope)
{
int size, align, addr;
- ParseState saved_parse_state = {0};
TokenString *init_str = NULL;
+
Section *sec;
Sym *flexible_array;
Sym *sym = NULL;
@@ -6768,10 +6765,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
} else {
skip_or_save_block(&init_str);
}
-
- /* compute size */
- save_parse_state(&saved_parse_state);
+ unget_tok(0);
+ /* compute size */
begin_macro(init_str, 1);
next();
decl_initializer(type, NULL, 0, 1, 1);
@@ -6959,7 +6955,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
/* restore parse state if needed */
if (init_str) {
end_macro();
- restore_parse_state(&saved_parse_state);
+ next();
}
nocode_wanted = saved_nocode_wanted;
@@ -7328,7 +7324,7 @@ found:
return 0;
}
-ST_FUNC void decl(int l)
+static void decl(int l)
{
decl0(l, 0, NULL);
}
diff --git a/tccpp.c b/tccpp.c
index 0e46510..8d003d7 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -820,9 +820,11 @@ ST_FUNC uint8_t *parse_comment(uint8_t *p)
return p;
}
-ST_FUNC void set_idnum(int c, int val)
+ST_FUNC int set_idnum(int c, int val)
{
+ int prev = isidnum_table[c - CH_EOF];
isidnum_table[c - CH_EOF] = val;
+ return prev;
}
#define cinp minp
@@ -999,30 +1001,6 @@ _default:
file->buf_ptr = p;
}
-/* ParseState handling */
-
-/* XXX: currently, no include file info is stored. Thus, we cannot display
- accurate messages if the function or data definition spans multiple
- files */
-
-/* save current parse state in 's' */
-ST_FUNC void save_parse_state(ParseState *s)
-{
- s->line_num = file->line_num;
- s->macro_ptr = macro_ptr;
- s->tok = tok;
- s->tokc = tokc;
-}
-
-/* restore parse state from 's' */
-ST_FUNC void restore_parse_state(ParseState *s)
-{
- file->line_num = s->line_num;
- macro_ptr = s->macro_ptr;
- tok = s->tok;
- tokc = s->tokc;
-}
-
#if 0
/* return the number of additional 'ints' necessary to store the
token */
@@ -1124,6 +1102,7 @@ ST_FUNC void begin_macro(TokenString *str, int alloc)
str->alloc = alloc;
str->prev = macro_stack;
str->prev_ptr = macro_ptr;
+ str->save_line_num = file->line_num;
macro_ptr = str->str;
macro_stack = str;
}
@@ -1133,6 +1112,7 @@ ST_FUNC void end_macro(void)
TokenString *str = macro_stack;
macro_stack = str->prev;
macro_ptr = str->prev_ptr;
+ file->line_num = str->save_line_num;
if (str->alloc == 2) {
str->alloc = 3; /* just mark as finished */
} else {
@@ -1402,6 +1382,21 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep)
*ptop = slast;
}
+/* fake the nth "#if defined test_..." for tcc -dt -run */
+static void maybe_run_test(TCCState *s, int *c)
+{
+ const char *p;
+ if (s->include_stack_ptr != s->include_stack)
+ return;
+ p = get_tok_str(tok, NULL);
+ if (0 != memcmp(p, "test_", 5))
+ return;
+ if (0 != --s->run_test)
+ return;
+ fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp);
+ *c = 1;
+}
+
/* eval an expression for #if/#elif */
static int expr_preprocess(void)
{
@@ -1420,6 +1415,8 @@ static int expr_preprocess(void)
if (tok < TOK_IDENT)
expect("identifier");
c = define_find(tok) != 0;
+ if (tcc_state->run_test)
+ maybe_run_test(tcc_state, &c);
if (t == '(') {
next_nomacro();
if (tok != ')')
@@ -1467,7 +1464,7 @@ ST_FUNC void parse_define(void)
/* '(' must be just after macro definition for MACRO_FUNC */
next_nomacro_spc();
if (tok == '(') {
- set_idnum('.', 0);
+ int dotid = set_idnum('.', 0);
next_nomacro();
ps = &first;
if (tok != ')') for (;;) {
@@ -1495,6 +1492,7 @@ ST_FUNC void parse_define(void)
}
next_nomacro_spc();
t = MACRO_FUNC;
+ set_idnum('.', dotid);
}
tokstr_buf.len = 0;
@@ -1505,7 +1503,6 @@ ST_FUNC void parse_define(void)
ID character in asm mode). But '#' should be retained instead of
regarded as line comment leader, so still don't set ASM_FILE
in parse_flags. */
- set_idnum('.', (saved_parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
while (tok != TOK_LINEFEED && tok != TOK_EOF) {
/* remove spaces around ## and after '#' */
if (TOK_TWOSHARPS == tok) {
@@ -1613,7 +1610,7 @@ static void pragma_parse(TCCState *s1)
} else if (tok == TOK_once) {
search_cached_include(s1, file->filename, 1)->once = pp_once;
- } else if (s1->ppfp) {
+ } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
/* tcc -E: keep pragmas below unchanged */
unget_tok(' ');
unget_tok(TOK_PRAGMA);
@@ -3043,6 +3040,7 @@ static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
tcc_open_bf(tcc_state, ":paste:", cstr.size);
memcpy(file->buffer, cstr.data, cstr.size);
+ tok_flags = 0;
for (;;) {
next_nomacro1();
if (0 == *file->buf_ptr)
@@ -3164,6 +3162,8 @@ static int next_argstream(Sym **nested_list, TokenString *ws_str)
break;
ch = ' ';
}
+ if (ch == '\n')
+ file->line_num++;
if (!(ch == '\f' || ch == '\v' || ch == '\r'))
tok_str_add(ws_str, ch);
cinp();
@@ -3483,7 +3483,7 @@ ST_INLN void unget_tok(int last_tok)
tok = last_tok;
}
-ST_FUNC void preprocess_start(TCCState *s1)
+ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
{
char *buf;
@@ -3496,7 +3496,7 @@ ST_FUNC void preprocess_start(TCCState *s1)
s1->pack_stack_ptr = s1->pack_stack;
set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
- set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
+ set_idnum('.', is_asm ? IS_ID : 0);
buf = tcc_malloc(3 + strlen(file->filename));
sprintf(buf, "\"%s\"", file->filename);
@@ -3517,6 +3517,20 @@ ST_FUNC void preprocess_start(TCCState *s1)
memcpy(file->buffer, cstr.data, cstr.size);
cstr_free(&cstr);
}
+
+ if (is_asm)
+ tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
+
+ parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0;
+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+}
+
+/* cleanup from error/setjmp */
+ST_FUNC void preprocess_end(TCCState *s1)
+{
+ while (macro_stack)
+ end_macro();
+ macro_ptr = NULL;
}
ST_FUNC void tccpp_new(TCCState *s)
@@ -3526,6 +3540,7 @@ ST_FUNC void tccpp_new(TCCState *s)
/* might be used in error() before preprocess_start() */
s->include_stack_ptr = s->include_stack;
+ s->ppfp = stdout;
/* init isid table */
for(i = CH_EOF; i<128; i++)
@@ -3570,14 +3585,6 @@ ST_FUNC void tccpp_delete(TCCState *s)
/* free -D and compiler defines */
free_defines(NULL);
- /* cleanup from error/setjmp */
- while (macro_stack)
- end_macro();
- macro_ptr = NULL;
-
- while (file)
- tcc_close();
-
/* free tokens */
n = tok_ident - TOK_IDENT;
for(i = 0; i < n; i++)
@@ -3606,19 +3613,16 @@ ST_FUNC void tccpp_delete(TCCState *s)
static void tok_print(const char *msg, const int *str)
{
FILE *fp;
- int t;
+ int t, s = 0;
CValue cval;
fp = tcc_state->ppfp;
- if (!fp || !tcc_state->dflag)
- fp = stdout;
-
- fprintf(fp, "%s ", msg);
+ fprintf(fp, "%s", msg);
while (str) {
TOK_GET(&t, &str, &cval);
if (!t)
break;
- fprintf(fp,"%s", get_tok_str(t, &cval));
+ fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1;
}
fprintf(fp, "\n");
}
@@ -3731,20 +3735,14 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
BufferedFile **iptr;
int token_seen, spcs, level;
const char *p;
- Sym *define_start;
+ char white[400];
- define_start = define_stack;
- preprocess_start(s1);
-
- ch = file->buf_ptr[0];
- tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
parse_flags = PARSE_FLAG_PREPROCESS
| (parse_flags & PARSE_FLAG_ASM_FILE)
| PARSE_FLAG_LINEFEED
| PARSE_FLAG_SPACES
| PARSE_FLAG_ACCEPT_STRAYS
;
-
/* Credits to Fabrice Bellard's initial revision to demonstrate its
capability to compile and run itself, provided all numbers are
given as decimals. tcc -E -P10 will do. */
@@ -3754,7 +3752,6 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
#ifdef PP_BENCH
/* for PP benchmarks */
do next(); while (tok != TOK_EOF);
- free_defines(define_start);
return 0;
#endif
@@ -3765,48 +3762,43 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
token_seen = TOK_LINEFEED, spcs = 0;
pp_line(s1, file, 0);
-
for (;;) {
iptr = s1->include_stack_ptr;
next();
if (tok == TOK_EOF)
break;
+
level = s1->include_stack_ptr - iptr;
if (level) {
if (level > 0)
pp_line(s1, *iptr, 0);
pp_line(s1, file, level);
}
-
- if (s1->dflag) {
+ if (s1->dflag & 7) {
pp_debug_defines(s1);
if (s1->dflag & 4)
continue;
}
- if (token_seen == TOK_LINEFEED) {
- if (tok == ' ') {
- ++spcs;
- continue;
- }
- if (tok == TOK_LINEFEED) {
- spcs = 0;
- continue;
- }
- pp_line(s1, file, 0);
+ if (is_space(tok)) {
+ if (spcs < sizeof white - 1)
+ white[spcs++] = tok;
+ continue;
} else if (tok == TOK_LINEFEED) {
+ spcs = 0;
+ if (token_seen == TOK_LINEFEED)
+ continue;
++file->line_ref;
- } else {
- spcs = pp_need_space(token_seen, tok);
+ } else if (token_seen == TOK_LINEFEED) {
+ pp_line(s1, file, 0);
+ } else if (spcs == 0 && pp_need_space(token_seen, tok)) {
+ white[spcs++] = ' ';
}
- while (spcs)
- fputs(" ", s1->ppfp), --spcs;
+ white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0;
fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
- token_seen = pp_check_he0xE(tok, p);;
+ token_seen = pp_check_he0xE(tok, p);
}
- /* reset define stack, but keep -D and built-ins */
- free_defines(define_start);
return 0;
}
diff --git a/tccrun.c b/tccrun.c
index 950ffb0..85957b8 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -108,6 +108,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
int (*prog_main)(int, char **);
s1->runtime_main = "main";
+ if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main))
+ return 0;
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
return -1;
prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
diff --git a/tcctools.c b/tcctools.c
index cfcb03d..53d88be 100644
--- a/tcctools.c
+++ b/tcctools.c
@@ -543,111 +543,4 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
fclose(depout);
}
-#ifdef TCC_IS_NATIVE
-/* -------------------------------------------------------------- */
-/* run test snippets from file */
-
-static char *readfile(const char *fname)
-{
- char *buf;
- int fsize;
- FILE *fi;
- fi = fopen(fname, "rb");
- if (!fi)
- return NULL;
- fseek(fi, 0, SEEK_END);
- fsize = ftell(fi);
- fseek(fi, 0, SEEK_SET);
- buf = tcc_malloc(fsize + 1);
- fread(buf, fsize, 1, fi);
- fclose(fi);
- buf[fsize] = 0;
- return buf;
-}
-
-static int run_prog(const char *prog, int ac, char **av)
-{
- TCCState *s;
- int (*func)(int, char**);
- int ret = -10000;
-
- s = tcc_new();
- tcc_parse_args(s, &ac, &av, 1);
- tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
- if (tcc_compile_string(s, prog) == -1)
- goto done;
- if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
- goto done;
- func = tcc_get_symbol(s, "main");
- if (!func)
- goto done;
- ret = func(ac, av);
-done:
- tcc_delete(s);
- return ret;
-}
-
-static char *trimback(char *a, char *e)
-{
- while (e > a && (unsigned char)e[-1] <= ' ')
- --e;
- *e = 0;;
- return a;
-}
-
-ST_FUNC int tcc_tool_test(TCCState *s, int argc, char **argv)
-{
- const char *fname;
- char *buf, *p, *a, *b, *e, tmp[100];
- int r = 0, c, n;
- const char sep[] = "/*-* test";
-
- n = s->do_test - argc;
- if (!n)
- return 0;
- fname = argv[0], argv -= n, argc += n;
-
- buf = readfile(fname);
- if (NULL == buf)
- return -1;
- p = strstr(buf, sep);
- if (!p) {
- tcc_free(buf);
- return -1;
- }
-
- while (*p) {
- a = p, p = strchr(p, '\n');
- if (NULL == p)
- break;
- *p++ = 0;
- b = p, p = strstr(p, sep);
- if (NULL == p)
- p = strchr(b, 0);
- c = *p, *p = 0;
-
- trimback(a, b);
- if (r)
- printf("\n");
- printf("%s\n", a);
- fflush(stdout);
-
- e = a += sizeof sep - 5;
- while (*e && *e != ':')
- ++e;
- if (!*e || e - a > 32)
- e = a + 4;
- n = snprintf(tmp, sizeof tmp, "#line 1 \"%.*s\"\n", (int)(e - a), a);
- if (b - buf >= n)
- b = memcpy(b - n, tmp, n);
- n = run_prog(b, argc, argv);
- if (n != -10000)
- printf("returns %d\n", n);
- *p = c, ++r;
- }
- tcc_free(buf);
- exit(0);
-}
-#endif /* TCC_IS_NATIVE */
-
/* -------------------------------------------------------------- */
diff --git a/tests/tests2/56_btype_excess-1.c b/tests/tests2/56_btype_excess-1.c
deleted file mode 100644
index 06eabe7..0000000
--- a/tests/tests2/56_btype_excess-1.c
+++ /dev/null
@@ -1 +0,0 @@
-struct A {} int i;
diff --git a/tests/tests2/56_btype_excess-1.expect b/tests/tests2/56_btype_excess-1.expect
deleted file mode 100644
index 4e6d2d7..0000000
--- a/tests/tests2/56_btype_excess-1.expect
+++ /dev/null
@@ -1 +0,0 @@
-56_btype_excess-1.c:1: error: too many basic types
diff --git a/tests/tests2/57_btype_excess-2.c b/tests/tests2/57_btype_excess-2.c
deleted file mode 100644
index ab95c3e..0000000
--- a/tests/tests2/57_btype_excess-2.c
+++ /dev/null
@@ -1 +0,0 @@
-char int i;
diff --git a/tests/tests2/57_btype_excess-2.expect b/tests/tests2/57_btype_excess-2.expect
deleted file mode 100644
index c12ef81..0000000
--- a/tests/tests2/57_btype_excess-2.expect
+++ /dev/null
@@ -1 +0,0 @@
-57_btype_excess-2.c:1: error: too many basic types
diff --git a/tests/tests2/58_function_redefinition.c b/tests/tests2/58_function_redefinition.c
deleted file mode 100644
index 33f16ee..0000000
--- a/tests/tests2/58_function_redefinition.c
+++ /dev/null
@@ -1,9 +0,0 @@
-int f(void)
-{
- return 0;
-}
-
-int f(void)
-{
- return 1;
-}
diff --git a/tests/tests2/58_function_redefinition.expect b/tests/tests2/58_function_redefinition.expect
deleted file mode 100644
index a95a3f0..0000000
--- a/tests/tests2/58_function_redefinition.expect
+++ /dev/null
@@ -1 +0,0 @@
-58_function_redefinition.c:7: error: redefinition of 'f'
diff --git a/tests/tests2/59_function_array.c b/tests/tests2/59_function_array.c
deleted file mode 100644
index 9fcc12d..0000000
--- a/tests/tests2/59_function_array.c
+++ /dev/null
@@ -1 +0,0 @@
-int (*fct)[42](int x);
diff --git a/tests/tests2/59_function_array.expect b/tests/tests2/59_function_array.expect
deleted file mode 100644
index bf62c6e..0000000
--- a/tests/tests2/59_function_array.expect
+++ /dev/null
@@ -1 +0,0 @@
-59_function_array.c:1: error: declaration of an array of functions
diff --git a/tests/tests2/60_enum_redefinition.c b/tests/tests2/60_enum_redefinition.c
deleted file mode 100644
index 2601560..0000000
--- a/tests/tests2/60_enum_redefinition.c
+++ /dev/null
@@ -1,4 +0,0 @@
-enum color {RED, GREEN, BLUE};
-enum color {R, G, B};
-
-enum color c;
diff --git a/tests/tests2/60_enum_redefinition.expect b/tests/tests2/60_enum_redefinition.expect
deleted file mode 100644
index 5cb41bc..0000000
--- a/tests/tests2/60_enum_redefinition.expect
+++ /dev/null
@@ -1 +0,0 @@
-60_enum_redefinition.c:2: error: struct/union/enum already defined
diff --git a/tests/tests2/60_errors_and_warnings.c b/tests/tests2/60_errors_and_warnings.c
new file mode 100644
index 0000000..0028caf
--- /dev/null
+++ b/tests/tests2/60_errors_and_warnings.c
@@ -0,0 +1,51 @@
+#if defined test_56_btype_excess_1
+struct A {} int i;
+
+#elif defined test_57_btype_excess_2
+char int i;
+
+#elif defined test_58_function_redefinition
+int f(void) { return 0; }
+int f(void) { return 1; }
+
+#elif defined test_global_redefinition
+int xxx = 1;
+int xxx;
+int xxx = 2;
+
+#elif defined test_59_function_array
+int (*fct)[42](int x);
+
+#elif defined test_60_enum_redefinition
+enum color { RED, GREEN, BLUE };
+enum color { R, G, B };
+enum color c;
+
+#elif defined test_62_enumerator_redefinition
+enum color { RED, GREEN, BLUE };
+enum rgb { RED, G, B};
+enum color c = RED;
+
+#elif defined test_63_local_enumerator_redefinition
+enum {
+ FOO,
+ BAR
+};
+
+int main(void)
+{
+ enum {
+ FOO = 2,
+ BAR
+ };
+
+ return BAR - FOO;
+}
+
+#elif defined test_61_undefined_enum
+enum rgb3 c = 42;
+
+#elif defined test_74_non_const_init
+int i = i++;
+
+#endif
diff --git a/tests/tests2/60_errors_and_warnings.expect b/tests/tests2/60_errors_and_warnings.expect
new file mode 100644
index 0000000..ed6a690
--- /dev/null
+++ b/tests/tests2/60_errors_and_warnings.expect
@@ -0,0 +1,28 @@
+[test_56_btype_excess_1]
+60_errors_and_warnings.c:2: error: too many basic types
+
+[test_57_btype_excess_2]
+60_errors_and_warnings.c:5: error: too many basic types
+
+[test_58_function_redefinition]
+60_errors_and_warnings.c:9: error: redefinition of 'f'
+
+[test_global_redefinition]
+60_errors_and_warnings.c:14: error: redefinition of 'xxx'
+
+[test_59_function_array]
+60_errors_and_warnings.c:17: error: declaration of an array of functions
+
+[test_60_enum_redefinition]
+60_errors_and_warnings.c:21: error: struct/union/enum already defined
+
+[test_62_enumerator_redefinition]
+60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED'
+
+[test_63_local_enumerator_redefinition]
+
+[test_61_undefined_enum]
+60_errors_and_warnings.c:46: error: unknown type size
+
+[test_74_non_const_init]
+60_errors_and_warnings.c:49: error: initializer element is not constant
diff --git a/tests/tests2/61_undefined_enum.c b/tests/tests2/61_undefined_enum.c
deleted file mode 100644
index bc7c6ea..0000000
--- a/tests/tests2/61_undefined_enum.c
+++ /dev/null
@@ -1 +0,0 @@
-enum rgb c = 42;
diff --git a/tests/tests2/61_undefined_enum.expect b/tests/tests2/61_undefined_enum.expect
deleted file mode 100644
index eb8b774..0000000
--- a/tests/tests2/61_undefined_enum.expect
+++ /dev/null
@@ -1 +0,0 @@
-61_undefined_enum.c:1: error: unknown type size
diff --git a/tests/tests2/62_enumerator_redefinition.c b/tests/tests2/62_enumerator_redefinition.c
deleted file mode 100644
index 3da85ae..0000000
--- a/tests/tests2/62_enumerator_redefinition.c
+++ /dev/null
@@ -1,4 +0,0 @@
-enum color {RED, GREEN, BLUE};
-enum rgb {RED, G, B};
-
-enum color c = RED;
diff --git a/tests/tests2/62_enumerator_redefinition.expect b/tests/tests2/62_enumerator_redefinition.expect
deleted file mode 100644
index 3d0e879..0000000
--- a/tests/tests2/62_enumerator_redefinition.expect
+++ /dev/null
@@ -1 +0,0 @@
-62_enumerator_redefinition.c:2: error: redefinition of enumerator 'RED'
diff --git a/tests/tests2/63_local_enumerator_redefinition.c b/tests/tests2/63_local_enumerator_redefinition.c
deleted file mode 100644
index dd4d8e0..0000000
--- a/tests/tests2/63_local_enumerator_redefinition.c
+++ /dev/null
@@ -1,14 +0,0 @@
-enum {
- FOO,
- BAR
-};
-
-int main(void)
-{
- enum {
- FOO = 2,
- BAR
- };
-
- return BAR - FOO;
-}
diff --git a/tests/tests2/63_local_enumerator_redefinition.expect b/tests/tests2/63_local_enumerator_redefinition.expect
deleted file mode 100644
index e69de29..0000000
--- a/tests/tests2/63_local_enumerator_redefinition.expect
+++ /dev/null
diff --git a/tests/tests2/74_nocode_wanted.c b/tests/tests2/74_nocode_wanted.c
deleted file mode 100644
index e824d02..0000000
--- a/tests/tests2/74_nocode_wanted.c
+++ /dev/null
@@ -1 +0,0 @@
-int i = i++;
diff --git a/tests/tests2/74_nocode_wanted.expect b/tests/tests2/74_nocode_wanted.expect
deleted file mode 100644
index f060ef4..0000000
--- a/tests/tests2/74_nocode_wanted.expect
+++ /dev/null
@@ -1 +0,0 @@
-74_nocode_wanted.c:1: error: initializer element is not constant
diff --git a/tests/tests2/96_nodata_wanted.c b/tests/tests2/96_nodata_wanted.c
index 6f7f3c2..1f022c9 100644
--- a/tests/tests2/96_nodata_wanted.c
+++ b/tests/tests2/96_nodata_wanted.c
@@ -1,36 +1,35 @@
/*****************************************************************************/
/* test 'nodata_wanted' data output suppression */
-/*-* test 1: initializer not computable 1 */
+#if defined test_static_data_error
void foo() {
if (1) {
- static short w = (int)&foo; /* error */
+ static short w = (int)&foo; /* initializer not computable */
}
}
-/*-* test 2: initializer not computable 2 */
+#elif defined test_static_nodata_error
void foo() {
if (0) {
- static short w = (int)&foo; /* error */
+ static short w = (int)&foo; /* initializer not computable */
}
}
-/*-* test 3: initializer not computable 3 */
+#elif defined test_global_data_error
void foo();
-static short w = (int)&foo; /* error */
+static short w = (int)&foo; /* initializer not computable */
-/*-* test 4: 2 cast warnings */
+#elif defined test_local_data_noerror
void foo() {
- short w = &foo; /* no error */
+ short w = &foo; /* 2 cast warnings */
}
-/*-* test 5; nodata_wanted test */
+#elif defined test_data_suppression
#include <stdio.h>
-#define DATA_LBL(s) \
- __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n"); \
- extern char d##s[],t##s[];
+#define ASMLABELS(s) \
+ __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n")
#define PROG \
static void *p = (void*)&main;\
@@ -47,28 +46,29 @@ void foo() {
int main()
{
+ extern char ds1[],ts1[];
+ extern char ds2[],ts2[];
+ extern char de1[],te1[];
+ extern char de2[],te2[];
+
printf("suppression off\n");
- DATA_LBL(s1);
if (1) {
+ ASMLABELS(s1);
PROG
+ ASMLABELS(e1);
}
- DATA_LBL(e1);
printf(" data length is %s\n", de1 - ds1 ? "not 0":"0");
- //printf(" text length is %s\n", te1 - ts1 ? "not 0":"0");
+ printf(" text length is %s\n", te1 - ts1 ? "not 0":"0");
printf("suppression on\n");
- DATA_LBL(s2);
if (0) {
+ ASMLABELS(s2);
PROG
+ ASMLABELS(e2);
}
- DATA_LBL(e2);
printf(" data length is %x\n", de2 - ds2);
- //printf(" text length is %X\n", te2 - ts2);
+ printf(" text length is %X\n", te2 - ts2);
return 0;
}
-/*-* test 6: some test */
-int main()
-{
- return 34;
-}
+#endif
diff --git a/tests/tests2/96_nodata_wanted.expect b/tests/tests2/96_nodata_wanted.expect
index 0db4ba2..9fd35ca 100644
--- a/tests/tests2/96_nodata_wanted.expect
+++ b/tests/tests2/96_nodata_wanted.expect
@@ -1,24 +1,22 @@
-/*-* test 1: initializer not computable 1 */
-test 1:3: error: initializer element is not computable at load time
+[test_static_data_error]
+96_nodata_wanted.c:7: error: initializer element is not computable at load time
-/*-* test 2: initializer not computable 2 */
-test 2:3: error: initializer element is not computable at load time
+[test_static_nodata_error]
+96_nodata_wanted.c:14: error: initializer element is not computable at load time
-/*-* test 3: initializer not computable 3 */
-test 3:2: error: initializer element is not computable at load time
+[test_global_data_error]
+96_nodata_wanted.c:20: error: initializer element is not computable at load time
-/*-* test 4: 2 cast warnings */
-test 4:2: warning: assignment makes integer from pointer without a cast
-test 4:2: warning: nonportable conversion from pointer to char/short
+[test_local_data_noerror]
+96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast
+96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short
-/*-* test 5; nodata_wanted test */
+[test_data_suppression]
suppression off
static data: 8 - 8.0 - 8.0 - main - static string
static bitfields: 333 44 555555 6 7
data length is not 0
+ text length is not 0
suppression on
data length is 0
-returns 0
-
-/*-* test 6: some test */
-returns 34
+ text length is 0
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
index 832aa49..4dd1591 100644
--- a/tests/tests2/Makefile
+++ b/tests/tests2/Makefile
@@ -20,7 +20,7 @@ endif
ifeq (,$(filter i386 x86_64,$(ARCH)))
SKIP += 85_asm-outside-function.test
endif
-ifeq (-$(findstring gcc,$(CC)-)-,--)
+ifeq (-$(findstring gcc,$(CC))-,--)
SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
endif
ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
@@ -40,8 +40,9 @@ NORUN =
FLAGS =
76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
-# run the source file cut into snippets
-96_nodata_wanted.test : FLAGS = -dT
+# These tests run several snippets from the same file one by one
+60_errors_and_warnings.test : FLAGS += -dt
+96_nodata_wanted.test : FLAGS += -dt
# Always generate certain .expects (don't put these in the GIT),
GEN-ALWAYS =
@@ -90,8 +91,8 @@ F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)"
@$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1
@rm -f *.exe *.obj *.pdb
-# using TCC for .expect if -dT in FLAGS
-GEN = $(if $(findstring -dT,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
+# using TCC for .expect if -dt in FLAGS
+GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS)
GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS)
GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe