Commit Graph

592 Commits

Author SHA1 Message Date
herman ten brugge
3e731e3a78 Add symbolic debug support
This allows debugging with variables/structs/unions/enums/bitfields.

Add new functions:
- tcc_debug_stabs: store stabs debug info
- tcc_debug_stabn: store stabn debug info
- tcc_get_debug_info: generate stabs debug info
- tcc_debug_finish: store debug info in debug section
- tcc_add_debug_info: Add function debug info

Update functions:
- tcc_debug_end: free debug hash
- tcc_debug_funcstart: Generate correct function debug info
- tcc_debug_funcend: Finish debug info
- put_extern_sym2: Generate debug info for symbols
- pop_local_syms: Add debug info
- prev_scope: Add local symbols
2020-05-03 11:59:57 +02:00
Michael Matz
245f6a0d13 stdarg: always have the __builtin_va_* available
This makes available the __builtin_va_list type and __builtin variants
of va_start, va_arg, va_copy and va_end.  We do this via a header file
that's prepended to all compilations always (except if merely
preprocessing): tcc_predefs.h.  That header could also be used
for predefining other builtins in the future.

We don't need the define hacks for musl anymore with this.

Also fix x86_64 gfunc_prologue to reserve enoug space for the
full va_list structure, not just 16 bytes.
2020-04-15 22:06:52 +02:00
Michael Matz
38ab621b55 Factor out common type combination
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 :)
2020-04-15 02:44:12 +02:00
Michael Matz
00fbf65524 Move type_incompatibility_error earlier
also move type_incompatibility_warning and type_to_str.
2020-04-15 02:11:05 +02:00
grischka
6696da2f61 win32: long double as distinct C-type
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.
2020-04-11 22:03:09 +02:00
matthias
704b602184 instruduce C2x _Static_assert syntaxe 2020-03-04 11:35:34 +01:00
matthias
cb041f11f6 improve _Static_assert
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
2020-03-04 11:35:34 +01:00
Udo
923100c498 Better follow spacing style. (only changed formatting) 2020-02-18 21:11:49 +01:00
Udo
9272fac7c4 rework type coercion in ternary expr (a bit) and uncomment previously failing test. Be more explicit in diagnostic messages. 2020-02-17 18:25:43 +01:00
Udo
89b3cf0b87 warn if attr. __cleanup__ is given in type decl. (Allow this as an extension?) 2020-02-09 18:21:59 +01:00
Udo
c092f2ed61 Check if symbol given for attr. cleanup is actually a function 2020-02-07 23:23:31 +01:00
grischka
7e901299bf Rework expr_infix
- revert const-folding in gvtst() and put it back into
  expr_landor().  Although it did make sense, one reason
  not to do it is __builtin_constant_p() which may return
  true when it shouldn't because of nocode_wanted, see test.

- tccgen_init() can do init_prec(), also for tcc -E.

- for nostalgic reasons, keep the original expression parser
  functions in the source.

- Makefile: remove stale stuff
2020-01-22 21:57:19 +01:00
Michael Matz
aeac24de98 Rework expr_landor
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.
2020-01-20 05:48:48 +01:00
Michael Matz
23a8bac7b5 Use precedence parser for expressions
This is smaller and uses less stack depth per expression (eight function
calls from expr_or to get down to a unary).  It's a tiny bit faster
depending on how good the branch predictor is, on my machine a wash.
2020-01-20 05:48:48 +01:00
grischka
d79e1dee8c backtrace: test with DLLs
- 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 == '-')
        ...
