Skip to content

The nightly goes green: the LLVM-AOT rail links, the emitter stops leaking, and a PR that closes a nightly-failure issue runs the nightly - #4046

Open
aleksisch wants to merge 11 commits into
masterfrom
aleksisch/nightly-fail
Open

aleksisch wants to merge 11 commits into
masterfrom
aleksisch/nightly-fail

Conversation

@aleksisch

@aleksisch aleksisch commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Fixes #4032

The nightly was red on four independent causes, not one. Each is reproduced and fixed
here; the LLVM-AOT rail is verified end to end on this branch's tip.

The LLVM-AOT rail (run_tests_llvm_aot, every Release lane)

Nightly Backend Sweeps armed a rail that had never run in CI, and it reported 16 files
on linux, 14 on darwin, all error[50101]. Three causes:

  • linkCppAot skipped the hash pass for a requestNoJit function under LLVM-AOT, but
    getFunctionAotHash still folds that function in as a dependency, so every caller
    folded a zero where the emitter folded the real hash. The diagnostic shows it as
    test_r2v C1<S<testing::T>>?=0x0.
  • A [tune] stamp changes the semantic hash, and the -jit --use-aot rail consumes
    objects the emitter built, so both sides must be stamp-free. The object emitter was
    not, and baked its own utils/internal/jit/main.tune.json into the artifact.
  • The run walked all of tests/ while the corpus is partly curated lists
    (AOT_DASLIB_FILES), which no --exclude pattern can track. The run now restricts the
    walk to the corpus through dastest --test-list. It stays a walk, so tests/.das_test
    still gates the folders this rail must not enter.
  • Armed on every Release lane, the rail found a fourth: test_lattice_idot.das aborted on
    darwin26 with Cannot select: AArch64ISD::SDOT. The MCJIT the C API builds has no cpu
    and no feature string, so its subtarget is the generic one, while the emitter's gates
    read the host and lowered the idot family to SDOT. Every defined function of an
    in-memory module now carries the host cpu and feature string as target-cpu /
    target-features attributes - the route the fat-mode clones already ride - so the
    subtarget a function is selected under matches the gates that emitted it. Reproduced
    and verified on an M5: the test aborted three of three runs under test_llvm_aot -jit --run and passes after; the whole rail is 12836 green locally, modules/dasLLVM/tests
    and the wasm / cross-target / neon JIT tests green, the emitter pin re-minted.

The asan lane

LLVMGetDefaultTargetTriple returns a string the caller owns. emit_object_only leaked
one per emitted object, which LeakSanitizer reports as a 32-file batch's worth of strdup
at once. A second site leaked one per module under debug info.

The windows Release lane

Both standalone-sweep tiers passed ~900 absolute paths as one -DFILES= argument. At 70KB
that overruns cmd.exe's 8191-character line limit whatever wrapper script the generator
writes, so the lane died on a truncated path with 'D:' is not recognized as an internal or external command. The list travels in a file now.

The windows RelWithDebInfo lane

test_worker_heap reported exactly 10248 KB against a 10240 KB ceiling on two consecutive
nights. That lane tracks allocations with the free list off, so it never reuses a freed
chunk and its high-water between collects is wider than any lane the ceiling was measured
on. An uncollected bed still clears twenty megabytes, so the signal survives the new one.

The tsan lane

Slow Release Tests runs test_concurrent_init, which drives NEED_ALL_DEFAULT_MODULES +
Module::Initialize + Shutdown from 128 threads, and ThreadSanitizer reported the two
plain-global writes every thread made: register_fusion() storing the two fusion hooks, and
shutdownInternal() storing g_deferredModuleLoader. The same four reports sit in the last
scheduled nightly's tsan lane, so this is a fifth pre-existing cause, not one of the four above.
The hooks are set under a once_flag (which also orders every later reader after the one
write), and the deferred loader is an atomic its accessors load and store. test_concurrent_init
passes 10 rounds locally; the tsan lane on this tip is the proof.

A PR that closes a nightly-failure issue runs the nightly

Per-PR CI never walks the lanes the nightly owns, so a fix for a red nightly had no way to
prove itself before landing. pre_job resolves the PR's closing issues and labels into one
flag that drives the matrix shape, the nightly-only jobs and the nightly-only steps. The
issue-filing job still gates on schedule alone, so an armed PR cannot file an issue at
itself. This PR is the first user of it.

