Commit Graph

632 Commits

Author SHA1 Message Date
grischka
8cb3e5368f bitfields init : tiny solution
This replaces commit 5c6356ff8e,
except the tests.
2020-09-18 23:31:34 +02:00
herman ten brugge
5c6356ff8e default-initialization of bitfields
The code:

struct bf_SS {unsigned int bit:1,bits31:31; };
void func(void) {
  struct bf_SS bf_finit = { .bit = 1 };
}

will not init bits31 to 0.

tccgen.c:
- check_bf: New function to check if bitfield is present in struct/union
- decl_initializer: Call check_bf and set value to 0 is bitfield found

tests/tcctest.c:
- Add struct bitfield test code
2020-09-18 19:20:57 +02:00
herman ten brugge
c9bbd4e707 Allow strings in __builtin_constant_p
tccgen.c:
- Fix handling __builtin_constant_p

tests/bug.c:
- Remove tst3

tests/tcctest.c:
- Add new tests for __builtin_constant_p
2020-09-17 09:11:10 +02:00
Kyryl Melekhin
618ba55a81 fix float to u64 intrinsics
reverts commit
310e3b428c
(more info there)

now functions check for
sign bit in float.

now hopefully this patch will
cover entirety of areas it might affect
2020-09-10 17:35:36 +00:00
Kyryl Melekhin
310e3b428c (bug caused by tcc intristics)
reproduce bug:
$ ./configure --cc=gcc
$ make
$ make install
(OK)
run a test:

extern int printf(const char *str, ...);
int main()
{
        int t2 = (int)(-1.847759065f * 4096);
        printf("%d\n", t2);
}

$ tcc test.c
$ ./a.out
$ -7568
(OK)

(self compiled now)
$ ./configure --cc=tcc
$ make
$ make install
(OK)

$ tcc test.c
$ ./a.out
$ 7568
(WRONG!!!)

why:
gcc does not have intristics for
uint to long double conversion
therefore it does cast implicitly, so
the sign bit is preserved, but this does
not happen when __fixunsxfdi is called
because tcc was bootstrapped.

solution:
force cast to int64 and preserve the
sign bit.

side effects:
not found.
2020-09-08 22:12:01 +00:00
grischka
53d815b8a0 win32/tccpe: use full dll-path with -run
This allows for example this scenario:

- A dll to be linked with is specified in file.c, where file.c
  and the dll exist in the same directory:
    #pragma comment(lib, "txml")
    #pragma comment(option, "-L{f}")

- tcc is called to run file.c from other, varying directories:
    $ tcc -run some/dir/file.c <args...>

Note that tcc replaces {f} by the currently compiled file's
directory ('some/dir' in this example).

Also:
- tccgen.c: fix last commit for gen_cast.
2020-08-21 22:47:56 +02:00
grischka
d746e32349 tests2: rework 117..119 to follow our conventions
Please respect some conventions:

- tests2 filenames don't end with '..._test'

- tests2 tests are meant to produce some output

- the output should be somehow informative, not just
  "error" or "dummy". Because other people would want to
  know where it fails if it does.

- tests2 tests should work with both GCC and TCC, except
  if there are specifc reasons (like testing tcc-only
  feature such as bounds checking)

- tests2 tests should never crash or abort.  Because that
  would cause gui dialogs to pop up on windows, and because
  other people would not know where it fails if it does.

- tests2 tests should be somehow specific, in general.
  (rather than just collections of random stuff)

- in general, do not use 'long' if you mean 'larger than int'
  Because it isn't on many platforms.

- use four (4) spaces for block indention.  Do not insert
  tab characters in files if possible.

Also:
- tccgen.c:gen_cast() simplify last fix.
2020-08-21 21:44:11 +02:00
grischka
f9870f7860 bcheck: remove static (compile-time) control
Providing both run-time and compile-time control for bounds
checking as an user interface appears unnecessary and confusing.

Also:
- replace 'bound_...' by 'bounds_...' for consistency
- tcc-doc: put related info into one place and cleanup

The __bounds_checking(x) function is still missing explanation.
(I.e. what happens if the accumulated value drops below zero.)
2020-08-21 20:26:36 +02:00
herman ten brugge
a34a9775ba Fix char to ushort cast
tccgen.c:
- gen_cast: add check for char to ushort cast

tests/bug.c:
- remove tst1

