From 38c32400f5f4aa008f38bbd35d6f5a5c2a1d453b Mon Sep 17 00:00:00 2001 From: agra Date: Mon, 15 Jun 2026 03:53:03 +0300 Subject: [PATCH] =?UTF-8?q?test(ffi-linkage):=20Phase=205.0=20prereq=20?= =?UTF-8?q?=E2=80=94=20xfail=20extern=20undeclared-library=20ref=20unvalid?= =?UTF-8?q?ated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An `extern LIB "csym"` ref must name a declared #library / #import c unit, like its `#foreign LIB` twin (example 1620). Today checkForeignRefs reads only foreign_expr.library_ref and skips the extern keyword's extern_lib, so a bogus `extern nosuchunit "abs"` compiles silently (the symbol resolves via the default image and runs). Expected pins the DESIRED compile-time diagnostic; the next commit extends checkForeignRefs to green it. Fourth extern/#foreign divergence and a prerequisite for the fn-decl migration. 647 corpus (1231 xfail), 444 unit. --- examples/1231-ffi-extern-undeclared-lib.sx | 19 +++++++++++++++++++ .../1231-ffi-extern-undeclared-lib.exit | 1 + .../1231-ffi-extern-undeclared-lib.stderr | 5 +++++ .../1231-ffi-extern-undeclared-lib.stdout | 0 4 files changed, 25 insertions(+) create mode 100644 examples/1231-ffi-extern-undeclared-lib.sx create mode 100644 examples/expected/1231-ffi-extern-undeclared-lib.exit create mode 100644 examples/expected/1231-ffi-extern-undeclared-lib.stderr create mode 100644 examples/expected/1231-ffi-extern-undeclared-lib.stdout diff --git a/examples/1231-ffi-extern-undeclared-lib.sx b/examples/1231-ffi-extern-undeclared-lib.sx new file mode 100644 index 0000000..8f540e0 --- /dev/null +++ b/examples/1231-ffi-extern-undeclared-lib.sx @@ -0,0 +1,19 @@ +// An `extern LIB "csym"` reference must name something real, exactly like +// its `#foreign LIB` twin (example 1620): `nosuchunit` names neither a +// #library constant nor a named `#import c` unit, so this is a compile-time +// diagnostic — the bogus library reference is caught BEFORE the symbol +// would silently resolve through whatever image happens to carry it. +// +// Regression (FFI-linkage Part B): `checkForeignRefs` validated only a +// `#foreign` (foreign_expr) library_ref and skipped the `extern` keyword's +// `extern_lib`, so a bogus `extern` lib reference compiled silently (the +// symbol resolved via the default image and ran). Prerequisite for +// migrating the fn-decl `#foreign` path onto `extern`. +#import "modules/std.sx"; + +c_abs :: (n: i32) -> i32 extern nosuchunit "abs"; + +main :: () -> i32 { + print("c_abs = {}\n", c_abs(-5)); + 0 +} diff --git a/examples/expected/1231-ffi-extern-undeclared-lib.exit b/examples/expected/1231-ffi-extern-undeclared-lib.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/examples/expected/1231-ffi-extern-undeclared-lib.exit @@ -0,0 +1 @@ +1 diff --git a/examples/expected/1231-ffi-extern-undeclared-lib.stderr b/examples/expected/1231-ffi-extern-undeclared-lib.stderr new file mode 100644 index 0000000..f81012c --- /dev/null +++ b/examples/expected/1231-ffi-extern-undeclared-lib.stderr @@ -0,0 +1,5 @@ +error: extern library 'nosuchunit' is not declared; expected a #library constant or a named '#import c' unit + --> examples/1231-ffi-extern-undeclared-lib.sx:14:1 + | +14 | c_abs :: (n: i32) -> i32 extern nosuchunit "abs"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/expected/1231-ffi-extern-undeclared-lib.stdout b/examples/expected/1231-ffi-extern-undeclared-lib.stdout new file mode 100644 index 0000000..e69de29