@aleksisch
aleksisch force-pushed the aleksisch/nightly-fail branch 6 times, most recently from e6514bb to cfb32a3 Compare September 16, 2026 18:33
@aleksisch
aleksisch requested a review from borisbat September 16, 2026 18:43
@aleksisch
aleksisch force-pushed the aleksisch/nightly-fail branch 5 times, most recently from 184f0b6 to 1d7fedf Compare September 16, 2026 22:10
linkCppAot skipped the hash pass for a requestNoJit function under LLVM-AOT, but
getFunctionAotHash folds every non-noAot dependency into a caller's hash whether or not
the rail can bind it. The skipped function kept hash 0, so every caller folded a zero
where the object emitter folded the real value and missed its own entry - the diagnostic
prints it as `test_r2v C1<S<testing::T>>?=0x0`. Hash the whole non-noAot set; the
requestNoJit skip belongs to the binding loop, which still has it.

C++ AOT is unaffected by construction: isLlvmAot is false there, so the old condition
already read `!noAot`. Only the LLVM-AOT path changes, and only a program that reaches a
no_jit function through a bound caller.
A [tune] stamp rewrites the function before codegen, so it changes the semantic hash.
tune_aot_gate froze only an AOT run without the JIT, which left the -jit --use-aot rail
stamping at run time against objects built under other assumptions. The gate is
policies.aot now: a run that consumes AOT artifacts is frozen, whichever backend binds
them. A plain -jit run sets no aot policy and still stamps, and -exe still stamps through
tune_exe_gate.

The object emitter freezes for the reason every other AOT generator does - the artifact
is cross-box. utils/internal/jit/main.das is the driver the cmake rules invoke, and it
was the one sibling that never set tune_frozen, so it baked its own sidecar path into
the emitted objects.
LLVMGetDefaultTargetTriple returns a string the caller owns. emit_object_only leaked one
per emitted object, and the debug-flag path leaked one per module, which LeakSanitizer
reports as a batch's worth of strdup at once on the asan lane.

llvm_jit_common.das is in the pinned emitter set, so the pin moves with it. The disposal
frees a string LLVMSetTarget has already copied, so emitted code is unchanged and
LLVM_JIT_CODEGEN_VERSION holds.
Two rules handed a whole corpus to a tool as one argument. The standalone sweep passed
~900 absolute paths as -DFILES=, which at 70KB overruns cmd.exe's 8191-character line
limit whatever wrapper script the generator writes, so the windows lane died on a
truncated path. run_tests_llvm_aot spelled the corpus a second time as --exclude
patterns, which cannot track TEST_AOT_ALL_DAS because that is partly curated lists
(AOT_DASLIB_FILES) - a file the corpus lacks has no object, and reaching it under
--use-aot is a hard error.

Both now write the list at configure time and name the file. dastest gains --test-list,
which restricts the collected set rather than replacing it, so --test still walks tests/
and tests/.das_test still gates the folders this rail must not enter.
Per-PR CI never walks the lanes the nightly owns - the sanitizer cells, windows Debug,
mingw, clang-cl, the full AOT suite, the backend sweeps - so a change that can break one
has no way to prove itself before it lands. pre_job resolves the PR's closing issues, its
labels and a `#nightly` marker in its body into one flag that drives the matrix shape,
the nightly-only jobs and the nightly-only steps. The body is read through the API and
matched with jq, never interpolated into the shell: a PR body is attacker-controlled.

The issue-filing job still gates on schedule alone, so an armed PR cannot file an issue
at itself. make_pr's checklist says when to arm by hand.
Four emitters wrapped a whole statement in `unsafe { }` where one or two operations
inside it needed the permission. The wrap now goes on each addr/reinterpret the emitter
writes, and the block is gone: the finalize destroyer, the opt_struct_ptr field view, the
batch allocate call and the out-array enumerate call.

The generated files are DO NOT EDIT, so narrowing them by hand would have survived only
until the next regeneration - and nightly_vulkan.yml diffs the two ratchet reports, never
the generated .das, so nothing would have caught the loss. Regenerating is deterministic
and leaves skip_report.txt and copyability_report.txt byte-identical.
STYLE024 and STYLE025 went blind on the tool path until the unsafe-scope rules were
repaired, so the tree carries wraps around bodies that need no permission and blocks
broader than the one operation inside them. A redundant wrap goes and the body dedents; a
broad one collapses onto the operation the compiler names - addr, reinterpret, pointer
index, pointer arithmetic, an unsafe builtin - which is the only way to find it, since
the finding says a narrowing is possible without saying of what. An assignment takes
`lhs = unsafe(rhs)`, a pointer index on the left takes `unsafe(p[i]) = v`, and a call
with a block wraps whole, closing brace included.