2020-01-19 11:46:07 +01:00
gr
ef42295fe8 tccrun.c: standalone backtraces with -bt[N] or -b
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
2020-01-17 22:58:39 +01:00
herman ten brugge
4092b05068 Exclude ellipsis functions from bounds checking.
This fails on i386.
2020-01-16 09:40:33 +01:00
herman ten brugge
0d7c40b948 Call pop_local_syms before gfunc_epilog 2020-01-16 08:24:17 +01:00
Michael Matz
65f2fe390c Cleanup new bound checking code
remove quadratic loops by not using side tables; address-taken
can simply be a flag per local sym, and the lbounds section can
be filled after symbols go out of scope at which point we know
if the address was taken, so that there's no need to compress it
again after the funcion is done.
2020-01-16 01:19:59 +01:00
Michael Matz
4a70b2bc2d Fix handling of unevaluated subexpression of const
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.
2020-01-15 23:32:40 +01:00
herman ten brugge
3877618785 Update bound checking code.
Add __attribute__((constructor)) to __bounds_init.
- remove tcc_add_bcheck from i386-link.c and x86_64-link.c
- add simplified tcc_add_bcheck to tccelf.c
- Update tccrun.c to call constructor/destructor.
Set dynsym sh_info to number of local symbols in tccelf.c
Reduce stack size when bounds checking is enabled.
Added variable TCC_LIBBCHECK for windows support.
Add signal stack to detect stack overflow.
Add all & parameters in lbound_section and remove them if not used.
Close fd in tcc_relocate in tccrun.c
Fix section type constructor/destructor in tccelf.c
Add check code in tests/boundtest.c for mem/str functions.
Remove -ba from documentation.
Add bounds check signal info in documentation.

bcheck.c:
- Fix initial_pool alignment.
. Fix printf statements.
. Add prototypes for all external interface functions.
- Add TCC_BOUNDS_WARN_POINTER_ADD environment variable.
. Add ctype and errno data.
- Fix alloca when multithreading is used.
- Add lock for __bound_checking and __bound_never_fatal.
- Catch pthread_create and use locks when called.
- Detect in loaded in shared lib and use locks when found
- Use spin locks instead of semaphore locks.
- Make spin locked code as small as possible.
- Fix mem/str functions checking.
- Fix overlap checking mem/str functions.
2020-01-15 08:53:19 +01:00
Michael Matz
c8ca64d28b Adjust return value promotion for some archs
this is a bit complicated: for i386 and x86-64 we really need to
extend return values ourself, as the common code now does.  For arm64
this at least preserves old behaviour.  For riscv64 we don't have to
extend ourself but can expect things to be extended up to int (this
matters for var-args tests, when the sign-extension to int64 needs to
happen explicitely).  As the extensions are useless, don't do them.

And for arm32 we actually can't express GCC behaviour: the callee side
expects the return value to be correctly extended to int32, but
remembers the original type.  In case the ultimate target type for the
call result is only int, no further extension is done.  But in case
the target type is e.g. int64 an extension happens, but not from int32
but from the original type.  We don't know the ultimate target type,
so we have to choose a type to put into vtop:
* original type (plus VT_MUSTCAST) - this looses when the ultimate
  target is int (GCC: no cast, TCC: a cast)
* int (without MUSTCAST) - this looses when the ultimate target is
  int64 (GCC: cast from original type, TCC: cast from int)
This difference can only be seen with undefined sources, like the
testcases, so it doesn't seem worthwhile to try an make it work, just
disable the test on arm and choose the second variant as that generates
less code.
2019-12-17 01:46:06 +01:00
grischka
a64353ce71 tccgen.c: generic char/short promotion for function return values 2019-12-16 21:58:32 +01:00
grischka
89372dc482 update gen_cast 2019-12-16 21:37:44 +01:00
grischka
35475b5423 remove VT_LVAL_BYTE etc.
For some reason there was no point for that anymore.
2019-12-16 20:59:23 +01:00
grischka
5914f4d57d tccgen.c: cleanup reg classes
wrap some copy&paste code into functions
2019-12-16 20:44:48 +01:00
grischka
ff3b5ee91c -bench fix
Put total_lines etc. into TCCState.  Also, initialize
the predefined compiler types for the preprocessor too.
tccpe.c: fix BaseOfCode if .init section present (with tcc -b)
2019-12-16 20:17:10 +01:00
Michael Matz
b476a5f478 Readd lost error on local static function decls
see testcase: block scope decls for functions can't use static
(allowed is only extern or none).  This got lost in commit 85690480.
2019-12-16 07:00:26 +01:00
grischka
65f74a4df0 tccrun.c: better stab debug support
* a major revision of the rt_printline() feature in
  tccrun.c to report file:linenumber more correctly.