tests/tests2/117_gcc_test.c:
- add tst_cast
2020-08-21 19:35:30 +02:00
herman ten brugge
696b765437 Fix switch/case
Fix switch for signed/unsigned switch
Also add new testcase 118
2020-08-18 20:05:53 +02:00
Willy Tarreau
b107f7bdd9 Fix switch/case on uint64_t
The switch/case operation was entirely performed on int64_t, resulting
in a warning and bad code to be emitted on 64 bit machines when used on
an unsigned long with a case range whose signed representation starts
positive and ends negative like in the example below:

  #include <limits.h>
  #include <stdio.h>
  #include <stdlib.h>

  int nbdg(unsigned long n)
  {
  	switch (n) {
  	case                    1UL ...                   9UL: return 1;
  	case                   10UL ...                  99UL: return 2;
  	case                  100UL ...                 999UL: return 3;
  	case                 1000UL ...                9999UL: return 4;
  	case                10000UL ...               99999UL: return 5;
  	case               100000UL ...              999999UL: return 6;
  	case              1000000UL ...             9999999UL: return 7;
  	case             10000000UL ...            99999999UL: return 8;
  	case            100000000UL ...           999999999UL: return 9;
  	case           1000000000UL ...          9999999999UL: return 10;
  	case          10000000000UL ...         99999999999UL: return 11;
  	case         100000000000UL ...        999999999999UL: return 12;
  	case        1000000000000UL ...       9999999999999UL: return 13;
  	case       10000000000000UL ...      99999999999999UL: return 14;
  	case      100000000000000UL ...     999999999999999UL: return 15;
  	case     1000000000000000UL ...    9999999999999999UL: return 16;
  	case    10000000000000000UL ...   99999999999999999UL: return 17;
  	case   100000000000000000UL ...  999999999999999999UL: return 18;
  	case  1000000000000000000UL ... 9999999999999999999UL: return 19; // this one
  	case 10000000000000000000UL ...             ULONG_MAX: return 20;
  	}
  	return 0;
  }

  int main(int argc, char **argv)
  {
  	unsigned long v = strtoul(argc > 1 ? argv[1] : "1111", NULL, 0);
  	printf("%lu : %d\n", v, nbdg(v));
  	return 0;
  }

  $ tcc dg.c
  dg.c:26: warning: empty case range
  $ x="";for i in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0; do x=$x$i; ./a.out $x;done
  1 : 1
  12 : 2
  123 : 3
  1234 : 4
  12345 : 5
  123456 : 6
  1234567 : 7
  12345678 : 8
  123456789 : 9
  1234567890 : 10
  12345678901 : 11
  123456789012 : 12
  1234567890123 : 13
  12345678901234 : 14
  123456789012345 : 15
  1234567890123456 : 16
  12345678901234567 : 17
  123456789012345678 : 18
  1234567890123456789 : 0
  12345678901234567890 : 20

What this patch does is to use a separate set of signed and unsigned
case_cmp functions depending on whether the expression is signed or
unsigned, and also does this to decide when to emit the warning.

The bad code on output was caused by the removal of the unsigned bit
resulting from the signed sort, which causes only signed comparisons
to be emitted in the asm code. As such some sets could not match.

Note that there is no way to rely on the values only to sort properly
nor to emit the warning because we're effectively dealing with 65-bit
arithmetic here and any two values will have a different behavior
depending on the signed or unsigned expectation.

For unsigned expressions now the warning only happens when bounds are
switched, For signed expressions (e.g. if the input is signed long
above), the warning remains and the abnormal output as well. In both
cases this remains consistent with what gcc produces.
2020-08-18 11:27:27 +02:00
herman ten brugge
4c9e3a5988 Update attribute bound_no_checking
tcctok.h:
- Add CONFIG_TCC_BCHECK  arround TOK_NO_BOUND_CHECK1/TOK_NO_BOUND_CHECK2

tccgen.c:
- Add CONFIG_TCC_BCHECK  arround TOK_NO_BOUND_CHECK1/TOK_NO_BOUND_CHECK2
- Undo alias definition in tccpp.c when function bound checking if off

tests/tests2/114_bound_signal.c:
- Test alias undo
- fix sleep problem
2020-08-14 06:35:47 +02:00
herman ten brugge
c740fa2795 Fix attribute patch for windows 2020-08-13 11:26:59 +02:00
herman ten brugge
50fe33f880 Add attribute bound_no_checking
tcc-doc.texi:
- Document attribute bound_no_checking

tcctok.h:
- Add bound_no_checking attribute

tcc.h:
- Add no_bcheck function attribute