The rules stop reporting wraps the compiler requires. A declaration owns its permission -
a stack class local, a smart_ptr local without inscope, a local of a non-local type - and
`unsafe()` is an expression form with nothing to wrap: `let d = unsafe(Derived())` still
reports error[31017] on `d`. A delete lowers to builtin`finalize_dim` as well as
builtin`finalize`, and whether it needs the wrap is TypeDecl::isSafeToDelete, now bound so
this side can read it. A module `with` survives infer under the lint's own policies, so it
marks when the file carries with_module_is_unsafe.

Reading isSafeToDelete also stops a safe delete from counting as the reason for its wrap,
which uncovered redundant wraps the unconditional marking had hidden - six in
tests/language/smart_ptr.das and one in the STYLE024 fixture, whose expectation moves from
5 to 6 because it was pinning the over-marking rather than the rule.

One site keeps a nolint: `_fold` rewrites its chain and erases the `each` whose
unsafeOutsideOfFor required the wrap, leaving nothing in the tree to mark.

llvm_jit.das, llvm_macro.das and llvm_jit_link.das are in the pinned emitter set, so the
pin moves with them. An unsafe wrapper is a compile-time permission scope the fold removes
before codegen, so emitted code is unchanged and LLVM_JIT_CODEGEN_VERSION holds.
deserialize_program reached finalizeAnnotations with thisModuleGroup unset, so
ast_annotations.cpp bound `*program->thisModuleGroup` from a null pointer - undefined the
moment the reference forms, which the UBSAN lane reports against the rtti round-trip test.
Nothing crashed because no finalize body reads the group; the adapter hands it to a
[function_macro]'s finish, and none of the fixtures has one.

The group could not be supplied at all: the header says it is passed from top-level, the
compile path passes it, and the das API had no parameter for it. dastest already knew -
it opens a ModuleGroup around its --deser loop and had to name it `_mg`, unused, because
there was nowhere to put it. So the parameter is the fix rather than a stand-in group: an
empty one would let a finish see empty user data instead of the caller's, trading a
sanitizer finding for a silent wrong answer.

Both overloads take it after access, the way compile_file does, and both in-tree callers
pass the group they already had.
The fastmath lane builds the whole tree -ffast-math, and three tests assert guarantees that
flag trades away: nan compare semantics, the sign of zero, and a division that stays finite
across an inf. All three pass interpreted and fail under --use-aot, because the interpreter
compares at run time while AOT emits daslang's const-folded inf and nan as literals for a
C++ compiler that has been told neither exists.

inf_and_nan already meant to skip such a host, but its probe compares values laundered
through opaque(), which nothing folds - so the probe answers "this host is fine" while the
asserts beside it are folded away. HOST_FAST_MATH is the exact answer and the tree's
existing one; the probe stays for a host that passes only -ffinite-math-only.

test_builder keys a spirv constant by bits and wants 0.0 and -0.0 to be two ids, which
-fno-signed-zeros makes one value. fast_math_specials pins that a silu stays NaN-free -
the JIT stamp is narrowed to reassoc|nsz|contract for exactly that reason, but a tree built
-ffast-math hands the C++ tier the rcp-estimate lowering anyway, and the sweep comes back
with 1104 NaNs. That guarantee is the host's to keep once it has asked for the flag.

On every other host the three still run; nothing is skipped.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It spans core runtime/serialization, LLVM emitter behavior, CMake/CI infrastructure, and a very large mechanical refactor surface, so it needs final human verification across platforms and lanes.

Pull request overview

This PR addresses multiple independent nightly CI failures and adds an opt-in mechanism for PRs that fix nightly breakages to run the nightly-shaped CI matrix, improving confidence before merge.

Changes:

  • Fix LLVM-AOT rail correctness (semantic hash / dependency hashing) and reduce platform-specific flakes by skipping fast-math–sensitive tests when the host runtime is built with fast-math.
  • Fix sanitizer-reported leaks in the LLVM emitter path by correctly disposing LLVM-owned strings.
  • Improve CI/test infrastructure: add dastest --test-list filtering, avoid Windows cmdline length limits by switching large -D... argument payloads to file-based lists, and update nightly issue guidance/arming.
