The code:
void mul(double *p)
{
*p *= 2.0;
}
failed on x86_64 because register was not loaded after
bound checking call.
Also printed size when pointer indir failes.
I updated the tests/gcctestsuite.sh a bit.
before:
3329 test(s) ok.
210 test(s) skipped.
168 test(s) failed.
28 test(s) exe failed.
after:
3331 test(s) ok.
299 test(s) skipped.
79 test(s) failed.
26 test(s) exe failed.
I found some small problems:
include/tccdefs.h: Add alloca definition for i386 and x86_64
lib/alloca.S/lib/alloca-bt.S: align i386 alloca to 16 bytes.
i386_gen.c vla code and gcc do the same.
x86_64-gen.c: fix typo in comment
arm-link.c: remove some casts
tccelf.c: code style and remove code
tccpp.c: use correct pointer size so cross compiling works
riscv64-gen.c: make code more readable
I tried to fix all remaining warnings/errors reported by -fsanitize.
The riscv64-gen.c is a bit large because it contained a lot of warnings.
I forgot some arm-link.c changes in last commit.
The other changes are all small fixes to avoid warnings/errors.
Tested code with:
clang -fsanitize=address,undefined,nullability -pie -fPIE -Iinclude -I. -g tcc.c -o tcc.tcc -lm -ldl -lpthread
./tcc.tcc -Iinclude -I. -b -g tcc.c -o tcc.tcc1 -lm -ldl -lpthread
Also checked on i386/x86_64 with -fsanitize=memory (others not supported).
arm-link.c: use read32le/write32le/add32le to avoid unaligned access
tcc.h i386-asm.c: fix signed left shift
lib/bcheck.c: Add _Atomic
libtcc.c: Correct MEM_DEBUG_CHECK3 to avoid unaligned access
riscv64-link.c: Fix R_RISCV_SET16
tccpp.c: Align tal_header_t to avoid unaligned access
tccgen.c x86_64-gen.c: avoid use of uninitialized value
There are still warnings reported:
tccgen.c:4031:13: runtime error: member access within null pointer of type 'TCCState' (aka 'struct TCCState')
tccelf.c:321:22: runtime error: applying zero offset to null pointer
tccelf.c:1132:23: runtime error: applying non-zero offset 169184 to null pointer
A lot of left shift of negative value warnings.
I ignored these for the moment.
Also the -run option does no work well with -fsanitize. It gets confused
because it does not detect that the generated code in memory is used
without -fsanitize option.
There are a lot more -fsanitize options. I did not find serious problems
with them.
While adding some testcases for attribute cleanup I found a
bug in the riscv code. It modifies the sv->c.i in load_symofs.
If a structure contains more then one element only the
first is stored correctly. This only happens on a large
stack frame.
Fixed by saving/restoring sv->c.i.
workflows/build.yml:
- win32/64: install mingw32/64 gcc on msys (because the default
gcc installed elsewhere seems to use ucrt, producing incompatible
fp printf formats.)
tccgen.c:
- cleanup funcs: save any lvalues from return expressions. Also use
get_temp_local_var() which however was causing a problem on i386
because its gfunc_call() removes the arguments from vstack and by
that defeats the 'in-use' tracking of get_temp_local_var(). Fixed by:
i386/arm/arm64/x86_64-gen.c:
- in gfunc_call(): save_regs before anything else, fixes
problems seen in arm64/i386
tccpp.c:
- allow arm asm specific use of '#' in macros
libtcc.c:
- organize -M options, and:
tccpe.c:
- move the subsystem option parsing from libtcc.c
tccelf.c:
- improved error handling in tcc_load_ldscript()
lib/atomic.S:
- TCC_TARGET_... not defined when building the lib
- endbrNN security feature not supported by TCC
tests/tests2/136_atomic_gcc_style.c:
- never use standard assert() in tests
In gfunc_call(), structure members are loaded into registers during
argument handling.
This operation may overwrite previous function call results stored in
registers (e.g., s0). To prevent this, we must save function call
results to the stack before processing structure arguments.
The functions fetch_and_add_arm, fetch_and_add_arm64 and
fetch_and_add_riscv64 where removed with atomic change.
Replace the code in bcheck.c with call to atomic_fetch_add.
Use asm implements for i386/x86_64/arm/aarch64/riscv:
__atomic_load_[1,2,4,8]
__atomic_store_[1,2,4,8]
__atomic_compare_exchange_[1,2,4,8]
__atomic_test_and_set_[1,2,4,8]
atomic_thread_fence
atomic_signal_fence
atomic_flag_test_and_set
atomic_flag_test_and_set_explicit
atomic_flag_clear
atomic_flag_clear_explicit
`atomic.S` is extracted from `gcc` v15.1.0 `libatomic.a`.
And generated by https://github.com/kbkpbot/gen_atomic.git
tcc_set_str() already calls tcc_free() to free the memory of the stringpointer in s->outfile.
With the additional tcc_free(), the memory would be freed twice.
--
Regards ... Detlef
This makes attribute cleanup code work the same as gcc and also
makes bound checking a very little bit faster.
tcc.h:
Add save_return_reg(CType *) and restore_return_reg(CType *)
Change gfunc_epilog() to gfunc_epilog(Sym *)
arm-gen.c:
arm64-gen.c:
c67-gen.c:
i386-gen.c:
il-gen.c:
riscv64-gen.c:
x86_64-gen.c:
Move save and restore register around bound_local_delete call
to save_return_reg and restore_return_reg.
Pass func_type from gfunc_epilog to gen_bounds_epilog.
tccgen.c:
Call save_return_reg/restore_return_reg in try_call_scope_cleanup
when RETURN is found.
tccrun.c:
Fix warning when bound checking not used.
tests/tests2/101_cleanup.c
tests/tests2/101_cleanup.expect
Extra checks attribute cleanup save/restore registers.
tests/tests2/Makefile:
Fix when bound checking not used.
This commit adds GCC-compatible atomic builtins to stdatomic.h for
better compatibility with code relying on GCC's atomic primitives.
1. **New Macros**:
- `__atomic_compare_exchange_n`.
- `__atomic_load_n`.
- `__atomic_store_n`.
2. **Motivation**:
- Improves compatibility with codebases using GCC's atomic builtins
directly.
- Simplifies atomic operations by allowing direct value passing
(instead of pointers), enhancing code readability.
- Aligns TCC's atomic support closer to GCC/Clang for cross-compiler
projects.
3. **Testing**:
- Verified with basic test cases (integer CAS, load/store) on x86.
- Confirmed no regressions in existing atomic operations.
- This change does not affect existing C11 `atomic_*` APIs.
- Struct types are intentionally unsupported in `_n` variants due to
complexity.
cleanup libtcc.c:tcc_set_linker()
cleanup tccelf.c:tcc_load_ldscript()
Also
- tccrun.c, tccelf.c:relocate_syms():
with tcc -run -nostdlib, do resolve but only from explicitly
on the command-line given libraries.
- tccgen.c: optimize UMOD x % c -> x & (c-1) for c = 2^n
- tcc-doc.texi: cleanup
- tcc.h, tccpp.c, libtcc.c: add 'size' arg to pstrncpy()
Also reorder functions in libtcc.c a bit.
9 files changed, 556 insertions(+), 617 deletions(-)
Aka 'intmax_t', as recommended by newer standards.
For example
if (-0x80000000 < 0) is false,
but
#if (-0x80000000 < 0) is true
because in C, 0x80000000 is an unsigned int, Whereas in
a preprocessor expression, it is a signed long long, even
without LL suffix.
Oviously what the patch wants is... on Windows, with
"tcc c:/dir/xyz.dll -run file"... pass the absolute
path of the dll to LoadLibrary() which can make sense
in situations.
Other changes in the patch to other platfurms seem to
have no effect. This reverts 52a9a541b0
except 2 lines in tccpe.c.
Also revert _Float16 patch a06c608625
As long as tcc does not really handle _Float16, we can just define
it in tccdefs.h.
Also move uint128_t to tccdefs.h for same reason.
Update github action (might fix random arm64 crashes)
arm-asm.c: add forward branches & some ops
lib/armeabi.c: faster i/udivmod (asm)
arm-gen.c: use movw/movt to load constants for CPUVER >= 70
configure: use dwarf-4 debug sections on android, detect idiv
lib/Makefile: always add -I$(TOP) for access to config.h
tcdbg.c: add a "code mapping symbol" to help out llvm-objdump
tccelf.c: don't load SHT_ARM_EXIDX, modify ARM.attributes
tccpp.c: accept '@' for arm asm comments
libtcc.c:
- free 'elfint' string
- acceot -O and -Os
- accept -gstabs (to override dwarf when default)
- better -Wp,...
tccpp.c:
- #line cleanup
also warn with "extra tokens after directive"
tccgen.c & xxx_gen.c:
- force CPU flags to register earlier
tccelf.c:
- tcc_load_object: align size only for code sections
data/bss objects are always put with their specfic type align
(in decl_initializer_alloc())
x86/64 doesn't need aligned code
from c6afdff7ab
tccpe.c:
- enable dllimport for "_imp__<sym>" also from assembler
x86_64-gen.c & lib/libtcc1.c:
- simpler fneg without libtcc1 reference
tests2/134_double_to_signed.c:
- a tcc compiled by msvc won't pass this test
TCC treats -nostdlib and -Wl,-nostdlib as equivalent, but on other compilers
which call a discrete linker, -nostdlib behaves as on tcc (not adding
startfiles/libc/endfiles) by modifying the ld command line, but -Wl,-nostdlib
adds -nostdlib to the ld cmdline, which stops the linker searching the default
directories for libraries.