tccgen.c:
- Use function attribute no_bcheck in merge_funcattr/parse_attribute/gen_function

bcheck.c:
- Fix no_checking in __bound_new_region/__bound_free/__bound_check

tests/tests2/114_bound_signal.c:
- Fix code with new attribute bound_no_checking

tests/tests2/103_implicit_memmove.c:
- Fix memmove prototype
2020-08-13 11:19:11 +02:00
herman ten brugge
8b8e714517 Fix bound checking for packed struct 2020-08-11 07:33:11 +02:00
herman ten brugge
09ed7e9557 Add bool debug type 2020-08-11 07:23:01 +02:00
herman ten brugge
dcb87d36fe Fix long bitfield
The fix is avoiding a core dump for radare2 project.
2020-08-09 07:50:34 +02:00
herman ten brugge
d55a3f3362 Fix riscv64 compare problem.
Fix 64->32 bits sign/zero extention for riscv64.
2020-07-30 09:40:35 +02:00
herman ten brugge
c1e1c17c0a Move bound functions to tccgen.c
Move gen_bounded_ptr_add() and gen_bounded_ptr_deref() code to tccgen.c
No functional changes.
2020-07-12 10:55:40 +02:00
herman ten brugge
fc05da3c0b Fix alloca and arm problems
alloca is only defined for i386 and x86_64
arm has __aeabi_ prefixes for mem... calls
2020-07-06 20:10:56 +02:00
grischka
2a0167adfe __builtin_/__bound_: A 'stay tiny' approach to the matter
tccgen.c:
- cleanup __builtin_... stuff
- merge __attribute((alias("sym"))) with __asm__("sym")
    Now one cannot have both, however for alias underscores are
    added if enabled.  For __asm__ they aren't.
tccpp.c:
- extend tcc_predefs accordingly.  Was generated with
  'cd tests/misc && tcc -run c2str.c tcc_predef.h tcc_predefs'
xxx-gen.c:
- move bcheck setjmp test to tccgen.c:gbound_args()
i386-gen.c:
- create win32 compatible stack space for big structures
tcctest.c:
- some cleanup + nicer output
2020-07-06 13:42:02 +02:00
grischka
72277967ff some cleanups related to recent commits
- configure/Makefile : cleanup, really use CC_NAME
- tccasm.c : remove C99 construct that MSVC doesn't compile
- arm-gen.c, x86_64-gen.c, riscv64-gen.c, tccmacho.c : ditto
- arm64-gen.c: commit 383acf8eff wrote:
  "Instead of a cast, it would be better to pass the exact type."
  It is true that there are better solutions but it is not
  passing the exact type (I think).
- tcctest.c: revert "fix cast test for clang" 03646ad46f
  this obviously wants to test non-portable conversions
- 114_bound_signal.test: clock_nanosleep is too new for older
  linuxes, just use sleep() instead
2020-07-06 13:00:47 +02:00
herman ten brugge
9712aff9c0 Fix gcc testsuite problems
arm-gen.c:
- is_hgen_float_aggr/gfunc_sret: Fix for zero sized structs

arm64-gen.c:
- arm64_ldrs: Fix for zero sized structs
- arm64_sym: Use R_AARCH64_ABS64 instead of R_AARCH64_MOVW_UABS_G*
             This has same speed. See 117_gcc_test.c(tst_adr)
- load: Fix for zero sized structs and add VT_CONST | VT_LVAL support
- store: add VT_CONST | VT_LVAL support
- arm64_gen_bl_or_b: Allow branch. See 117_gcc_test.c(tst_branch)
- gen_bounds_prolog: Use R_AARCH64_ABS64 for bound checking
- gen_bounds_epilog: Use R_AARCH64_ABS64 for bound checking
- gfunc_call: Allow large stack
- arm64_gen_opic: Do not crash on large shift

riscv64-gen.c:
- load: Move type_size call. (move_reg set sv.type.ref NULL for VT_STRUCT)
- gfunc_call: Allow large stack
- gen_opil: Fix word mode calls

x86_64-gen.c:
- load: Fix for zero sized structs

libtcc.c:
- Add some defines for gcc testsuite (only most common)

tccgen.c:
- parse_builtin_params: Add types for builtins
- unary: Add builtins: __builtin_abort __builtin_memcpy __builtin_memcmp
                       __builtin_memmove __builtin_memset __builtin_strlen
                       __builtin_strcpy __builtin_strncpy __builtin_strcmp
                       __builtin_strncmp __builtin_strcat __builtin_strchr
                       __builtin_strdup __builtin_malloc __builtin_realloc
                       __builtin_calloc __builtin_free __builtin_alloca