File summaries
File Description
utils/mcp/tools/outline.das Narrows unsafe usage around popen and sorting.
utils/mcp/tools/grep_usage.das Narrows unsafe usage and removes redundant unsafe blocks.
utils/mcp/protocol_core.das Narrows unsafe to expression form for shutdown exit.
utils/mcp/mcp_core.das Narrows unsafe to expression form for heap collection.
utils/lint/tests/style025_unsafe_block_narrow.das Adds fixture coverage for cases where unsafe {} block form is required.
utils/lint/tests/style024_redundant_unsafe.das Updates STYLE024 fixtures/expectations and adds more regression coverage.
utils/jobque-timeline/tl_loader.das Removes redundant unsafe around string construction.
utils/jobque-timeline/tl_launch.das Narrows/removes redundant unsafe in argv splitting and channel cleanup.
utils/internal/jit/main.das Freezes tune stamping for AOT-object emission mode.
utils/daspkg/test_daspkg.das Narrows unsafe to expression form in test.
utils/daspkg/index.das Narrows unsafe to expression form in index formatting paths.
utils/dasllama-server/model_catalog.das Narrows unsafe for channel removal on shutdown.
utils/das-fmt/dasfmt.das Narrows unsafe around fio::exit calls.
utils/dap/dap_bridge.das Narrows unsafe to individual buffer reads.
utils/benchctl/utils.das Narrows unsafe around popen usage.
tutorials/macros/structure_macro_mod.das Narrows unsafe to reinterpret expression form.
tutorials/language/45_debug_agents.das Removes redundant unsafe blocks; narrows unsafe around pointer/address ops.
tutorials/language/44_helper.das Removes redundant unsafe around typed pointer writes.
tutorials/language/44_compile_and_run.das Narrows unsafe around invoke_in_context calls.
tutorials/dasPUGIXML/05_linq_over_xml.das Removes redundant unsafe around _fold examples.
tests/type_traits/test_iterator_variance.das Narrows unsafe to iterator-producing call.
tests/table_packed/test_packed_large.das Removes redundant unsafe around container deletes.
tests/table_packed/test_packed_constkey.das Removes redundant unsafe around container deletes.
tests/strings/delete_strings.das Narrows unsafe to delete_string expressions; removes redundant block.
tests/stbimage/test_apng.das Narrows unsafe around raw pointer address passing to stb functions.
tests/standalone-sweep/sweep_jit.cmake Switches from -DFILES= payload to -DFILES_LIST= file input to avoid cmdline limits.
tests/standalone-sweep/sweep_contexts.cmake Reads file-list input for contexts collection (see stored comment re: validation).
tests/standalone-sweep/CMakeLists.txt Writes sweep file list to disk and updates sweep commands to pass FILES_LIST.
tests/spirv/test_builder.das Skips bitkey test on fast-math hosts to avoid false failures.
tests/network/test_client.das Narrows unsafe to individual buffer reads.
tests/module_tests/test_modules.das Narrows unsafe around invoke_in_context.
tests/module_cache/test_rtti_serializer.das Updates deserialize call to pass ModuleGroup for correct annotation finalization.
tests/mcp/test_mcp_jsonrpc.das Narrows unsafe around popen_argv_pipe.
tests/math/mat_let_handle.das Narrows unsafe to addr expression form.
tests/math/inf_and_nan.das Skips nan-compare tests on fast-math hosts and updates skip message.
tests/match/all_matches.das Narrows unsafe to reinterpret expression form.
tests/long_array_table/test_long_iterators.das Narrows unsafe to iterator source.
tests/long_array_table/test_huge_temp_array.das Narrows unsafe to temp_array expression.
tests/long_array_table/test_huge_array_iterate.das Narrows unsafe to iterator source.
tests/long_array_table/test_dim_int64_indexing.das Removes redundant unsafe around safe-index reads.
tests/linq/test_linq_table_source.das Removes redundant unsafe around _fold chains.
tests/linq/test_linq_from_decs.das Removes redundant unsafe around _fold chains.
tests/linq/test_linq_fold_theme6_decs_bridge_warn.das Removes redundant unsafe around _fold chain; keeps assertions.
tests/linq/test_linq_fold_theme6_decs_bridge_warn_silenced.das Removes redundant unsafe around _fold chain; keeps assertions.
tests/language/variant.das Narrows unsafe around variant index changes / unsafe field reads.
tests/language/tuple.das Narrows unsafe to addr expression.
tests/language/to_array.das Narrows unsafe to iterator source.
tests/language/test_rtti_init_mnh.das Removes redundant unsafe around typeinfo reads.
tests/language/string_ops.das Narrows unsafe to delete_string call.
tests/language/smart_ptr.das Removes redundant unsafe around deletes.
tests/language/serialization.das Removes redundant unsafe block around pure-DAS serialization flow.
tests/language/properties.das Narrows unsafe to reinterpret expressions and avoids uninitialized string var.
tests/language/optimization_inline_unsafe.das Narrows unsafe to addr expression; removes redundant block.
tests/language/optimization_auto_inline_functions.das Narrows unsafe to reinterpret expression.
tests/language/offset_pointer_write_through_helper.das Removes redundant unsafe wrapper around safe helper call.
tests/language/new_delete.das Narrows unsafe to delete_string expressions.
tests/language/lock_array.das Narrows unsafe to element access lvalues/rvalues.
tests/language/each_ref.das Narrows unsafe to addr expression.
tests/language/container_init_off.das Removes redundant unsafe around container deletes.
tests/language/container_finalize.das Removes redundant unsafe around container deletes.
tests/language/cast.das Narrows unsafe to reinterpret expression.
tests/language/annotation_info.das Removes redundant unsafe around pure AST/RTTI iteration.
tests/language/addr_cast_sugar.das Narrows unsafe to pointer arithmetic and removes redundant unsafe blocks.
tests/jsonrpc/test_request_ownership.das Removes redundant unsafe around container delete.
tests/jobque/test_jobque_tracking.das Narrows unsafe to removal calls; removes redundant blocks.
tests/jobque/test_jobque_jobs.das Narrows unsafe to addr and removal expressions.
tests/jit/fast_math_specials.das Skips test on fast-math hosts; clarifies rationale.
tests/jit_tests/variant.das Narrows unsafe to set_variant_index expression.
tests/jit_tests/trap_block_ann.das Narrows unsafe around popen expression.
tests/jit_tests/pointer.das Narrows unsafe around pointer index ops; keeps required unsafe block for ++ a.
tests/jit_tests/new_ascend_and_delete.das Removes redundant unsafe around deletes.
tests/jit_tests/memset.das Narrows unsafe to intrinsic calls.
tests/jit_tests/llvm_split_modules.das Narrows unsafe around popen_timeout usage.
tests/jit_tests/llvm_compile_only.das Narrows unsafe around popen_timeout usage.
tests/jit_tests/jit_lib.das Narrows unsafe around popen_timeout usage.
tests/jit_tests/jit_exe.das Narrows unsafe around popen usage.
tests/jit_tests/exe_host_cpu.das Narrows unsafe around popen_timeout usage.
tests/jit_tests/cross_target_folds.das Narrows unsafe around popen_timeout usage.
tests/jit_tests/aarch64_neon.das Narrows unsafe to pointer reads.
tests/gc/test_gc_deep_recursion.das Narrows unsafe to heap_collect expression form.
tests/gc/test_gc_coverage.das Narrows unsafe to heap_collect expression form.
tests/gc/lattice_escape_tests.das Narrows unsafe to addr expression form.
tests/gc/gc_typedecl.das Narrows unsafe around invoke_in_context.
tests/fixed_array/test_layout.das Narrows unsafe to field/array access.
tests/fio/fio_prefetch.das Narrows unsafe around prefetch call.
tests/fio/fio_fmap_rw.das Narrows unsafe to raw pointer writes and close call.
tests/fio/fio_exit_now.das Narrows unsafe to exit_now expression.
tests/fio/fio_dwrite.das Narrows unsafe to raw pointer writes in loops.
tests/decs/test_gc.das Narrows unsafe to heap_collect expression form.
tests/debug_agent/test_threadlock.das Removes redundant unsafe around pointer writes; narrows unsafe calls.
tests/debug_agent/test_state_collection.das Removes redundant unsafe around pointer writes; narrows invoke calls.
tests/debug_agent/test_on_log.das Removes redundant unsafe around pointer writes; narrows invoke calls.
tests/debug_agent/test_lifecycle.das Narrows unsafe around invoke call.
tests/debug_agent/test_invoke_method.das Removes redundant unsafe around pointer writes; narrows invoke calls.
tests/debug_agent/test_invoke_in_context.das Removes redundant unsafe around pointer writes; narrows invoke calls.
tests/debug_agent/test_callback_threadlock.das Narrows unsafe around invoke_in_context call.
tests/data_walker/test_walk_tuples_variants.das Narrows unsafe to addr expressions for walker API calls.
tests/data_walker/test_walk_mutation.das Narrows unsafe to addr expressions for walker API calls.
tests/data_walker/test_walk_lattice.das Narrows unsafe to addr expressions for walker API calls.
tests/dasPUGIXML/test_serial_variant.das Narrows unsafe to variant field writes.
tests/dasPUGIXML/test_serial_table.das Narrows unsafe around potentially-unsafe table indexing in test.
tests/CMakeLists.txt Updates LLVM-AOT test runner to use curated --test-list instead of directory-wide walk.
tests/bool_array/test_bool_array_iterator_crash.das Removes redundant unsafe around logging.
tests/ast/test_any_long_size.das Narrows unsafe to addr expressions.
tests/aot/test_int64_ptr_index.das Narrows unsafe to indexed pointer write lvalue.
tests/aot/CMakeLists.txt Generates LLVM-AOT corpus file (llvm_aot_corpus.txt) for --test-list.
src/builtin/module_builtin_rtti.cpp Updates RTTI binding arg names to include libGroup for deserialize API.
src/builtin/module_builtin_ast_serialize.cpp Threads ModuleGroup* through deserialize to finalize annotations correctly.
src/builtin/module_builtin_ast_annotations_1.cpp Exposes TypeDecl.isSafeToDelete property via RTTI.
src/ast/ast_simulate.cpp Ensures hash pass runs for LLVM-AOT dependency consistency.
skills/internal/make_pr.md Documents #nightly / run-nightly arming guidance for PR CI.
skills/daslang/references/everything.md Updates docs for deserialize_program behavior and adds TypeDecl.isSafeToDelete.
modules/dasVulkan/tutorials/recording/tutorial_record.das Narrows unsafe to stb APNG call argument.
modules/dasVulkan/tutorials/14_teapot/teapot_tut.das Removes redundant unsafe blocks around deletes.
modules/dasVulkan/tutorials/09_msaa/msaa_tut.das Removes redundant unsafe blocks around deletes.
modules/dasVulkan/tutorials/08_shadow/shadow_tut.das Removes redundant unsafe blocks around deletes.
modules/dasVulkan/tutorials/07_particles/particles_tut.das Removes redundant unsafe blocks; narrows unsafe around Vulkan API pointer args.
modules/dasVulkan/tutorials/06_skybox/skybox_tut.das Removes redundant unsafe blocks around deletes.
modules/dasVulkan/tutorials/05_instancing/instancing_tut.das Removes redundant unsafe blocks around deletes.
modules/dasVulkan/tutorials/04_cube/cube_tut.das Removes redundant unsafe blocks around deletes.
modules/dasVulkan/tutorials/03_sdf/window/resident_compute.das Removes redundant unsafe around deleting weak-copy set-layout array.
modules/dasVulkan/tutorials/03_sdf/sdf_tut.das Removes redundant unsafe; narrows unsafe for Vulkan API pointer args.
modules/dasVulkan/tutorials/02_mandelbrot/window/mandelbrot_compute.das Removes redundant unsafe around deleting weak-copy set-layout array.
modules/dasVulkan/tests/integration/test_ubo_nested.das Narrows unsafe to addr expression passed to Vulkan.
modules/dasVulkan/tests/integration/test_os_video_memory.das Narrows unsafe to addr expression in pNext chain.
modules/dasVulkan/tests/integration/test_opt_ptr_view_semantics.das Narrows unsafe to addr expression for optional pointer field.
modules/dasVulkan/tests/integration/test_nonuniform_ext.das Narrows unsafe to addr expression passed to Vulkan.
modules/dasVulkan/tests/integration/test_compute_shared.das Narrows unsafe to pointer-arg expressions and removes redundant blocks.
modules/dasVulkan/tests/integration/test_compute_features.das Narrows unsafe to pointer-arg expression.
modules/dasVulkan/tests/integration/test_bindless_descriptor_array.das Narrows unsafe to addr expression passed to Vulkan.
modules/dasVulkan/examples/smoke.das Narrows unsafe to Vulkan pointer args.
modules/dasVulkan/examples/enumerate.das Narrows unsafe to Vulkan pointer args.
modules/dasVulkan/examples/device_probe.das Narrows unsafe to Vulkan pointer args; keeps example behavior.
modules/dasVulkan/daslib/vulkan_runtime.das Removes redundant unsafe around typed pointer write.
modules/dasVulkan/daslib/vulkan_reflect.das Removes redundant unsafe around delete of temporary arrays.
modules/dasVulkan/daslib/vulkan_gltf.das Removes redundant unsafe around deletes.
modules/dasVulkan/daslib/vulkan_assets.das Removes redundant unsafe around deletes; narrows unsafe for Vulkan pointer args.
modules/dasTerminal/tests/ownership_semantics.das Narrows unsafe to heap_collect expression form.
modules/dasTerminal/tests/app_compat.das Removes redundant unsafe blocks in test driver logic.
modules/dasTerminal/daslib/terminal.das Removes redundant unsafe around safe container resize.
modules/dasPEG/peg/parser_generator.das Removes redundant unsafe block around safe variant overwrite in matched arm.
modules/dasOpenGL/opengl/opengl_ttf.das Narrows unsafe to pointer-arg expressions for OpenGL/stbtt calls.
modules/dasOpenGL/opengl/opengl_boost.das Narrows unsafe to pointer-arg expressions and reinterpret.
modules/dasLLVM/tests/test_tuned.das Narrows unsafe around popen_timeout capture.
modules/dasLLVM/tests/llvm_tune_scope.das Narrows unsafe; removes redundant unsafe block around JSON mutation.
modules/dasLLVM/tests/llvm_tune_profiles.das Narrows unsafe around popen_timeout.
modules/dasLLVM/tests/llvm_tune_modes.das Narrows unsafe around popen_timeout.
modules/dasLLVM/tests/llvm_tune_fat.das Narrows unsafe around popen_timeout.
modules/dasLLVM/tests/llvm_jit_baseline.das Narrows unsafe around popen_timeout.
modules/dasLLVM/daslib/llvm_macro.das Removes redundant unsafe around run_jit result write.
modules/dasLLVM/daslib/llvm_jit.das Removes redundant unsafe and simplifies annotation list construction.
modules/dasLLVM/daslib/llvm_jit_run.das Fixes LLVM-owned triple string leak by disposing when owned.
modules/dasLLVM/daslib/llvm_jit_link.das Narrows unsafe around invoke_in_context.
modules/dasLLVM/daslib/llvm_jit_common.das Fixes LLVM-owned triple leak in object emission by disposing message.
modules/dasLLAMA/tests/test_tune_interrupt.das Narrows unsafe around popen capture.
modules/dasLLAMA/tests/test_tts_blocks.das Narrows unsafe to pointer-arg expressions.
modules/dasLLAMA/tests/test_tower_helpers.das Narrows unsafe to addr expressions.
modules/dasLLAMA/tests/test_tower_asr_kernels.das Narrows unsafe to addr expressions.
modules/dasLLAMA/tests/test_repack.das Narrows unsafe to addr expressions; removes redundant unsafe block.
modules/dasLLAMA/tests/test_repack_lane_context.das Narrows unsafe to lvalue write through pointer.
modules/dasLLAMA/tests/test_deltanet.das Narrows unsafe to addr expression used for intptr conversion.
modules/dasLLAMA/REVIEW.das Updates image-layout stamp hash after functional changes.
modules/dasLLAMA/performance/coopmat_mulmm_reference.das Narrows unsafe to Vulkan pointer args.
modules/dasLLAMA/performance/coopmat_mulmm_port.das Narrows unsafe to Vulkan pointer args.
modules/dasLLAMA/performance/box_ident.das Narrows unsafe around popen capture.
modules/dasLLAMA/harness/dasllama_tuner.das Narrows unsafe around popen_timeout and preserves output streaming.
modules/dasLLAMA/harness/batch_rows_probe.das Narrows unsafe to addr expressions.
modules/dasLLAMA/dasllama/dasllama_whisper.das Narrows unsafe to addr expressions; removes redundant unsafe block.
modules/dasLLAMA/dasllama/dasllama_tts_blocks.das Narrows unsafe in temp-array forget and pointer arithmetic call sites.
modules/dasLLAMA/dasllama/dasllama_rope.das Narrows unsafe to pointer indexing expression.
modules/dasLLAMA/dasllama/dasllama_pocket.das Narrows unsafe around scratch resize call.
modules/dasLLAMA/dasllama/dasllama_mtp_gemma.das Narrows unsafe to Vulkan/ptr-arg expressions.
modules/dasLLAMA/dasllama/dasllama_moe.das Removes redundant unsafe around GPU tail call; narrows pointer arg.
modules/dasLLAMA/dasllama/dasllama_load.das Narrows unsafe to addr expression passed to append callback.
modules/dasLLAMA/dasllama/dasllama_kv_codec.das Narrows unsafe to pointer arithmetic expressions.
modules/dasLLAMA/dasllama/dasllama_image.das Narrows unsafe to raw memory ops and temp_array construction.
modules/dasLLAMA/dasllama/dasllama_common.das Removes redundant unsafe around deleting a table.
modules/dasLLAMA/dasllama/dasllama_batch.das Narrows/removes redundant unsafe blocks in batch decode path.
modules/dasLLAMA/benchmarks/setup_lcpp_ref.das Narrows unsafe around popen capture helper.
modules/dasHV/example/telnet.das Narrows unsafe to message buffer reads/sends.
modules/dasGlsl/glsl/glsl_internal.das Narrows/removes redundant unsafe around addr and reinterpret usage.
include/daScript/ast/ast_serializer.h Updates public RTTI deserialize signatures to include ModuleGroup* libGroup.
examples/vulkan/one_source_path_tracer/pt_reference.das Narrows unsafe to addr expressions passed to stb write.
examples/pathTracer/toy_path_tracer.das Narrows unsafe to addr expression passed to stb write.
examples/pathTracer/toy_path_tracer_profile.das Narrows unsafe to addr expression passed to stb write; keeps logging outside unsafe.
examples/debugapi/stack_walker.das Narrows unsafe to addr expression for RTTI printing.
examples/debugapi/hw_breakpoint.das Narrows/removes redundant unsafe blocks around breakpoint calls.
examples/debugapi/allocation_tracking.das Narrows unsafe around cross-context invocation.
doc/source/stdlib/handmade/function-rtti-deserialize_program-0x6822cf0d160c8c65.rst Updates handmade stdlib docs for deserialize_program with libGroup semantics.
doc/source/stdlib/handmade/function-rtti-deserialize_program-0x15d628ec5a8ce8da.rst Removes outdated handmade doc variant.
doc/source/stdlib/handmade/function-ast-_dot__rq_isSafeToDelete-0x39575a71bd440d4d.rst Adds handmade docs for new TypeDecl.isSafeToDelete.
doc/source/reference/language/lint.rst Extends STYLE025 documentation for cases where narrowing is impossible.
dastest/dastest_clargs.das Adds --test-list CLI argument.
.github/workflows/nightly_issue.yml Updates nightly issue body text to describe how to run nightly CI from a PR.
Review details
  • Files reviewed: 243/243 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/standalone-sweep/sweep_contexts.cmake