* minor changes to the stab info produced by the
  compiler in tccgen.c

However stab addresses are limited to 32 bits.  I added
a work around:

    if (sizeof pc == 8)
        pc |= wanted_pc & 0xffffffff00000000ULL;

However GDB has problems with that too.
2019-12-14 17:48:50 +01:00
grischka
56db092ab7 bcheck cleanup
- revert Makefiles to state before last bcheck additions
  Instead, just load bcheck.o explicitly if that is
  what is wanted.

- move tcc_add_bcheck() to the <target>-link.c files and
  remove revently added arguments.  This function is to
  support tccelf.c with linking, not for tccgen.c to
  support compilation.

- remove -ba option:  It said:
  "-ba  Enable better address checking with bounds checker"
  Okay, if it is better then to have it is not an option.

- remove va_copy. It is C99 and we try to stay C89 in tinycc
  when possible.  For example, MS compilers do not have va_copy.

- win64: revert any 'fixes' to alloca
  It was correct as it was before, except for bound_checking
  where it was not implemented.  This should now work too.

- remove parasitic filename:linenum features
  Such feature is already present with rt_printline in
  tccrun.c.  If it doesn't work it can be fixed.

- revert changes to gen_bounded_ptr_add()
  gen_bounded_ptr_add() was working as it should before
  (mostly).  For the sake of simplicity I switched it to
  CDECL.  Anyway, FASTCALL means SLOWCALL with tinycc.

In exchange you get one addition which is required for
bounds_cnecking function arguments.  The important thing
is to check them *BEFORE* they are loaded into registers.
New function gbound_args() does that.

In any case, code instrumentation with the bounds-check
functions as such now seems to work flawlessly again,
which means when they are inserted as NOPs, any code that
tcc can compile, seems to behave just the same as without
them.

What these functions then do when fully enabled, is a
differnt story.  I did not touch this.
2019-12-14 13:26:18 +01:00
herman ten brugge
a86f47889c Fix debug info 2019-12-13 15:07:02 +01:00
herman ten brugge
39c0ff311d Add new bounds checking functions.
The following functions are now also bounds checked:
memcmp, strncpy, strcmp, strncmp, strcat, strchr, strdup.

Add statistics code for bounds checking functions.
The statistics can be printed by settings environment variable
"TCC_BOUNDS_PRINT_STATISTIC".

Enabled more tests in test/Makefile.
2019-12-12 20:49:35 +01:00
herman ten brugge
35512be1ee Fix typo with -ba option 2019-12-12 14:21:07 +01:00
herman ten brugge
75145ddc1a Add -ba option for bounds_checking 2019-12-12 13:29:45 +01:00
herman ten brugge
4a2e33d160 Update bounds checking.
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.
2019-12-12 12:56:06 +01:00
grischka
72729d8e36 allow libtcc states to be used concurrently
This allows creation of TCCStates and operation with API
calls independently from each other, even from threads.

Frontend (option parsing/libtcc.c) and backend (linker/tccelf.c)
now depend only on the TCCState (s1) argument.

Compilation per se (tccpp.c, tccgen.c) is still using
globals for convenience.  There is only one entry point
to this section which is tcc_compile() which is protected
by a semaphore.

There are some hacks involved to avoid too many changes,
as well as some changes in order to avoid too many hacks ;)

