fix: diagnose missing 'main' instead of segfaulting on 'sx run' (issue 0137)
A program with no 'main' reached the JIT entry-point call with a garbage address (ORC reports lookup success but leaves main_addr degenerate), then called it -> SIGSEGV. Add a pre-JIT entry-point check in main.zig that emits 'error: no main function found' and exits non-zero before codegen, plus a defensive main_addr==0 guard in target.zig runJITFromObject as a backstop. Regression: examples/1188-diagnostics-run-no-main.sx
This commit is contained in:
39
examples/1059-errors-same-name-error-set-own-wins.sx
Normal file
39
examples/1059-errors-same-name-error-set-own-wins.sx
Normal file
@@ -0,0 +1,39 @@
|
||||
// issue 0134 — a same-name `error` set collapses into a namespaced import's
|
||||
// set (error sets lack per-decl nominal identity).
|
||||
//
|
||||
// `EventErr` is declared locally as `error { Boom }`, but
|
||||
// `#import "modules/std.sx"` also carries `event.EventErr` (an error set with
|
||||
// tags Init/Register/Wait). Because error-set DECLARATIONS are not given
|
||||
// per-decl nominal identity (unlike struct/enum/union under E6a) —
|
||||
// `registerErrorSetDecl` registers via the flat `findByName`-dedup path — the
|
||||
// local `EventErr` collapses into the imported one, losing its own `Boom` tag.
|
||||
//
|
||||
// So `raise error.Boom` / `r == error.Boom` are checked against the IMPORTED
|
||||
// set, which has no `Boom`.
|
||||
//
|
||||
// EXPECT (today): build FAILS —
|
||||
// error: error tag 'error.Boom' is not in error set 'EventErr'
|
||||
// EXPECT (after fix): prints `own EventErr.Boom`, exit 0.
|
||||
//
|
||||
// Proof it's the collision: rename `EventErr` -> `MyErr` and it compiles and
|
||||
// prints. The reference side (`!EventErr` → resolveNominalLeaf) is already
|
||||
// visibility-aware from issue 0132's broader fix, but it is dormant until the
|
||||
// local declaration gets its own TypeId. See the .md.
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
EventErr :: error { Boom }
|
||||
|
||||
fail :: () -> !EventErr {
|
||||
raise error.Boom;
|
||||
}
|
||||
|
||||
main :: () -> i32 {
|
||||
r := fail();
|
||||
if r == error.Boom {
|
||||
print("own EventErr.Boom\n");
|
||||
return 0;
|
||||
}
|
||||
print("wrong set\n");
|
||||
return 1;
|
||||
}
|
||||
12
examples/1188-diagnostics-run-no-main.sx
Normal file
12
examples/1188-diagnostics-run-no-main.sx
Normal file
@@ -0,0 +1,12 @@
|
||||
// `sx run` on a program with no `main` must emit a clean diagnostic and exit
|
||||
// non-zero — never call into a garbage JIT address and segfault. A pre-JIT
|
||||
// entry-point check in main.zig (plus a defensive `main_addr == 0` backstop in
|
||||
// target.zig's runJITFromObject) replaces the old silent garbage-pointer call.
|
||||
//
|
||||
// Regression (issue 0137).
|
||||
#import "modules/std.sx";
|
||||
|
||||
// Intentionally no `main` — only a helper.
|
||||
greet :: () {
|
||||
print("unreachable\n");
|
||||
}
|
||||
1
examples/expected/1188-diagnostics-run-no-main.exit
Normal file
1
examples/expected/1188-diagnostics-run-no-main.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
1
examples/expected/1188-diagnostics-run-no-main.stderr
Normal file
1
examples/expected/1188-diagnostics-run-no-main.stderr
Normal file
@@ -0,0 +1 @@
|
||||
error: no 'main' function found — 'sx run' requires a top-level 'main' entry point
|
||||
1
examples/expected/1188-diagnostics-run-no-main.stdout
Normal file
1
examples/expected/1188-diagnostics-run-no-main.stdout
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user