The MCJIT the C API builds has no cpu and no feature string, so its subtarget is the
generic one, while the emitter's gates read the host: on an aarch64 part with DotProd the
idot family lowered to SDOT and instruction selection aborted with `Cannot select:
AArch64ISD::SDOT` (tests/type_lattice/test_lattice_idot.das under test_llvm_aot, the rail
this branch arms on every Release lane; a static daslang build always ends on this engine).
The host cpu and feature string the DLL and exe rails build their machine from now land on
every defined function of an in-memory module as target-cpu / target-features attributes,
the route the fat-mode clones already ride, so the subtarget the function is selected under
matches the gates that emitted it. host_machine_cpu_features carries the one host string
both places read. The emitter pin follows the edit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It touches core LLVM/JIT/AOT behavior, CI matrix shaping, and wide swaths of tests/tutorials, so it warrants final human review even after the requested fixes.

Review details

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

tests/CMakeLists.txt:140

  • --test-list ${LLVM_AOT_TEST_LIST} is unquoted. If the build directory path contains spaces, this will be passed as multiple argv entries and dastest won't receive a valid --test-list path. Quote the variable in the COMMAND arguments.
    tests/aot/CMakeLists.txt:593
  • file(WRITE ...) uses an unquoted output path. If ${PROJECT_BINARY_DIR} (and thus LLVM_AOT_TEST_LIST) contains spaces, CMake will split the argument and the configure step will fail or write to the wrong location. Quote the path argument to make this robust.
    tests/standalone-sweep/CMakeLists.txt:62
  • -DFILES_LIST=${_sweep_files_list} is passed without quoting. If the build directory contains spaces, CMake will split the argument and the script will fail to locate the list file. Quote the -D...= values (and the existing -DOUT=... while here for the same reason).
  • Files reviewed: 244/244 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