The test libtcc_test_mt.c shows the feature.  Except this
new file the patch adds 87 lines overall.
2019-12-11 02:36:19 +01:00
Michael Matz
fb22e0c12d Fix type/r/r2 confusion differently
on i386 111_conversion.c breaks when save_reg_upstack isn't careful
about r2 and type mismatches.  The bcheck patches fixed this by
enlarging the stack slot beyond the natural type, this variant simply
avoids saving the second register is the type indicates that it isn't
needed.

Adds also a comment how this should ideally work, namely that type
and r/r2 entries in the vstack are consistent.  In the 111_conversion
testcase it's specifically gen_cast via gen_cvt_ftoi that breaks
this, but there more general code broken as well, so that would deserve
a careful fixup based on some additional asserts.
2019-12-10 17:49:04 +01:00
herman ten brugge
4461f38a9e Fix bounds checking for linux/windows 2019-12-10 08:07:25 +01:00
herman ten brugge
800c3a5e0b Add constructor/destructor support 2019-10-29 07:02:58 +01:00
Pursuer2
a7b37f9c63 Fix bug in gen_cvt_ftoi1. Add test 107_stack_safe for this fix.
(Thanks to the support of herman ten brugge)
2019-10-24 00:57:59 +08:00
Sergey Sushilin
53a1521c2e fix _Noreturn keyword 2019-09-08 18:35:15 +03:00
grischka
7b8799e5ff tccgen.c: local extern decls: copy s->ref for VT_PTR too
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)
2019-09-08 16:59:17 +02:00
Michael Matz
9264f06efe Improve ?: expansion a little
there's no need to prematurely convert the condition into registers
before emitting the test.
2019-09-01 23:13:21 +02:00
Michael Matz
d5bb407cc4 riscv: Add special cases for const operands
RISC-V supports small immediates for some operations, let's
use them.
2019-09-01 23:13:21 +02:00
Michael Matz
c505074a9f riscv: rewrite parameter passing
this fixes the ret_mixed_test of abitest.c, now everything of the
testsuite works.

The generic code for returns is good enough for our use, except in
the specific case of a mixed int/float structures returned in registers,
so instead of duplicating the whole generic gfunc_return function, add
another modus for gfunc_sret: returning -1 makes the actual register
transfer by a new backend function.
2019-09-01 23:13:21 +02:00
Michael Matz
98f1b83ffe riscv: Start fixing float struct passing/returnig
this fixes ret_2float_test, ret_2double_test and
ret_8plus2double_test of abitest.c.  The common gfunc_return
actually works for these cases, so let's use that for now.

The ret_mixed_test (as well as mixed2 and mixed3) are left
broken, and tccgen.c:gfunc_return can't be used for that as is,
so I'll leave the gfunc_return implementation in riscv64-gen.c for
now, I'll have to think about this some more.
2019-09-01 23:13:20 +02:00
Michael Matz
98dc4c123d riscv: Fix stdarg_many_test
if named params are passed on stack, the va_arg area begins after
that, not at sp+0.  Fixes abitest:stdarg_many_test.
2019-09-01 23:13:20 +02:00
Michael Matz
509f561823 riscv: fix more sign/zero-extension problems
see the testcase.  For the signed case this problably does
the wrong thing, and it should break other archs.  Rework once
there are testcases for this.
2019-09-01 23:13:20 +02:00
Michael Matz
2668eda595 riscv: Implement long double support
for the implementation of operations we can reuse the ones
from lib/lib-arm64.c, risc-v long double is also float128.
Also implement ggoto, and PDIV, and use t0 in load/store as
temporary register if necessary, not one given by get_reg
(the latter can destroy assignments of long double parameters
in function calls that are already set up).

This let's us compile tcc.c and tcctest.c, though both
don't yet work.
2019-09-01 23:13:20 +02:00
Michael Matz
2616c6b230 riscv: Fix 73_arm.c
some constants were loaded wrong (e.g. 0xffffabcdU), and
risc-v needs to do explicit zero-extensions for widening from
32bit (not sign-extensions like the other 64bit targets).

This makes the whole tests2.all testsuite work.

