summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/projects/c/filc/safety_test/src/main.c17
-rw-r--r--tests/projects/c/filc/safety_test/test.lua52
-rw-r--r--tests/projects/c/filc/safety_test/xmake.lua9
3 files changed, 78 insertions, 0 deletions
diff --git a/tests/projects/c/filc/safety_test/src/main.c b/tests/projects/c/filc/safety_test/src/main.c
new file mode 100644
index 000000000..d23718c3e
--- /dev/null
+++ b/tests/projects/c/filc/safety_test/src/main.c
@@ -0,0 +1,17 @@
+/* Test that filc catches calling a function pointer with a wrong address.
+ *
+ * Expected runtime output (exit non-zero):
+ * filc safety error: cannot access pointer as function with ptr != aux ...
+ * filc panic: thwarted a futile attempt to violate memory safety.
+ */
+#include <stdfil.h>
+#include <stdlib.h>
+
+static void foo(void) {
+}
+
+int main() {
+ void (*my_foo)(void) = (void(*)(void))((char*)foo + 42);
+ my_foo();
+ return 0;
+}
diff --git a/tests/projects/c/filc/safety_test/test.lua b/tests/projects/c/filc/safety_test/test.lua
new file mode 100644
index 000000000..2a372b3cd
--- /dev/null
+++ b/tests/projects/c/filc/safety_test/test.lua
@@ -0,0 +1,52 @@
+import("utils.ci.is_running", {alias = "ci_is_running"})
+
+function main(t)
+ -- filc only supports Linux x86_64
+ if os.host() ~= "linux" or os.arch() ~= "x86_64" then
+ return t:skip("filc is only supported on linux/x86_64")
+ end
+
+ local flags = ci_is_running() and "-vD" or ""
+
+ -- configure and install the filc package; skip if unavailable
+ local configured = try
+ {
+ function ()
+ os.exec("xmake f -c -y " .. flags)
+ return true
+ end,
+ catch { function () end }
+ }
+ if not configured then
+ return t:skip("filc package not available or install failed")
+ end
+
+ os.exec("xmake -r " .. flags)
+
+ -- find the compiled binary
+ local binfile = path.join("build", os.host(), os.arch(), "release", "safety_test")
+ assert(os.isfile(binfile), "binary not found: " .. binfile)
+
+ -- run the binary — it MUST exit non-zero and emit a filc safety error
+ -- os.iorunv raises on non-zero exit in the sandbox, so catch the failure
+ local filc_output = nil
+ try
+ {
+ function ()
+ os.iorunv(binfile, {})
+ end,
+ catch
+ {
+ function (errors)
+ filc_output = tostring(errors)
+ end
+ }
+ }
+ assert(filc_output, "expected safety_test to exit non-zero, but it succeeded")
+ assert(filc_output:find("filc safety error", 1, true),
+ "expected 'filc safety error' in output, got:\n" .. filc_output)
+ assert(filc_output:find("filc panic", 1, true),
+ "expected 'filc panic' in output, got:\n" .. filc_output)
+
+ cprint("${green}filc safety check triggered as expected${reset}")
+end
diff --git a/tests/projects/c/filc/safety_test/xmake.lua b/tests/projects/c/filc/safety_test/xmake.lua
new file mode 100644
index 000000000..4ebbf9792
--- /dev/null
+++ b/tests/projects/c/filc/safety_test/xmake.lua
@@ -0,0 +1,9 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("filc")
+
+target("safety_test")
+ set_kind("binary")
+ set_toolchains("@filc")
+ add_packages("filc")
+ add_files("src/*.c")