- decl_initializer: Fix crash. See 60_errors_and_warnings(test_var_array)

tccmacho.c:
- Remove 'ret = 0'

tcctok.h:
- Add builtin/bound checking tokens

tests/gcctestsuite.sh:
- Add more counters and run execute tests

tests/bug.c
- Some remaining bugs in tcc (not complete)

tests/tests2/60_errors_and_warnings:
- Add test_var_array test

tests/tests2/117_gcc_test:
- New test

Results of gcctestsuite.sh for all targets:

linux:
x86_64: 3036 test(s) ok.  328 test(s) failed.  24 test(s) exe failed.
i386:   3037 test(s) ok.  327 test(s) failed.  24 test(s) exe failed.
arm:    2986 test(s) ok.  362 test(s) failed.  40 test(s) exe failed.
arm64:  2996 test(s) ok.  367 test(s) failed.  25 test(s) exe failed.
macos:  3031 test(s) ok.  332 test(s) failed.  25 test(s) exe failed.
riscv:  2948 test(s) ok.  401 test(s) failed.  39 test(s) exe failed.

windows:
x86_64: 3027 test(s) ok.  333 test(s) failed.  28 test(s) exe failed.
i386:   3029 test(s) ok.  331 test(s) failed.  28 test(s) exe failed.

linux with bounds checking:
x86_64: 3030 test(s) ok.  328 test(s) failed.  30 test(s) exe failed.
i386:   3028 test(s) ok.  327 test(s) failed.  33 test(s) exe failed.
arm:    2997 test(s) ok.  362 test(s) failed.  29 test(s) exe failed.
arm64:  2986 test(s) ok.  367 test(s) failed.  35 test(s) exe failed.
macos:  3026 test(s) ok.  332 test(s) failed.  30 test(s) exe failed.
riscv:  2936 test(s) ok.  409 test(s) failed.  43 test(s) exe failed.

windows with bounds checking:
x86_64: 3029 test(s) ok.  332 test(s) failed.  27 test(s) exe failed.
i386:   3027 test(s) ok.  331 test(s) failed.  30 test(s) exe failed.

all: fail for complex and vector types, nested functions
     and a lot of gcc defines/buitins.
arm/arm64/riscv: fail for asm and alloca.
riscv: fail with 'error: unimp: store(struct)'
2020-07-05 14:01:50 +02:00
Michael Matz
ba8980f492 limit gnu_inline hack to macos
some linux programs (kernel) really want to have 'extern inline'
functions be visible from other units, i.e. not be static, but also
mark them as always_inline.  That's -fgnu89-inline semantics, so it's
fine, but we don't (yet) implement this, so we can't make them static
just so.  But we do need this hack on MacOS due to some uses in
system headers (see commit f18f8651).

So, for now conditionalize the hack on Mach-O.
2020-06-21 02:03:46 +02:00
Michael Matz
f18f865159 Handle always_inline as GNU inline
this is needed for multi-file testcases using stdio.h, as
the __sputc function is implemented as a extern inline
function (with gnu_inline attribute, but we don't support that for now).

Without this change that leads to multiply defined symbols when using
multiple units including stdio.h.

It also has an always_inline attribute, which we can use to guide our
behaviour, as in ISO-C an always_inline can't be defined with ISO
'extern inline' semantics.  This is the minimal change and not a full
implementation of GNU inline semantics, which would require thorough
testcases.

If __clang__ would be defined the header would make use of C99 semantics,
which would work for us.  It would also do that if _GNUC_ wouldn't be
defined.  But we can't do the latter (as the whole MacOSX SDK refuses
to be compiled with anything not defining that).  I haven't tested
defining __clang__, but suspect that's going to be problematic.
2020-06-20 22:14:56 +02:00
Michael Matz
94066765ed macos: First cut at generating Mach-O executables
this does generate a working executable for a very simple
example input, e.g. this:

% cat simple.c
int main(void)
{
  return 0;
}
% ./tcc -B. -c simple.c
% ./tcc -nostdlib -B. simple.o -lc
% ./a.out && echo okay
okay

(the -lc is actually not necessary right now, see below).  This
has many limitations:

* no symbol table, hence no calls to external functions from
  e.g. libc, aka libSystemB
* no proper entry point (should be main, but is hardcoded to first
  real .text address)
* libSystemB is hardcoded, no other libs are supported (but again
  no external calls anyway)
