This adds a PARSE_FLAG_ACCEPT_STRAYS parse flag to accept stray
backslashes in the source code, and uses it for pure preprocessing.
For absolutely correct behaviour of # stringification, we need to use
this flag when parsing macro definitions and in macro arguments, as
well; this patch does not yet do so. The test case for that is something
like
#define STRINGIFY2(x) #x
#define STRINGIFY(x) STRINGIFY2(x)
STRINGIFY(\n)
which should produce "\n", not a parse error or "\\n".
See http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html
Perhaps a better fix would be to ensure tok is set to TOK_EOF rather
than 0 at the end of a macro stream.
This partially fixes test2 of the examples given in:
http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html
It's still failing, but at least it's not running out of memory now.
The old code had an inverted condition, so
#define a(b)## b
would be accepted while
#define a(b,c) b ## ## c
would be rejected with the confusing error message "'##' invalid at
start of macro".
Quick fix for
http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00160.html.
I don't fully understand the intended semantics of when file->buf_ptr[0]
is valid, but the rest of the code doesn't have any obvious spots with
the same bug.
Feel free to revert this if I'm mistaken or we need to discuss this
change further.
- pop_macro incorrect with initially undefined macro
- horrible implementation (tcc_open_bf)
- crashes eventually (abuse of Sym->prev_tok)
- the (unrelated) asm_label part is the opposite of a fix
(Despite of its name this variable has nothing to do with
the built-in assembler)
This reverts commit 0c8447db79.
* give warning if pragma is unknown for tcc
* don't free asm_label in sym_free(),
it's a job of the asm_free_labels().
The above pragmas are used in the mingw headers.
Thise pragmas are implemented in gcc-4.5+ and current
clang.
library Cello: http://libcello.org/ which uses `$` and several
variations of as macros.
There is also RayLanguage which also uses it as a macro for a kind of
ObjC style message passing: https://github.com/kojiba/RayLanguage
This is a patch from Daniel Holden.
Lets assume that in *.S files a preprocessor directive
follow '#' char w/o spaces between. Otherwise there is
too many problems with the content of the comments.
* tell a right line number in error message
if a #line directive is wrong
* don't print an error message if we preprocess a .S file
and #line directive is wrong. This is the case of
the
# 4026 bytes
comment in *.S file.
* preprocess_skip: skip a line with
if (parse_flags & PARSE_FLAG_ASM_COMMENTS)
p = parse_line_comment(p);
if line starts with # and a preprocessor command not found.
A test program:
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
# This repeats until either a device doesn't exist, or until
#endif
* remove a second definition of the TOK_FLAG_* and PARSE_FLAG_*
from the tccpp.c
in the same pass like
tcc -E one.c two.c three.c -o combined.i
This will allow to speed up a compilation process by using a commamd like
tcc -E *.c | tcc -o program.exe -xc -
It looks that multi-times initialization don't affect anything.
Only call to the free_defines(define_start) in tcc_preprocess()
is removed in assumption that free_defines(NULL) in
tcc_cleanup() will free all defines.
With this option on a defines are included into the output
(inside comments). This will allow to debug a problems like:
In file included from math.c:8:
In file included from /usr/include/math.h:43:
/usr/include/bits/nan.h:52: warning: NAN redefined
tcc -E -P
do not output a #line directive, a gcc compatible option
tcc -E -P1
don't follow a gcc preprocessor style and do output a standard
#line directive. In such case we don't lose a location info when
we going to compile a resulting file wtith a compiler not
understanding a gnu style line info.
A cpp from gcc do this.
A test case:
tcc -E tccasm.c -o tccasm.i
tcc -E tccasm.i -o tccasm.ii
After a patch the line numbers in tccasm.ii are the same
as in tccasm.i
* tccpp.c (parse_number): `shift' should be 1 while parsing binary
floating point number.
* tests/tests2/70_floating_point_literals.c: New test cases for
floating point number parsing.
As per grischka comment, always output a space after macro concatenation
instead of trying to detect if it's necessary as the current approach
has a huge cost.
This was going wrong (case TOK_LAND in unary: computed labels)
- vset(&s->type, VT_CONST | VT_SYM, 0);
- vtop->sym = s;
This does the right thing and is shorter:
+ vpushsym(&s->type, s);
Test case was:
int main(int argc, char **argv)
{
int x;
static void *label_return = &&lbl_return;
printf("label_return = %p\n", label_return);
goto *label_return; //<<<<< here segfault on linux X86_64 without the memset on vset
printf("unreachable\n");
lbl_return:
return 0;
}
Also::
- Rename "void* CValue.ptr" to more usable "addr_t ptr_offset"
and start to use it in obvious cases.
- use __attribute__ ((noreturn)) only with gnu compiler
- Revert CValue memsets ("After several days searching ...")
commit 4bc83ac393
Doesn't mean that the vsetX/vpush thingy isn't brittle and
there still might be bugs as to differences in how the CValue
union was set and is then interpreted later on.
However the big memset hammer was just too slow (-3% overall).
As was pointed out on tinycc-devel, many uses of get_tok_str gives as
second parameter the value NULL. However, that pointer was
unconditionally dereferenced in get_tok_ptr. This commit explicitely add
support for thas case.
I found the problem it was because CValue stack variables have rubish as it inital values
and assigning to a member that is smaller than the big union item and trying to
recover it later as a different member gives bak garbage.
ST_FUNC void vset(TCCState* tcc_state, CType *type, int r, int v)
{
CValue cval;
memset(&cval, 0, sizeof(CValue));
cval.i = v; //,<<<<<<<<<<< here is the main bug that mix with garbage
vsetc(tcc_state, type, r, &cval);
}
/* store a value or an expression directly in global data or in local array */
static void init_putv(TCCState* tcc_state, CType *type, Section *sec, unsigned long c,
int v, int expr_type)
{
...
case VT_PTR:
if (tcc_state->tccgen_vtop->r & VT_SYM) {
greloc(tcc_state, sec, tcc_state->tccgen_vtop->sym, c, R_DATA_PTR);
}
//<<< on the next line is where we try to get the assigned value to cvalue.i as cvalue.ull
*(addr_t *)ptr |= (tcc_state->tccgen_vtop->c.ull & bit_mask) << bit_pos;
break;
Also this patch makes vla tests pass on linux 32 bits
- tccgen: error out for cast to void, as in
void foo(void) { return 1; }
This avoids an assertion failure in x86_64-gen.c, also.
also fix tests2/03_struct.c accordingly
- Error: "memory full" - be more specific
- Makefiles: remove circular dependencies, lookup tcctest.c from VPATH
- tcc.h: cleanup lib, include, crt and libgcc search paths"
avoid duplication or trailing slashes with no CONFIG_MULTIARCHDIR
(as from 9382d6f1a0)
- tcc.h: remove ";{B}" from PE search path
in ce5e12c2f9 James Lyon wrote:
"... I'm not sure this is the right way to fix this problem."
And the answer is: No, please. (copying libtcc1.a for tests instead)
- win32/build_tcc.bat: do not move away a versioned file
- add quotes: eval opt=\"$opt\"
- use $source_path/conftest.c for OOT build
- add fn_makelink() for OOT build
- do not check lddir etc. on Windows/MSYS
- formatting
config-print.c
- rename to conftest.c (for consistency)
- change option e to b
- change output from that from "yes" to "no"
- remove inttypes.h dependency
- simpify version output
Makefile:
- improve GCC warning flag checks
tcc.h:
- add back default CONFIG_LDDIR
- add default CONFIG_TCCDIR also (just for fun)
tccpp.c:
- fix Christian's last warning
tccpp.c: In function ‘macro_subst’:
tccpp.c:2803:12: warning: ‘*((void *)&cval+4)’ is used uninitialized
in this function [-Wuninitialized]
That the change fixes the warning doesn't make sense but anyway.
libtcc.c:
- tcc_error/warning: print correct source filename/line for
token :paste: (also inline :asm:)
lddir and multiarch logic still needs fixing.
This replaces -> use instead:
-----------------------------------
- tcc_set_linker -> tcc_set_options(s, "-Wl,...");
- tcc_set_warning -> tcc_set_options(s, "-W...");
- tcc_enable_debug -> tcc_set_options(s, "-g");
parse_args is moved to libtcc.c (now tcc_parse_args).
Also some cleanups:
- reorder TCCState members
- add some comments here and there
- do not use argv's directly, make string copies
- use const char* in tcc_set_linker
- tccpe: use fd instead of fp
tested with -D MEM_DEBUG: 0 bytes left