Parameter passing is still not psABI-compliant, but internally
consistent.  (e.g. structs of two floats/doubles are passed
in integer registers, but should sit in float regs).
2019-09-01 23:13:20 +02:00
Michael Matz
982de78e8d riscv: implement stdarg functions
this also fixes passing of params > 16 bytes.  In riscv
they aren't passed by value on stack, but via reference (and
because callees are allowed to modify by-ref params the caller must
allocate an own copy per call).

This fixes the stdarg parts of 73_arm.c.
2019-09-01 23:13:20 +02:00
Michael Matz
f44df9d85b riscv: some work on large function arguments
like long double (16 bytes) and structs.  Not completely
correct, but 73_arm64 somewhat works now (when the stdarg part
is disabled), though with some errors.  What's definitely incorrect
is arguments of a mixed int/float struct.  I'm using VT_LDOUBLE
(which conveniently has to be placed in a int-reg-pair) to load/store
structure arguments of size > 8 and <= 16, and that can lead to
overreads.
2019-09-01 23:13:20 +02:00
Michael Matz
9309585dbe riscv: some long double support
long double on risc-v is 128bit, but there are no registers
for that type (without the Q ISA extension).  They are passed
like two 64bit integers values (with an exception for varargs,
where it's an aligned register pair).  This all requires some
hacks in generic code as otherwise RC_FLOAT regs are tried for
holding values of long double type, but we need a RC_INT register
pair.  This really could all use some cleanup for all archs.

This doesn't implement any conversions of operations for long
double, but it's enough to get 70_floating_point_literals working.
2019-09-01 23:13:19 +02:00
Michael Matz
9c1b17407f riscv: Make 32_leds work
* more ops: umod and udiv
* large immediates: suboptimal code, e.g. when loading
  0xffffffffU (which is what a cast from long to int does).

tests2 work up to 67_macro_concat.
2019-09-01 23:13:19 +02:00
Michael Matz
16edda58b7 riscv: Add more ops and fixes
* implement compares, gtst and gsym/gjmp and add
* implement stores (simple cases)
* fix arg passing with more than one register arg, fix
  loads to not always use 8byte loads
* add some predefined macros: __riscv, __riscv_xlen,
  __SIZEOF_POINTER__ (needed by glibc header)

The first 5 tests of tests2 run now.
2019-09-01 23:13:08 +02:00
Michael Matz
0676d5bc23 riscv64: Add skeleton target 2019-08-14 18:18:46 +02:00
Michael Matz
9e429dbef0 Fix invalid size with GNU designated initializers
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.
2019-07-21 21:14:58 +02:00
grischka
ce1ef5b8fc some smaller fixes
- libtcc.c/tccpp.c: fix -U option for multiple input files
- libtcc: remove decl of tcc_add_crt() for PE
- tcc.h: define __i386__ and __x86_64__ for msvc
- tcc.h: undef __attribute__ for __TINYC__ on gnu/linux platforms
- tccelf.c: disable prepare_dynamic_rel unless x86/x64
- tccpe.c: construct rather than predefine PE section flags
- tccpp.c: (alt.) fix access of dead stack variable after error/longjmp
- x86_64-gen.c: fix func_alloca chain for nocode_wanted
- tccpp.c/tccgen.c: improve file:line info for inline functions
- winapi/winnt.h: correct position for DECLSPEC_ALIGN attribute
- win32/lib/crt: simplify top exception handler (needed for signal)
- arm64-gen.c: remove dprintf left from VT_CMP commit
- tccgen.c: limit binary scan with gcase to > 8 (= smaller code)
- tccgen.c: call save_regs(4) in gen_opl for cmp-ops (see test in tcctest.c)
2019-07-14 22:46:19 +02:00
YX Hao
756e766295 win: ignore dllimport/dllexport for typedef with warning instead of error
Keep the same as gcc and clang.
The usage exists in MinGW-w64 headers.
2019-07-02 18:19:24 +08:00
Christian Jullien
a9340dd325 Applying grischka proposed patch fixes error reported on 93_integer_promotion test as found on Debian buster / gcc 8.3 for ARM plateform 2019-06-26 05:26:20 +02:00
grischka
3d78918e63 introduce scopes for VLA & attribute cleanup 2019-06-24 11:40:01 +02:00
grischka
8227db3a23 jump optimizations
This unifies VT_CMP with VT_JMP(i) by using mostly VT_CMP
with both a positive and a negative jump target list.

Such we can delay putting the non-inverted or inverted jump
until we can see which one is nore suitable (in most cases).

example:
    if (a && b || c && d)
        e = 0;

before this patch:
   a:	8b 45 fc             	mov    0xfffffffc(%ebp),%eax
   d:	83 f8 00             	cmp    $0x0,%eax
  10:	0f 84 11 00 00 00    	je     27 <main+0x27>
  16:	8b 45 f8             	mov    0xfffffff8(%ebp),%eax
  19:	83 f8 00             	cmp    $0x0,%eax
  1c:	0f 84 05 00 00 00    	je     27 <main+0x27>
  22:	e9 22 00 00 00       	jmp    49 <main+0x49>
  27:	8b 45 f4             	mov    0xfffffff4(%ebp),%eax
  2a:	83 f8 00             	cmp    $0x0,%eax
  2d:	0f 84 11 00 00 00    	je     44 <main+0x44>
  33:	8b 45 f0             	mov    0xfffffff0(%ebp),%eax
  36:	83 f8 00             	cmp    $0x0,%eax
  39:	0f 84 05 00 00 00    	je     44 <main+0x44>
  3f:	e9 05 00 00 00       	jmp    49 <main+0x49>
  44:	e9 08 00 00 00       	jmp    51 <main+0x51>
  49:	b8 00 00 00 00       	mov    $0x0,%eax
  4e:	89 45 ec             	mov    %eax,0xffffffec(%ebp)
  51:   ...

with this patch:
   a:	8b 45 fc             	mov    0xfffffffc(%ebp),%eax
   d:	83 f8 00             	cmp    $0x0,%eax
  10:	0f 84 0c 00 00 00    	je     22 <main+0x22>
  16:	8b 45 f8             	mov    0xfffffff8(%ebp),%eax
  19:	83 f8 00             	cmp    $0x0,%eax
  1c:	0f 85 18 00 00 00    	jne    3a <main+0x3a>
  22:	8b 45 f4             	mov    0xfffffff4(%ebp),%eax
  25:	83 f8 00             	cmp    $0x0,%eax
  28:	0f 84 14 00 00 00    	je     42 <main+0x42>
  2e:	8b 45 f0             	mov    0xfffffff0(%ebp),%eax
  31:	83 f8 00             	cmp    $0x0,%eax
  34:	0f 84 08 00 00 00    	je     42 <main+0x42>
  3a:	b8 00 00 00 00       	mov    $0x0,%eax
  3f:	89 45 ec             	mov    %eax,0xffffffec(%ebp)
  42:   ...
2019-06-24 11:40:01 +02:00
grischka
1b57560502 nocode, noreturn
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.
2019-06-24 11:40:01 +02:00
grischka
8569048031 work on local extern declarations
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)
2019-06-24 11:38:32 +02:00
Pascal Cuoq
cbbba01b46 reject invalid arrays in post_type() 2019-06-24 10:28:44 +02:00
Michael Matz
cb73be5346 Fix last commit
it wasn't complete.
2019-06-17 20:52:09 +02:00
Michael Matz
c3f0937012 Don't emit unreferenced static inlines
there's no need to emit unreferenced static function, even
if they are forced.
2019-06-17 19:36:59 +02:00
Michael Matz
fe23a14ebb Deal with more tentative definitions
see testcase.
2019-06-17 18:52:49 +02:00
Michael Matz
69a46b0c53 Make mingw work again
my last inline changes caused parameter names to be overwritten
always (as VT_EXTERN now doesn't mark the current def anymore),
leading to a compile error when including windows.h.  Rework this.

Also silence a warning that currently happens for mingw, which is
written with gnu-inline behaviour in mind.  Our work-arounds
of using "static inline" actually create invalid C (which we warn
about).  Until we implement this properly, just silence the warning.
2019-06-17 18:28:56 +02:00
Michael Matz
cb8bbf1ab9 TLC for C99 inline implementation
there's no need for two new flags in type.t .  We just can't use
VT_EXTERN as marker if functions are defined or not (like we can
for objects), and then can simply implement the rules of C99/C11
by not overwriting VT_STATIC/VT_EXTERN at all but rather only
look at them.  A function already on the inline list can be
forced by removing the VT_INLINE flag, and then linkage
follows from some combination of VT_STATIC, VT_EXTERN and VT_INLINE.
2019-06-17 03:34:03 +02:00
Petr Skocik
587e1f5598 standard conformant inline functions
- 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.)
2019-06-11 16:29:24 +02:00
Vlad Vissoultchev
1dd6842654
Don't drop asm_label hack on external symbols for win32 DLL exports 2019-05-14 22:37:13 +03:00
matthias
14be3a1dc1 fix cleanup with for loop initialisation
Signed-off-by: matthias <uso.cosmo.ray@gmail.com>
2019-05-03 12:32:55 +02:00
matthias
0d54946dec fix cleanup with break and continue
fix cleanup
2019-05-03 12:32:55 +02:00
Michael Matz
d30bc6d00a _Static_assert must be followed by semicolon
as per the C11 grammar.
2019-05-03 00:22:35 +02:00
matthias
5a0101856b add C11 _Static_assert support 2019-04-28 01:07:21 +02:00
Michael Matz
c07e81b087 Tidy some code
the real difference is in decl0 where we can use external_sym
just fine also for function definitions, we don't have to use
external_global_sym.  Setting VT_EXTERN in external_sym isn't
necessary either (the type will have it set if necessary).
The rest is tidying: removing unused arguments and moving
some code around.
2019-04-18 03:42:23 +02:00
Michael Matz
0344c0b6a0 Fix more struct inits
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.
2019-04-11 00:30:41 +02:00
Michael Matz
38a6aba468 Fix _Alignas
* don't accept _Alignas as type qualifier (after pointer '*').
* accept type-names within _Alignas
* add testcases
2019-04-08 22:06:51 +02:00
Michael Matz
2a417b50ee Detect invalid VLA decls
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.
2019-04-07 04:09:25 +02:00
Michael Matz
5ac2a26666 Don't endlessly recurse on invalid nested typedefs
see testcase.
2019-04-07 03:15:05 +02:00
Michael Matz
d00f98a7a5 Fix 98_al_ax_extend.c compile error
this test is run only on i386 so its failing went unnoticed for
a while, since 1fd3709379.  IS_ASM_SYMs should not be tested
for conflicting types, the C typing overrides.
2019-04-07 02:44:32 +02:00
Devin Hussey
9382a3ad58 C11 conformance: Add _Noreturn, stdnoreturn.h, and partial _Alignas support
_Noreturn, just like __attribute__((noreturn)), is ignored.
I also added stdnoreturn.h, in all its glorious uselessness.

