Repository navigation
Version 0.8.6
Pre-release
Pre-release
Changes / improvements
@asmnameallows defining external names like@cnamebut without normal name mangling.- Improved GfxKey mappings.
- Add the
source-libtarget type (andc3c source-libcommand) to pack the C3 sources, C sources and headers of a project into a.c3llibrary. .c3lmanifests withouttargetsnow work for all platforms, and may containversion,authorsandlangrev.fetch,vendor-fetchandproject fetchnow unpack libraries into a<name>.c3ldirectory by default. Use--decompress=noto keep them compressed.fetchnow verifies the downloaded library against thechecksum(sha256:<hex>) of the registry, and refuses a library that doesn't match.dependencies, in projects and in library manifests, may name a registry library as[<url>:]<namespace>/<name>[@<version>]. The build only uses the name.fetchadds just the library name todependencies.project fetchonly fetches the libraries it is given:c3c project fetch <library>.... Without any, it lists the missing ones. Each must be a dependency of the project, or of a library that is installed. A name uses the path of the dependency, or is looked up in the registry: thefetch-urlproject property or--fetch-urlfor the project's dependencies, the default registry for those of libraries.- A version in the registry's library info may have a
url, whichfetchdownloads the library from instead of from the registry itself. - A registry library can be locked to a checksum:
<namespace>/<name>@<version>:<sha256>.fetchrefuses a library that doesn't match. - An
else ifnow requires{ }around a single statement, likeelsedoes.else if (x) foo();is an error. #3473 - Add
depends-onto project targets, allowing them to depend on other targets. - LLVM IR (
.ll) and bitcode (.bc) files can be added to the compilation, just like .o files #3339 project.jsonstrings (exceptexecandtype) expand environment variables written as${NAME}. #3580- Add
envandenv-overridetoproject.json, setting environment variables ("NAME=value") for theexecscripts. #3580 - Add
-gline-tables-onlyto emit line tables debug info only. - Disallow
{ .a = 1, .a = 1 }. #3579 - Add better instantiation error output.
- Implicitly converting a negative constant to a wider unsigned type, e.g.
ulong x = -1;, is now correctly an error. - Improved the error when implicitly casting an enum to an integer, it now points to the explicit cast.
- Casting a non-constant integer larger than a pointer, e.g. an
int128, to a pointer is now an error. Cast it touptrfirst. - Converting between signed and unsigned integers of the same size in arrays, slices and vectors, e.g.
int[3]touint[3], requires explicit casts. float16andbfloatno longer convert implicitly to each other, as both directions lose information.- An explicit cast of a slice to a pointer is now allowed for any pointer type, like a cast between pointers.
- Selectors are now a stable 128 bit signature. The first 16 bytes are guaranteed unique.
- Add
--stats=<none|summary|full|json>for compiler statistics. - Removed
--print-large-functions,--stats=fullreplaces it. - Compiler generated panics will now be emitted to the
std::core::runtime::panicsmodule. PanicFnis changed to support both formatting and non-formatted messages.--panic-msg=noonly traps if--show-backtrace=nois also set, otherwise it gives the short message with file, function and line.--show-backtrace=nostops passing file, function and line.--panicfnnow names a function rather than a function pointer variable, and sets the initial value ofbuiltin::panicthrough the new$$PANIC_FN, so stdlib panics andabortalso reach it. #3443- Make panic on infinite loops opt-in with
--infinite-loop-detect=yes– and is only added in safe mode. #3630
Fixes
- Compressed
.c3llibraries were not unpacked again when only files other thanmanifest.jsonhad changed. - Fixed regression for MacOS loading multiple C3 dylibs.
@finalizernow correctly works in descending order. - Fix miscompilation for OpenBSD on later processors. #3563
- Polling a GfxEvent for a window and having events on other windows would silently discard the last event.
- Setting no-border state during fullscreen on Win32 would not work properly.
- X11 window destruction order was incorrect.
- Win32 did not support sharing of OpenGL contexts.
- Win32 OpenGL pixel format selection ignored several hints.
- Added
FAILED_TO_CREATE_WGL_CONTEXTfor Win32 WGL format fails. - Win32 handle would leak on drag-and-drop when dnd was disabled.
- X11 mode change did not change the stored mode.
- X11 window name is now kept when recreating a window for opengl init.
- Doc viewer collision between modules and declarations sharing the same path. #3572
- Fixes to transparent mouse pointer.
- Compiler crashes when using a value derived from a const as an initializer elsewhere. #3574
- Improve OpenGL-handling of vsync.
- Regression for emscripten, accidentally retainin unused panic functions. #3575.
- Compiler hangs on c3c project fetch #3562
- Temp dirs were left behind by
c3c compile(including unpacked.c3llibraries),fetch-list,vendor-fetchand the SDK fetch commands, in particular after errors. #3553 - Fix integer overflow vulnerabilities in regex compiler (CVE-2026-107891). #3585
- Compiler crashes when emitting line-tables debug info. #3581
- Do not pass PIE/PIC on Windows. #3586
- Crashes in slice->vector and ptrvec->intvec conversions.
- Implicit cast rules too loose for slice->arrptr.
- Invalid lowering for
(Bitstruct)-1where the bitstruct is backed by an unsigned type. - Cast to
anyfrom typedef with an underlying inline pointer, would cause a crash. - Cast from constant
bool[<2>]tofloat[<2>]would crash. - Padding would be incorrectly lowered in things like
(char[<8>])(char[8])"abc". - Const casting a const slice derived from a zero array initializer (e.g.
(bool)(int[])(int[3]){}) would incorrectly return false. - Casting a constant to an alias to an enum would be incorrectly checked.
- Cast to aliased bitstruct would fail when non-aliased cast would succeed.
- Casting an optional distinct index would incorrectly fail.
- Aarch64 MacOS did not zero/sign-extend args (and Win32 Aarch64 incorrectly did). #3593
- Overaligned structs were not passed correctly on Linux Aarch64.
- Add alignstack for Linux Aarch64 ABI for correct HFA/HVA handling.
string::unescapeandstring::escapewould not work correctly after initial size was reached. #3592$definedon an untyped list that cannot be converted, e.g.$defined(int[*] y = $list)withvar $list = { 1, "a" };, would print an error instead of being false.- An empty constant string could not be converted to an array, e.g.
char[4] x = "";. - A constset inlining a constset that in turn inlines a third one, could not be implicitly converted to the one in the middle.
$definedon an implicit pointer conversion was true for pointers to distinct types, and printed an error instead of being false when the pointee alignment would increase.- Casting a
typeidorfaultto a wider signed integer, e.g.(int128)t, would sign extend instead of zero extend. - An implicit cast between unrelated distinct types would report the error twice.
- The hints in cast errors (for enums, distinct types,
ZStringand pointers to slices) were missing when the value was optional. - Casting between
float16andbfloat, also in vectors, would abort the compiler. An explicit cast now converts throughfloat. - Casting a constant float to an integer it does not fit, e.g.
(int)1e30,(char)300.5, infinity or NaN, would abort the compiler or give a wrong value. It is now an error, also for the elements of a constant float vector or array cast to an integer vector. - An inline distinct signed integer, or an inline constset of one, would implicitly convert to an unsigned integer of the same size, e.g.
uint y = my_inline_int;, whichinttouintdoes not allow. - Explicitly casting a pointer wrapped in an inline distinct type to
anyor an interface was an error, even though the implicit cast worked. - A struct implementing an interface through an alias, e.g.
struct Foo (IAlias), would not convert to the interface, and an interface inheriting through an alias would not convert to its parent. - Casting an enum to a distinct type over that enum, e.g.
(MyFoo)foowithtypedef MyFoo = Foo;, was an error. It is now allowed with an explicit cast, like for a distinct type over an integer. - Errors in multithreaded compilation tasks, such as a failing
c-sourcesfile, could crash the compiler. A failing task now aborts the remaining tasks and the compiler exits with an error. #3584 - Fix error message rethrowing in a non-function context.
- Fix name mangling of untyped list.
"max-vector-size"was not whitelisted as a project property.- In some cases, optional ref was extracted before it was created during LLVM IR codegen #3598.
- Bitstruct method did not check if field with the same name existed #3602.
- Casting a constant string (or constant bytes) to a vector at compile time would cause a crash. #3601
- Support unicode paths on Windows when running processes from the compiler. #3605
- Fixes to i128 compiler_rt.
- Using a const from another module that refers to a private symbol would fail to link in some cases e.g.
static List{int} g = list::ONHEAP{int};. - Reading an enum associated value at runtime from another module would fail to link if it referred to a private symbol.
- A function only used in an
@ensurecould be stripped when it wasn't the first statement to run on return, failing to link. - The sign of constant NaN expressions was ignored during codegen.
- Generic type inference fails with optional expected types #3612.
- Signed shift amounts narrower than the shifted value were zero extended affecting the panic message of an invalid shift amount.
- A function with
@test @benchmarkwould effectively never be included. - Incorrect compiler error using
from_ordinalwhen exceeding max. - Concatenated base64 literals lost decoded bytes after the first chunk.
- Improve accuracy of
logandlogfwithout a C library (wasm32, freestanding, or-D C3_MATH). - 16-byte align JmpBuf on Win32.
- Win64 returned
@simdvectors through a hidden pointer instead of XMM0. #3628 - Fix regression when slices or pointers exceed 2 GB. #3595
XmlSerializer.start_docwas missing the closing quote after the encoding.XmlSerializerescaped comments and processing instructions when serializing a document.gfx::get_vulkan_physical_device_presentation_supportwas broken.argon2::tencodetookkey_idas acharinstead of achar[].- The libc allocator was incorrectly declared in
std::core::mem::allocator. - Fixes to the
benchmarks.c3,map.c3andxml/3_xml_write_stream.c3examples. - A global slice of vectors, e.g.
int[<2>][] g = { { 1, 2 } };, would be lowered incorrectly. - Instantiating a generic with the type of an anonymous inner struct/union would crash the compiler. #3631
- Anonymous inner structs/unions of the same parent shared a name. They are now named by member index, e.g.
Foo.0. - Inner structs/unions of a generic struct lacked the generic parameters in their name.
- Fix Win32 compiler support for paths containing non-ASCII characters. #3606
- A constant struct containing a union initialized by a smaller member was emitted too small.
- Codegen for
%on float vectors was incorrect. /,%and>>on unsigned integer vectors used signed operations.- Assigning to
v[^i]on a vector with a non-constantiwrote the wrong element. - Assigning to a vector element or swizzle discarded would not evaluate right to left.
++and--on a multi-component swizzle, e.g.v.xy++, did not change the vector.- Comparing constant bitstructs could crash the compiler.
- Constant
!=on faults and on addresses of globals returned the result of==. a += eon an optionaladid not assign the fault whenewas a fault. It now works likea = a + e.- Constant folding of
int::min / -1was incorrect. return,break,continue,nextcaseand rethrow in a macro's trailing body were allowed when the macro invoked the body from adefer.
Stdlib changes
- Added termios support for OpenBSD.
- Add
file::open_fdto open files directly from file descriptors. - Changed regex fault and flag names, removed
NOSUB. #3585 - Added missing
__muloti4to compiler_rt. List.insert_atandList.push_frontnow use a singlememmoveinstead of an element-by-element shift.List.pushhas an inline fast path when there is spare capacity.List.remove_item,List.compact(and the same functions onFixedList) are now single pass instead of quadratic.- Cryptos now try to use funnel shift and rotation.
- Add
unorderedparameter toList.remove_firstand.remove_last - Added
matrix::perspective_infinite,matrix::perspective_reverse_zandmatrix::perspective_infinite_reverse_z. - Added
column,row,set_columnandset_rowtoMatrix2x2,Matrix3x3andMatrix4x4, andscale_factorstoMatrix3x3andMatrix4x4. math::signnow supports floats.- Add
chmodsupport #3536. std::hash::crc32now uses slicing-by-16, about 5x faster. This also speeds up gzip and zip.std::hash::adler32updateis about 3.5x faster (blocked modulo and portable vectors), results unchanged.- Rewrite
std::compression::deflateinflate: table driven decoder, 2-3x faster decompression; truncated input is now rejected andInflater.initworks with the defaultbit_reader_buf. - Add an optional
level(1-9) tostd::compression::deflatecompress,compress_streamandDeflater.init; the default level produces the same output as before. Faster deflate encoding, and incompressible data is stored instead of expanded. - Add an optional
leveltostd::compression::gzipcompress,compress_streamandGzipWriter.init(sets XFL per RFC 1952); the default is unchanged. - Add an optional
leveltostd::compression::zipZipArchive.open_writerandZipArchive.write_file(DEFLATE only); the default is unchanged. - Fix several
std::compression::zipproblems:openandrecoverclosed the file twice on errors,openfailed on ZIP64 archives with a comment or exactly 65535 entries, rejected data after the end record, and silently dropped entries after a broken central directory header.recovernow reads ZIP64 local headers,extractverifies the CRC32 and no longer overwrites the modification time,ZipEntryReader.seekrejects negative positions, and the central directory flags match the local header. - Added
XmlSerializer.add_rawto write unescaped text.