tccpe.c:
- fix arm64 unwind codes (to make native set/longjmp() work)
sizeof(RUNTIME_FUNCTION) is 8 on arm64 in the first place
no need to note stack slots if we don't save any registers anyway
arm64-gen.c:
- fix long double reg-move
- fix arm64_hfa() for structs with float arrays
- gfunc_prolog(): setup stackframe eariler (simplifies unwind codes)
- new function gv_addr(RC);
win32/include/setjmp.h:
- provide correct definition for setjmo() (frameoffset = 224)
tccasm.c:
- support ".quad" with symbol & relocation
- support ".size"
- fix ". - symbol" arithmetic
win32/lib/crt1.c and win32/include/stdlib.h:
- do not write to __argc/__argv which reside in msvcrt.dll
(msvcrt.dll on arm64 does not like that, crashes on unload)
tcc.c,libtcc.c:
- new functions tcc_fopen/fclose to avoid different stdio unstances
in tcc.exe & libtcc.dll
tests & github workflow:
- add test-win32.bat to run tests with a tcc compiled by build-tcc.bat
- add msvcrt_start.c for gcc/clang to use the same runtime as tcc
the problem is that newer gcc as well as clang and cl are
linking to newer runtimes (such as UCRT) that have partially
different printf format behavior which makes tcctest fail.
the solution here is to force these compilers to link with
msvcrt.dll just like tcc.
Also, there is no gcc on arm64-win32 currently at all.
Anyway, this approach to running the github CI tests
does not require msys2. But It does rely on gnumake
as well as on some 'sh' shell though which seems to be
installed somewhere (maybe it is the one from git).
from: https://github.com/bold84/tinycc
Author: Benjamin Oldenburg <benjamin.oldenburg@ordis.co.th> 2026-04-04 16:29:28
Committer: Benjamin Oldenburg <benjamin.oldenburg@ordis.co.th> 2026-04-04 16:29:28
Branch: win_arm64_clean
Commit: 8b5ab1bb01
Also here: https://repo.or.cz/tinycc.git/shortlog/refs/mob/mob_bold84/win_arm64_clean
This and the followup commits on mob is selected parts
of that original branch. So it is not everything.
It is not, for example:
- unrelated whitespace changes in many files
- a "pin msvcrt.dll" feature in tccpe.c (why that)
- a native getenv() replacement in tcc.c (why that)
- larger changes to the win32/lib runtime and tccrun.c (not needed)
- a very gcc specific detail for struct alignent in tccgen.c
- a custom set/longjmp implementation/replacement (not needed)
- lots of rather basic test files in the win32 folder
- a 'tests/asm' folder with some files (one file renamed to 140_test...c)
- a .docs folder with one file
This reverts the crap from an unknown committer "OpenCode[AI]", that added an extension to TinyCC,
which is incompatible to the C standard and not available in any other mainstream C compiler:
* Revert "No More ; needed"
This reverts commit 6547ea47d6
* Revert "Add AGENTS.md"
This reverts commit 898f496dc9.
This also reverts a regression fix by "Zuhaitz.dev", which fixed a small part of the OpenCode-AI chaos:
* Revert "tccgen: Fix optional semicolon regression"
This reverts commit 169628a6ab
--
Regards ... Detlef
workflow:
- revert 'pinact for security' for readability
from 831c3fa184
tccpp.c:
- remove code that allows tcc to parse numbers incorrectly (*)
from 829c848520
tccgen.c:
- Revert "Relaxed the 'incompatible pointer type' warning a bit" (*)
from d9ec17d334.
tccrun.c:
- remove support for -nostdlib -run
for simplicity, we require "main" with tcc -run always
tccpp.c:
- Revert "Free all preprocessor memmory in case of error."
from c96f0cad61
Remove TinyAlloc->limit instead. Thus it can do also bigger
allocs. Big TokenStrings (like 200kb+ when compiling tcc)
may come from inline functions or from large initializers.
Makefile/configure:
- use --config-pie for configuring tcc output only
- use -fPIC with clang-x86_64 to avoid 32-bit relocs
libtcc.c:
- fix "tcc file.c -run" i.e. -run as last argument
i386-gen.c:
- PIC refactor
(*) sorry, but code in tcc should have a minimum of generic relevance
* case 1: local scope of 'ff'
int main() {
int ff = 123;
{
int ff(int):
ff(456)
}}
* case 2: linkage of a static extern symbol
(older gcc did allow that)
static int ff(int);
int main() {
int ff(int):
ff(456)
}
Also:
- cleanup enum, let sym_push() handle redefinition
- just mark incomplete array base types, unshare only
when needed (in decl_initializer_alloc())
- fix sizeof empty array (= 0) : int ii[] = {};
- rename 'Sym' members used by __attribute__((cleanup(f)))
Fix 'void func2(char *(*md)(char *md))' declaration.
Fix global array and local extern array problems.
Fix scope problem with old function declaration.
Fix 'typedef int t[]' declaration. Empty size should remain.
... see tests
Also:
- tccgen.c: cleanup _Generic a little
- libtcc.c: cleanup mem-debug a little
- arm-link.c: read/write only once
- tcc.h: another fix for clang offsetof
- tccdbg.c:
* stabs: handle forward struct/enum decls
* stabs: fix anonymous struct members (must not have a .L123 name)
* avoid strncpy()
int foo(struct xxx {int x[3];} *p) { ...
We want 'xxx' be visible only inside the function. To get that,
the patch removes the 'sym_push(param)' in xxx-gen.c, and instead
(in tccgen.c:gen_function()) pushes all symbols that were newly
defined during parsing of the parameter list in post_type().
Also,
- decl_initializer_alloc():
patch existing globals earlier, which updates flex arrays too
- let patch_type() do the 'redefinition' check and FUNC_OLD update
tcc.c:
- be nice to leak checkers
tcctools.c:
- remove unused TCCState params
tccrun.c:
- call bound_exit() after signals to let it free mem
tccelf.c:
- use section_add() instead of section_ptr_add() when
more appropriate
tccpp.c:
- use size_t to align tal_header naturally
- 'POINTER_SIZE' and 'PTR_SIZE' in the same source is confusing
- "char file_name[TAL_DEBUG_FILE_LEN + 1];" looks silly.
- next_nomacro(): skip UTF8 BOM at BOF
tccgen.c:
- get rid of STMT_EXPR clause on top of block
- warn with useless type like 'int;'
- move skip()'s in block() for better error line-info
- BIT_SIZE bits are meaningful only with VT_BITFIELD
(not with enums for example)
workflow/test-win32:
- build with MSVC using build-tcc.bat also
alloca.S:
- fix 'off by one' problem on win32 (must touch current page
too because the 'push %edx' at the end could touch the next page)
- must not align greater than 4 when used for struct args
(i386-gen.c:gfunc_call())
libtcc.c:
- accept -g1dwarf (dwarf output, only line info)
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.
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.
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.
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
patch originally made to prove correctness (comparing stages)
with tinycc compiling gcc 2.95.3 which would assign registers
differently (but still correctly) when compiled with tcc without
this option).
Also: fixes get_temp_local_var() which on 32-bit systems
happened to return a temporary location that was still
in use because its offset was changed on the vstack
(incremented by four in gv() to load the second register
of a long long).
Also: optimize vrot-t/b (slightly) by using one memmove
instead of moving elements one by one in a loop.
- output correct line number with "error: duplicate case value"
- libtcc.c:error1(): support specific line numbers with "%i:"
tcc_error("%i:message ...", line_num, ...);
Also:
- simplify signed/unsigned switch compare
- optimize implicit case ranges such as
case 1: case 2: case 3: ...
- simplify llong constant propagation in gen_opic()
- rename Sym.ncl to Sym.cleanup_func
- new LIBTCC API tcc_setjmp() to allow longjmps & signals
from compiled code back to libtcc per TCCState
- new LIBTCC API tcc_set_backtrace_func() to handle backtrace output
- move c/dtor/atexit stuff to runtime (lib/runmain.c)
- move bt-log.o into libtcc1.a
- add timeouts to github action (beware, it did happen to hang
infinitely in the signal handler at some point)
- remove TOK_NOSUBST, mark the token itself instead
- get_tok_str(); mask out SYM_FIELD & update uses
- next(): optimize (~5% faster with tcc -E)
- tok_flags: remove some redundancy
- parse_define(): do not remove spaces around '##' and after '#'
and mark macros with '##' as MACRO_JOIN to avoid unnecessary
call to macro_twosharps(mstr):
- next_nomacro(): removed, next_nomacro1(): renamed to next_nomacro()
- next_argstream(): cleanup & new function peek_file()
- macro_subst_tok(): handle special macros (__DATE__ etc.)
like normal macros if they are #defined
- -DPP_DEBUG : more structured output
- pp_error(): better preprocessor expression error message
- tcctok.h: sort basic keywords (somehow)
- testspp/Makefile: generate .expect with 'make testspp.##+'
- tcc.c: tcc -E -o file : put unixy LFs also on windows
tccpp.c:
- revert "Preprocessor fix + new testcase"
Fix was not a fix and nobody could understand the test.
This reverts 6379f2ee76
- better fix and add new test (pp/18.c)
tccgen.c:
- remove global variables 'in_sizeof', 'constant_p'
- rework comma expression (gexpr())
- merge func/data 'alias_target' codes
(See 08c777053c)
- move call to do_Static_assert()
- better error: "expression expected before '%s'"
- fix "statement after label"
- remove unnecessary second parameter to block()
- remove unnecessary call to decl()
- revert changes to old C89 test file
See 7f0a28f6ca
tccelf.c:
- rework "...make undefined global symbol STT_NOTYPE"
(See f44060f8fc)
- move tccelf_add_crtbegin() from libtcc.c
tcctest:
- unfix K&R fix (keep old look of K&R functions)
tccrun.c:
- exit(0) returns 0
libtcc.c:
- move #defines for -dumpmachine
- more explicit error "file not found"
(as opposed to error while loading file)
tccpe.c, x86_64-gen.c, i386-asm.c, tccasm.c:
- use R_X86_64_PLT32 for functions on x86_64-win32
tccdefs.h
- empty #defines for _Nonnull, __has_builtin(), etc.
configure:
- Simpler "macOS .dylib ... VERSION letters."
(See 6b967b1285)
Makefile:
- macOS version also
- add cross searchpaths for packages
build.yml:
- disable codesign on macos-11 (doesn't seem to work)
This reverts commit ece74ceaaf.
codesigning is already supported via --config-codesign.
This patch actually broke testing for tcc builds with
that set.
Allows running the tests out-of-the-box on macOS.
Also delete *.dylib in tests2 dir on "make clean".
One remaining issue on macOS 14.1 is that the
-undefined warning option no longer works,
thus breaking test3 and test1b.
The testcases 22_floating_point and 24_math_library did not work with
make tcov-test
Add -lm for these in tests/tests2/Makefile
gcc -fanalyzer complains about tcc_malloc and tcc_realloc because
malloc(0) and realloc(ptr, 0) is not tested correctly.
configure:
- option --targetos=... for cross build
- cleanup
win32/build-tcc.bat:
- option -b <bindir>
- make 'libtcc1.a' and cross-prefix-libtcc1.a
(same convention as with makefile)
Makefile:
- streamline tcov-tests, help, etc.
workflow/build.xml: simplify
- using "windows-2019" runner (instead of windows-latest)
because its msys seems more complete and has no problems
with the 96_nodata_wanted.test either.
Changelog,TODO,USES,tcc-doc.texi: update
The following targets are added:
testc / testc2.all / testc2.37 / testc2.37+ / testc2.37-
testcpp.all / make testcpp.17
This allows to check that the testcase(s) test the code modified.
See Makefile tests/pp/Makefile tests/tests2/Makefile
lib/tcov.c: Fix while loops with fgets.
tcc.h: Fix tcc_p compilation with latest gcc
tests/tests2/22_floating_point.*: Better test floating point