* generated Mach-O executable is in old format: neither LC_DYLD_INFO
  no export tries for symbols are created (no symbol table at all!)
* the __LINKEDIT segment is faked and empty, as dyld doesn't like
  it empty even if no symbols point into it
* same with __DATA, dyld wants a non-empty writable segment which
  we enforce with useless data
* no relocations, hence no function call stubs (lazy or not) are
  generated
* hardcodes some other constants as well
2020-06-20 22:09:21 +02:00
Michael Matz
7b6931ed1f Fix some string literal expressions in initializers
Things like 'char x[] = { "foo"[1], 0 }' (which should initialize
a two-character array 'x' with "o\0").  See added testcase.
2020-06-20 22:00:18 +02:00
grischka
b5faa45d90 tccpp: faster next()
- call TOK_GET() as a function only for tokens with values
- get rid of 'next_nomacro_spc()'
- be sligtly more efficient in next()

This made about 4-5%+ speed in my tests.

Also: tcc.h: reorder tokens
2020-06-17 18:44:11 +02:00
herman ten brugge
44019e874f Fix debug info for functions
Add code for VT_FUNC.
Use octal number for unsigned int/unsigned long for 32 bits targets.
Add VT_BYTE | VT_UNSIGNED for targets with default unsigned signed char.
Remove extra ',' in default_debug struct.
2020-06-17 07:58:18 +02:00
herman ten brugge
0b8ee7364a Add bound checking to arm, arm64 and riscv64
Checked on:
- i386/x86_64 (linux/windows)
- arm/arm64 (rapberry pi)
- riscv64 (simulator)
Not tested for arm softfloat because raspberry pi does not support it.

Modifications:

Makefile:
  add arm-asm.c to arm64_FILES
  add riscv64-asm.c (new file) to riscv64_FILES

lib/Makefile:
  add fetch_and_add_arm.o(new file) to ARM_O
  add fetch_and_add_arm64.o(new file) to ARM64_O
  add fetch_and_add_riscv64.o(new file) to RISCV64_O
  add $(BCHECK_O) to OBJ-arm/OBJ-arm64/OBJ-riscv64

tcc.h:
  Enable CONFIG_TCC_BCHECK for arm32/arm64/riscv64
  Add arm-asm.c, riscv64-asm.c

tcctok.h:
  for arm use memmove4 instead of memcpy4
  for arm use memmove8 instead of memcpy8

tccgen.c:
  put_extern_sym2: for arm check memcpy/memmove/memset/memmove4/memmove8
                   only use alloca for i386/x86_64
  for arm use memmove4 instead of memcpy4
  for arm use memmove8 instead of memcpy8
  fix builtin_frame_address/builtin_return_address for arm/riscv64

tccrun.c:
  Add riscv64 support
  fix rt_getcontext/rt_get_caller_pc for arm

tccelf.c:
  tcc_load_dll: Print filename for bad architecture

libtcc.c:
  add arm-asm.c/riscv64-asm.c

tcc-doc.texi:
  Add arm, arm64, riscv64 support for bound checking

lib/bcheck.c:
  add __bound___aeabi_memcpy/__bound___aeabi_memmove
      __bound___aeabi_memmove4/__bound___aeabi_memmove8
      __bound___aeabi_memset for arm
  call fetch_and_add_arm/fetch_and_add_arm64/fetch_and_add_riscv64
  __bound_init: Fix type for start/end/ad
  __bound_malloc/__bound_memalign/__bound_realloc/__bound_calloc: Use size + 1

arm-gen.c:
  add bound checking code like i386/x86_64
  assign_regs: only malloc if nb_args != 0
  gen_opi/gen_opf: Fix reload problems

arm-link.c:
  relocate_plt: Fix address calculating

arm64-gen.c:
  add bound checking code like i386/x86_64
  load/store: remove VT_BOUNDED from sv->r
  arm64_hfa_aux/arm64_hfa_aux: Fix array code
  gfunc_prolog: only malloc if n != 0

arm64-link.c:
  code_reloc/gotplt_entry_type/relocate: add R_AARCH64_LDST64_ABS_LO12_NC
  relocate: Use addXXle instead of writeXXle

riscv64-gen.c:
  add bound checking code like i386/x86_64
  add NB_ASM_REGS/CONFIG_TCC_ASM

riscv64-link.c:
  relocate: Use addXXle instead of writeXXle

i386-gen.c/x86_64-gen.c
  gen_bounds_epilog: Fix code (unrelated)

