From 13efc565fac0ae4abf0b25c6668290ea86ed6a87 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 16:56:25 +0300 Subject: [PATCH] =?UTF-8?q?ffi=20issue-0046:=20nested=20comptime=20call=20?= =?UTF-8?q?+=20return=20=E2=80=94=20expected-failing=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lock-in for issue-0046. The test file expects the WORKING output ("inside" / "n=42") — pre-fix the interp panics non-deterministically at `storeAtRawPtr` (null pointer store) because `createComptimeFunction` does not save/restore the outer `lowerComptimeCall`'s `inline_return_target` state; the wrapper fn built for the nested `print` body inherits a slot belonging to a different basic block. Cadence rule shape 2: expected-failing test, the next commit turns it green. Today the suite shows 1 failure (issue-0046); post-fix it returns to all green. The thread ID + hex addresses in the panic output are non- deterministic so locking in the broken shape directly would be flaky — comparing actual panic vs expected-working still diffs as FAIL pre-fix, no need to snapshot the panic. The pack-fn face of issue-0046 was fixed incidentally by step 2b (mono path bypasses the inline-return-slot setup that leaked into nested comptime calls). Plain `($x: s32)` comptime fns stay on the inline path and still need this fix. --- examples/issue-0046.sx | 30 ++++++++++++++++++++++++++++++ tests/expected/issue-0046.exit | 1 + tests/expected/issue-0046.txt | 2 ++ 3 files changed, 33 insertions(+) create mode 100644 examples/issue-0046.sx create mode 100644 tests/expected/issue-0046.exit create mode 100644 tests/expected/issue-0046.txt diff --git a/examples/issue-0046.sx b/examples/issue-0046.sx new file mode 100644 index 0000000..e3b99c0 --- /dev/null +++ b/examples/issue-0046.sx @@ -0,0 +1,30 @@ +// issue-0046 — nested comptime call + return: state leak from +// outer `lowerComptimeCall` into the wrapper fn built by +// `createComptimeFunction`. Without saving/restoring +// `inline_return_target`, the wrapper inherits an inline-return +// slot belonging to a different basic block; the interp executes +// the wrapper and trips a null-pointer store at +// `storeAtRawPtr`. +// +// Repro: comptime fn (`$x: s32`) whose body has BOTH a nested +// comptime call (`print`) AND a `return X;` statement. Pre-fix: +// interp panics. Post-fix: prints "inside" then "n=42". +// +// The pack-fn variant of the same bug (filed in the original +// issue as face 2) was fixed earlier when step-2b moved pack-fn +// calls off the inline path into the mono path. Plain comptime +// fns stay on the inline path; their fix is the +// `createComptimeFunction` state save/restore. + +#import "modules/std.sx"; + +helper :: ($x: s32) -> s64 { + print("inside\n"); + return 42; +} + +main :: () -> s32 { + n := helper(7); + print("n={}\n", n); + return 0; +} diff --git a/tests/expected/issue-0046.exit b/tests/expected/issue-0046.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tests/expected/issue-0046.exit @@ -0,0 +1 @@ +0 diff --git a/tests/expected/issue-0046.txt b/tests/expected/issue-0046.txt new file mode 100644 index 0000000..5772865 --- /dev/null +++ b/tests/expected/issue-0046.txt @@ -0,0 +1,2 @@ +inside +n=42