_Alignas only works for integer expressions right now. In order
to comply, we need:
 - _Alignas(type) -> _Alignas(_Alignof(type)).
 - stdalign.h as soon as it is done.

Note: DR 444 is supported; it works on struct members.

Signed-off-by: Devin Hussey <husseydevin@gmail.com>
2019-03-20 15:03:27 -04:00
Michael Matz
1fd3709379 Fix local extern vardecl
see testcases.  A local 'extern int i' declaration needs to
refer to the global declaration, not to a local one it might
be shadowing.  Doesn't seem to happen in the wild very often as
this was broken forever.
2019-03-18 05:53:03 +01:00
Michael Matz
e6980f6cc7 Detect more invalid initializers
in presence of invalid source code we can't rely on the
next token to determine if we have or haven't already parsed
an initializer element, we really have to track it in some separate
state; it's a flag, so merge it with the other two we have (size_only
and first).  Also add some syntax checks for situations which
formerly lead to vstack leaks, see the added testcases.
2019-03-18 03:31:11 +01:00
Michael Matz
4b46e0ec63 Handle corner case for abstract decls
sometimes abstract decls in parameter lists left the returned name
uninitialized potentially leading to segfaults, like in

  int f(int ()) {
    return 0;
  }

Deal with this.
2019-03-12 17:27:15 +01:00
Michael Matz
ef0397cf3d Fix crash on invalid code
like on 'enum myenum { L = -1 } L;'.  It's a bit tedious as
there are two paths (for global vs local symbols), and because
the scope and enum_val share same storage.
2019-03-08 17:58:25 +01:00
matthias
b082659f19 fix segv in "{,}" combound literal 2019-03-06 18:51:13 +01:00
Michael Matz
5f737fb4d3 tidy code 2019-01-31 01:04:55 +01:00
Michael Matz
5c862a08b4 suppress code after continue as well
fix an oversight in code suppression
2019-01-31 00:37:49 +01:00
matthias
d27ea5155f remove incr/decr_local_scope functions 2019-01-29 21:32:38 +01:00
Michael Matz
4cc802a88e Tidy new support for cleanups
encode most things in Syms, do only as much work as necessary
(e.g. pending cleanups), don't track scopes in a large
structure (instead encode the scopes with cleanups directly
in the cleanups tree).  Removes ca. 120 lines of code.
2019-01-28 05:54:19 +01:00
matthias
46145af4a1 remove C99 'for' loop initial declarations 2019-01-23 19:42:04 +01:00
matthias
26f0cf0708 Fix scope limit for cleanup attribute
old implementation use only a global static array for storing
ScopeTracker which have the advantage to be fast, but you can't
use cleanup in a function that have move than SCOPE_TCK_STORE_SIZE
scopes.

