Conversation
e6514bb to
cfb32a3
Compare
184f0b6 to
1d7fedf
Compare
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.
1d7fedf to
af426a3
Compare
There was a problem hiding this comment.
🔵 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-listfiltering, 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.
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>
There was a problem hiding this comment.
🔵 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 anddastestwon't receive a valid--test-listpath. Quote the variable in the COMMAND arguments.
tests/aot/CMakeLists.txt:593file(WRITE ...)uses an unquoted output path. If${PROJECT_BINARY_DIR}(and thusLLVM_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>
There was a problem hiding this comment.
🔵 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_exstores the caller-providedlibGroupintostate->serializer->thisModuleGroupwithout 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) whenlibGroup == nullptrto make the API robust against misuse.
- Files reviewed: 246/246 changed files
- Comments generated: 0 new
- Review effort level: Lite
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 Sweepsarmed a rail that had never run in CI, and it reported 16 fileson linux, 14 on darwin, all
error[50101]. Three causes:linkCppAotskipped the hash pass for arequestNoJitfunction under LLVM-AOT, butgetFunctionAotHashstill folds that function in as a dependency, so every callerfolded a zero where the emitter folded the real hash. The diagnostic shows it as
test_r2v C1<S<testing::T>>?=0x0.[tune]stamp changes the semantic hash, and the-jit --use-aotrail consumesobjects the emitter built, so both sides must be stamp-free. The object emitter was
not, and baked its own
utils/internal/jit/main.tune.jsoninto the artifact.tests/while the corpus is partly curated lists(
AOT_DASLIB_FILES), which no--excludepattern can track. The run now restricts thewalk to the corpus through
dastest --test-list. It stays a walk, sotests/.das_teststill gates the folders this rail must not enter.
test_lattice_idot.dasaborted ondarwin26 with
Cannot select: AArch64ISD::SDOT. The MCJIT the C API builds has no cpuand 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-featuresattributes - the route the fat-mode clones already ride - so thesubtarget 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 --runand passes after; the whole rail is 12836 green locally,modules/dasLLVM/testsand the wasm / cross-target / neon JIT tests green, the emitter pin re-minted.
The asan lane
LLVMGetDefaultTargetTriplereturns a string the caller owns.emit_object_onlyleakedone per emitted object, which LeakSanitizer reports as a 32-file batch's worth of
strdupat 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 70KBthat 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_heapreported exactly 10248 KB against a 10240 KB ceiling on two consecutivenights. 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 Testsrunstest_concurrent_init, which drivesNEED_ALL_DEFAULT_MODULES+Module::Initialize+Shutdownfrom 128 threads, and ThreadSanitizer reported the twoplain-global writes every thread made:
register_fusion()storing the two fusion hooks, andshutdownInternal()storingg_deferredModuleLoader. The same four reports sit in the lastscheduled 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 onewrite), and the deferred loader is an atomic its accessors load and store.
test_concurrent_initpasses 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_jobresolves the PR's closing issues and labels into oneflag that drives the matrix shape, the nightly-only jobs and the nightly-only steps. The
issue-filing job still gates on
schedulealone, so an armed PR cannot file an issue atitself. This PR is the first user of it.