…ead atomically

tests-cpp/big/concurrent_init drives NEED_ALL_DEFAULT_MODULES + Module::Initialize +
Shutdown from 128 threads, and the tsan lane reported what it found: every thread's
register_fusion() wrote g_fusionContextFn and g_resetFusionEngineFn, and every thread's
shutdownInternal() wrote g_deferredModuleLoader - plain globals, no ordering. The hooks are
now set under a once_flag, which also orders every later reader after the one write; the
deferred loader is an atomic the accessors load and store. The nightly's tsan lane was red on
this before the branch and is the fifth cause the branch closes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It touches core runtime/compiler behavior, LLVM/JIT/AOT infrastructure, CI/workflows, and a very large surface of tests/modules, so it warrants final human verification despite targeted fixes.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/builtin/module_builtin_ast_serialize.cpp:4057

  • rtti_ast_serializer_deserialize_program_ex stores the caller-provided libGroup into state->serializer->thisModuleGroup without validating it. If a caller passes null, later annotation finalization dereferences *program->thisModuleGroup (e.g. src/ast/ast_annotations.cpp:32), which can crash the process. Consider failing fast (invoke the block with ok=false and an error string) when libGroup == nullptr to make the API robust against misuse.
  • Files reviewed: 246/246 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The nightly is red

3 participants