I don't want to use only dynarray_* as it would slow down tcc for
every functions, so I keep both stores.
2019-01-23 17:21:14 +01:00
matthias
0d91ba749c Add gcc attribute cleanup support
The major difficulty was to handle cleanup when a goto happen
to do so, I've had a "ScopeTracker" struct.
I can't use local_scope because that would not work with code like below
as local_scope would be at the same level:

{
    char * __attribute__ ((cleanup(clean_function))) str = "hej";
    goto next;
}
{
    next:
}
2019-01-23 17:21:14 +01:00
Matthias Gatto
2b94c0c3b1 Revert "allow c11 feature only when -std=c11 is use"
This reverts commit 756988e8f9.
2019-01-11 10:35:44 +01:00
matthias gatto
756988e8f9 allow c11 feature only when -std=c11 is use 2019-01-10 23:42:45 +01:00
Petr Skocik
51f6e52dd3 Support multiple __label__ declarations
Support multiple __label__ declarations at the beginning of a block
as long as they're contiguous.

gcc and clang accept:
    { __label__ a,b; __label__ c;  /*...*/ }
.
Tcc would fail it. This patch makes it accept it.

The patch:
-        if (tok == TOK_LABEL) {
+        while (tok == TOK_LABEL) {
2019-01-11 02:32:47 +08:00
Pursuer
b3b685d92a optimize the generated code when save_reg is required
Before this patch, save_reg can't reuse the temporary local variable
created before to save register. It may consume a lot of stack memory. this patch make save_reg reuse the temporary local variable.
2019-01-10 13:17:14 +08:00
Pursuer
0c313f491b Insert arm-xxx_FILES into Makefile to suport CROSS_TARGET and Remove duplicate function lexpand_nr 2019-01-09 02:06:26 +08:00