tests/Makefile:
  add $(BTESTS) for arm/arm64/riscv64

tests/tests2/Makefile:
  Use 85 only on i386/x86_64 because of asm code
  Use 113 only on i386/x86_64 because of DLL code
  Add 112/114/115/116 for arm/arm64/riscv64
  Fix FILTER (failed on riscv64)

tests/boundtest.c:
  Only use alloca for i386/x86_64
2020-06-16 07:39:48 +02:00
Michael Matz
9eef33993a Fix type compatiblity of enums and ints
an enum must be compatible with one or more integer type,
so adjust the test accordingly.  That means the following
redeclarations should work:

  enum e6 { E1 = -1, E0 };
  void f3(enum e6);
  void f3(int);        // should work as int and e6 are compatible

while the following should not:

  void f4(enum e6 e);
  void f4(unsigned e); // should error as unsigned and e6 are incompatible
2020-06-05 16:02:08 +02:00
herman ten brugge
3b617fdc53 Add sigsetjmp/siglongjmp bound checking support
tcctok.h:
- Add sigsetjmp/__sigsetjmp/siglongjmp

tccgen.c:
- redirect sigsetjmp/siglongjmp to bcheck.c code

i386-gen.c/x86_64-gen.c
- gcall_or_jmp: Set func_bound_add_epilog also when sigsetjmp is called
- gen_bounds_epilog: Only call __bound_local_new when needed (unrelated)

bcheck.c:
- Add __bound_siglongjmp
- __bound_setjmp/__bound_long_jump: Check no_checking
- Optimize __bound_local_delete (unrelated)

Modify testcase:
- 114_bound_signal
2020-05-25 12:26:55 +02:00
herman ten brugge
045632defb Fix gcc10 warnings
i386-gen.c:
- load/gen_opf: set v1.sym to NULL

lib/Makefile:
- Add -gstabs -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable

lib/bt-log.c:
- tcc_backtrace: Prevent __builtin_frame_address warning

tccgen.c:
- struct_layout: Set t.t to VT_BYTE
- default_debug: Use octal instead of -1 to make size_t work

tccpp.c:
- tal_realloc_impl: Only memcpy when p set

x86_64-gen.c:
- gen_bounds_epilog: Do not save/restore rcx (not caller/callee saved)
                     This also made stack not aligned to 16 bytes.
2020-05-23 20:27:43 +02:00
herman ten brugge
b5b92c7d6d Add setjmp/longjmp bound checking support
tcctok.h:
- Add __bound_setjmp/setjmp/_setjmp/longjmp

tccgen.c:
- redirect setjmp/longjmp to bcheck.c code

i386-gen.c/x86_64-gen.c
- Change func_bound_alloca_used into func_bound_add_epilog
- Set func_bound_add_epilog also when setjmp is called

bcheck.c:
- Add __bound_setjmp/__bound_longjmp
- __bound_local_delete: remove setjmp if used in function
- __bound_exit: clear setjmp list and print statistic
- make malloc_redir more readable (unrelated)

New testcases:
- 115_bound_setjmp
- 116_bound_setjmp2
2020-05-23 20:02:41 +02:00
grischka
4429cef9f6 tccgen.c: merge more function attributes
Merge function attributes with those given given for the
prototype, also handle post-decl appearance such as

    void func() __attribute__((noreturn))
    {
    }

Also, some test fixes (unrelated).
2020-05-13 11:39:39 +02:00
grischka
9c28349757 tccgen.c: cleanup debug support
from 3e731e3a78

tccgen.c:
- make 'struct default_debug' const
- pass TCCState* as parameter to tcc_debug_xxx functions
- always check tcc_state->do_debug before calling functions
- factor out tcc_debug_extern_sym()
- remove formats "%lld"/"%llu" (not reliable on windows)

xxx-gen files:
- set func_vt/var from caller
2020-05-11 11:41:56 +02:00
grischka
5bc1720776 tccgen.c: move 'alloca_used' complication to *-gen files
related to commit 8370bc03a1
2020-05-11 11:41:56 +02:00
herman ten brugge
29ba50da29 Fix some printf like functions 2020-05-05 09:00:24 +02:00
herman ten brugge
8370bc03a1 Allow signal handlers when bound checking
Disable generating bound_local_new/bound_local_delete when not needed.
Add new testcase 114_bound_signal.
2020-05-05 08:31:57 +02:00
herman ten brugge
973a14bb2f Fix symbolic debugging for -g -dt -run 2020-05-04 08:13:41 +02:00
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