as there's overlap between handling types for binary and ternay
operations. Factor this into a single routine (combine_types).
This uses the structure that gen_op was following, and expr_cond
was using as well in the past, which I find easier to reconvene
with the standard language. But it reuses the new functions for
diagnostics to improve (a little) on what GCC or clang produce :)
On windows. there is no long double really IOW it is the
same as double. However setting the VT_LONG flag in
combination with VT_DOUBLE allows to keep track of the
original type for the purpose of '_Generic() or more
accurate type warnings.
Fix static assert to support literal string instead of just printing
the sring of the current token as it use to be
so we can now use _Static_assert(0, "0" "1") which will print
__FILE__ __LINE__ error: 01
so that it also is called from the precedence parser. This
is complicated by the fact that something needs to be done before
the second operand is parsed in a single pass compiler, so it
doesn't quite fit into expr_infix itself. It turns out the smallest
code changes result when expr_landor remains separate. But it can
be tidied a bit.
- tests2/113_btdll.c: test handling multiple stabs infos
Also:
- libtcc.c: remove _ISOC99_SOURCE pre-defines. It is causing
strange warnings such as 'strdup not declared'
- i386/x86_64-gen.c cleanup bounds_pro/epilog. This discards
the extra code for main's argv. If needed, __argv might be
processed instead.
- tccgen.c:block(): reduce stackspace usage. For example with
code like "if (..) ... else if (..) ... else if (..)... "
considerable numbers of nested block() calls may occur.
Before that most stack space used when compiling itself was
for libtcc.c:tcc_set_linker().
Now it's rather this construct at tccpp.c:2765: in next_nomacro1():
if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
|| c == '.'
|| ((c == '+' || c == '-')
...
the strcat checker first checks dest for overlap, then src.
If the padding byte between b[] and the pad[] arrays happens to be zero
the dest check would have succeeded and the src test failed. If that
padding byte would be zero the dest check would trigger first.
As we can't influence the padding byte (only the b[] and pad[] arrays)
it was random if the dest or src checks triggered.
This makes it reliably trigger the dest check first.
This makes it possible to get backtraces with executables
(including DLLs/SOs) like we had it already with -g -run.
Option -b includes -bt, and -bt includes -g.
- new file lib/bt-exe.c: used to link rt_printline and the
exception handler from tccrun.c into executables/DLLs.
- new file lib/bt-log.c: provides a function that may be
called from user code to print out a backtrace with a
message (currently for i386/x86_64 only):
int (*tcc_backtrace)(const char *fmt, ...);
As an extra hack, if 'fmt' is prefixed like "^file.c^..."
then the backtrace will skip calls from within 'file.c'.
- new file lib/bt-dll.c: used on win32 to link the backtrace
and bcheck functions with the main module at runtime
- bcheck.c: now uses the tcc_backtrace function from above
- tccgen.c: minor cleanups
- tccelf.c: stab sections get SHF_ALLOC for easy access.
Also in relocate_section(): 64bit relocations for stabs
in DLLs cannot work. To find DLL addresses, the DLL base
is added manually in tccrun.c via rc.prog_base instead.
- tccpe.c: there are some changes to allow merging sections,
used to merge .finit_array into .data in the first place.
- tccpp.c: tcc -run now #defines __TCC_RUN__
also: refactor a line in tal_realloc that was incompatible
with bcheck
- tcctest.c: fixed a problem with r12 which tcc cannot preserve
as well as gcc does.
- tests2/112_backtrace.c: test the feature and the bcheck test18
that previously was in boundtest.c
we were emitting error messages for something like
'static int i = 2 || 1/0', even though the exception would be in
the unevaluated part. This doesn't destroy const-ness, so we must
accept it. This requires splitting the nocode_wanted values a bit more,
so that nocode_wanted due to const_wanted can be differentiated from
nocode_wanted due to non-evaluation.
The bounds checking code has now enabled gen_bounded_ptr_add tests.
This makes the code slower but finds more errors.
I had to correct some things in tcc to make it work.
- Fixed off by one in lib/bcheck.c
- Corrected tccelf.c sym_versions.
- Disabled USE_TAL when using bounds checking.
- Fixed cstr_printf va_start.
- Fixed tests/tests2/46_grep.c off by one error.
- Updated gen_bounded_ptr_add in x86_64-gen.c
- Fixed x86_64-link.c pointer diff.
For gen_vla_alloc now always use alloca call when bounds checking.
Added line/filename in %rax before bound calls to find location of error.
This fixes the issue
int main() { extern char *x; }
void main1() { extern char *x; }
t2.c:5: error: incompatible types for redefinition of 'x'
(reported by Giovanni Mascellani 2019/07/16)
the uninitialized cumofs was leading to random sizes for
the memset when initializing local structures, potentially
leading to segfaults from it. Only a problem with GNU
designated initializers, which we didn't test very well.
See testcase.
A more automatic approach to code suppression (aka. nocode_wanted)
The simple rules are:
- Clear 'nocode_wanted' at (im/explicit) label IF it was used
- Set 'nocode_wanted' after unconditional jumps
Also in order to test this then I did add the "function might
return no value" warning, and then to make that work again I
did add the __attribute__((noreturn)).
Also moved the look ahead label check into the type parser
to gain a little speed.
Example:
int a = 1;
void f(void)
{
int a = 2;
{
extern int a; // = 1 !!
....
To get this (more) correctly there is a new function to copy
syms between local to global stacks.
Also, this patch changes the meaning of VT_EXTERN back
to the simpler and IMO more useful notion of
DECLARED but not (yet) DEFINED.
and that for both variables and functions. That is, VT_EXTERN
in tcc doesn't have to do with the keyword 'extern' necessarily.
Also this patch does allow
int x[];
as alias for
extern int x[];
(as do gcc and msvc)
... which IMO are:
1) files don't need a _test suffix because all files in
the directory are tests ;)
2) we test the BEHAVIOR of the program, rather than its
binary bit contents.
Ok, but nobody said a test can't use two files ;)
(where the 104+_ construct is meant to prevent the file
from being picked up by the makefile as a test on its own).
Previously test 104 used a combination of *nix tools and system() calls
to emulate a `sh` script, which required split code paths for windows
due to different shell and different absolute path representation.
Also, it used a hardcoded tcc binary path, didn't set locale for sort.
Now the tools are used from a `sh` script which the program generates
and invokes, tmp files are at CWD and no conversion is required, tcc
path is taken from Makefile (exported), and `sort` uses LC_ALL=C.
- add tests for standard conformant inline functions
- implement it
The old tinycc failed to provide a conforming implementation
of non-static inlines. It would expose external symbols where it
shouldn't and hide them where it should expose them.
This commit provides a hopefully comprehensive test suite
for how things should be done. The .expect file can be obtained
by compiling the example c file (embedded in the test)
with a conforming compiler such as gcc, clang or icc and then
printing the exported symbols (e.g., with nm+awk+sort).
(The implementation currently reserves two new VT_ flags.
If anyone can provide an implementation without reserving
two extra flags, please replace mine.)
anonymous struct members were somewhat broken as the testcase
demonstrates. The reason is the jumping through hoops to fiddle
with the offsets I once introduced to avoid having to track
a cumulative offset. That's now not necessary anymore and actively
harmful, doing the obvious thing is now better.
see testcase, when the inner array dimension of multi-dimensional
VLAs isn't given TCC was generating invalid vstack accesses.
Those are actually invalid, so just diagnose them.