Repository navigation
fix(specs): bound simulation and layout loops to their arrays - #411
dmitrii-f-t27 wants to merge 2 commits into
Conversation
Ten generated Rust modules did not compile under rustc 1.96 with -D warnings, although the drift check passed, because the drift check only compares text with the pinned t27c output. Spec changes, regenerated with the unchanged pin eb8b4208: - Nine specs assigned to value parameters (E0384, E0594). Each such function now copies the parameter into a local `var` and writes the copy. This is the value semantics that the generated C (struct by value) and Zig (shadow) already had, so no result changes. - api_documenter: the array repeat count is a literal, because the pinned Rust emitter copies a u32 count verbatim (E0308). - auto_config: drop five `value >= 0` tests on u32 (unused_comparisons). - integration_framework: rename type_documentation to TYPE_DOCUMENTATION (non_upper_case_globals). Public argument and return types are unchanged. Typecheck warning counts are unchanged for all ten specs. tests/gen_rust_corpus_compiles.rs compiles every gen/rust module as its own crate with -D warnings, enforces a floor of 102 modules, and first proves that five negative controls (E0384, E0594, E0308, unused_comparisons, non_upper_case_globals) are rejected. tests/gen_rust_value_params.rs checks results and the caller contract of the changed functions. Closes gHashTag#399
Four generated functions indexed past a fixed-size array or divided by zero for out-of-range inputs, so the generated Rust panicked, the C read out of bounds or trapped, and Zig safety checks trapped. Spec changes, regenerated with the unchanged pin eb8b4208: - network_simulator.inject_fault: a node failure with target_id >= MAX_NODES returns 0 (the existing failure value) and leaves node_states alone. Written as if/else rather than an early return, because the pinned Verilog emitter does not skip statements after a nested early return. - traffic_animator.update_animation_packets: packet_count is clamped to MAX_PACKETS; the active_packets field reports the clamped count. - topology_visualizer.calculate_circular_layout and calculate_hierarchical_layout: node_count is clamped to MAX_NODES and the clamped count is returned. The hierarchical layout uses one node per level when node_count < 4 instead of dividing by zero. In-range inputs return the same values as before. Public argument and return types are unchanged. Typecheck warning counts are unchanged (6, 28, 27). Each spec gains a test block with the boundary inputs (runs under zig test, the C runner and icarus-simulate). tests/gen_rust_bounds.rs calls the generated Rust with the inputs from the issue table; against the previous gen/rust all five tests panic. Closes gHashTag#410 Refs gHashTag#399
Summary by t27-beesChecked by the t27 compilert27c parse, parse-complete and typecheck on each changed .t27 file at
Read by the modelThis PR fixes four out-of-bounds accesses and one division-by-zero in generated code by adding bounds checks and clamping in the spec files, then regenerating all three backends. The fixes target Worth a look
Read: 44 files, +1651 -467, the whole diff up to 60000 characters (the rest was not read). Head |
Closes #410
Refs #399. Stacked on #409: this branch starts at #409's head
59f39b68, because #409 changes the same three specs and makes these modules compile in Rust. Until #409 merges, this PR also shows its commit; merge #409 first, then this PR (the diff then reduces to the single commitda49268a).What changes
Four generated functions indexed past a fixed-size array or divided by zero for out-of-range inputs. The spec is the fix; all three backends are regenerated with the unchanged pin
eb8b4208, no generated file is edited by hand.network_simulator::inject_faultEVENT_NODE_FAILURE,target_id = 320(the existing failure value);node_statesuntouchedtraffic_animator::update_animation_packetspacket_count = 65MAX_PACKETS(64);active_packetsfield reports 64topology_visualizer::calculate_circular_layoutnode_count = 33MAX_NODES(32) and returnedtopology_visualizer::calculate_hierarchical_layoutnode_count = 3node_count < 4; count also clamped to 32In-range inputs return the same values as before. Public argument and return types are unchanged.
inject_faultuses if/else instead of a nested early return, because the pinned Verilog emitter does not skip the statements after a nested early return (the first draft failedicarus-simulatefor exactly that reason).Tests
testblock with the boundary inputs. Locally they pass underzig test(Zig 0.15.2), the C runner (-DT27_TEST_MAIN) andt27c icarus-simulate.tests/gen_rust_bounds.rs(declared inCargo.toml) calls the generatedgen/rustmodules with the inputs from the issue table plusu32::MAX. Negative control: against the previousgen/rustall five tests panic (topology_visualizer.rs:220,:242,network_simulator.rs:283,traffic_animator.rs:283).cargo fmt --all --check,cargo clippy --all-targets -- -D warningsandcargo testpass, includinggen_rust_corpus_compilesfrom fix(gen): compile all 102 generated Rust modules and gate the corpus #409.t27coutput;tools/regen.rs --check-stagedverified 9 staged artifacts.CI on this PR is the source of truth; the local runs above are not a substitute for it.
Not in scope
Same pattern, not listed in #410, left for a follow-up:
run_simulation_step(event_count > MAX_EVENTS),generate_traffic_heat_map(packet_count > MAX_PACKETS) andcalculate_animation_stats(frame_count > MAX_FRAMES).Dmitrii Fedorov (@dmitrii-f-t27)