summaryrefslogtreecommitdiff
path: root/tests/memory
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-14 23:59:54 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-14 23:59:54 +0000
commitdcfdc053cb5f9fb4d5eac0a2233c75126b7a8188 (patch)
treef34f30b382fa22d6fd0af46875a5b4b26d00feff /tests/memory
parenta918df69269a39ef7350a645b5db025d66ecb18a (diff)
Added some of the tests.
Diffstat (limited to 'tests/memory')
-rw-r--r--tests/memory/test_memory_safety.zc217
-rw-r--r--tests/memory/test_unsafe.zc56
2 files changed, 273 insertions, 0 deletions
diff --git a/tests/memory/test_memory_safety.zc b/tests/memory/test_memory_safety.zc
new file mode 100644
index 0000000..5cec2db
--- /dev/null
+++ b/tests/memory/test_memory_safety.zc
@@ -0,0 +1,217 @@
+
+import "std/mem.zc"
+
+// --- Globals ---
+var DROP_COUNT = 0;
+
+// --- Structs & Helpers ---
+
+trait Drop {
+ fn drop(self);
+}
+
+struct Resource {
+ id: int;
+}
+
+impl Drop for Resource {
+ fn drop(self) {
+ println "Dropping Resource {self.id}";
+ DROP_COUNT = DROP_COUNT + 1;
+ }
+}
+
+fn create_resource(id: int) {
+ var r = Resource{id: id};
+ println "Created Resource {r.id}";
+}
+
+struct Point {
+ x: int;
+ y: int;
+}
+
+fn distance(p1: Point, p2: Point) -> int {
+ var dx = p2.x - p1.x;
+ var dy = p2.y - p1.y;
+ return dx * dx + dy * dy;
+}
+
+fn accumulate(start: int, count: int) -> int {
+ var mut sum = start;
+ var mut i = 0;
+ while (i < count) {
+ sum += i;
+ i++;
+ }
+ return sum;
+}
+
+fn process_point(p: Point) -> Point {
+ var result = Point { x: p.x * 2, y: p.y * 2 };
+ return result;
+}
+
+fn counter_immut() {
+ var mut count = 0;
+ {
+ var mut inner = 10;
+ inner = inner + 5;
+ count = count + inner;
+ }
+}
+
+struct Permissions {
+ mask: U8;
+}
+
+impl Permissions {
+ fn new(m: U8) -> Permissions {
+ return Permissions { mask: m };
+ }
+ fn bitor(self, other: Permissions) -> Permissions {
+ return Permissions { mask: self.mask | other.mask };
+ }
+ fn has(self, flag: U8) -> U8 {
+ return (self.mask & flag) == flag;
+ }
+}
+
+fn get_resource() -> int {
+ println "resource opened";
+ return 42;
+}
+
+fn release_resource(id: int) {
+ if (id == 42) println "resource 42 released";
+ else println "resource released (unknown)";
+}
+
+fn test_defer_logic() {
+ println "start test";
+ var x = get_resource() defer release_resource(it);
+ println "using resource {x}";
+}
+
+
+test "test_alloc" {
+ "Testing alloc<T>...";
+
+ var p = alloc<int>();
+ *p = 42;
+ f" alloc<int>(): {*p}";
+ assert(*p == 42, "alloc failed");
+ free(p);
+
+ var arr = alloc_n<int>(5);
+ for var i = 0; i < 5; i++ {
+ arr[i] = i * 10;
+ }
+ f" alloc_n<int>(5): [{arr[0]}, {arr[1]}, {arr[2]}, {arr[3]}, {arr[4]}]";
+ free(arr);
+
+ " ✓ alloc works!";
+}
+
+test "test_box" {
+ "Testing Box<T>...";
+ var b = Box<int>::new();
+ *b.get() = 100;
+ var val = *b.get();
+ f" Box value: {val}";
+ assert(val == 100, "Box failed");
+ b.free();
+ " ✓ Box works!";
+}
+
+test "test_slice" {
+ "Testing Slice<T>...";
+ var data: int[5] = [1, 2, 3, 4, 5];
+ var s = Slice<int>::new(&data[0], 5);
+ f" Slice len: {(int)s.len}";
+ var v2 = s.get(2);
+ f" Slice[2]: {v2}";
+ assert(v2 == 3, "Slice get failed");
+ s.set(0, 99);
+ var v0 = s.get(0);
+ f" After set: Slice[0] = {v0}";
+ assert(v0 == 99, "Slice set failed");
+ " ✓ Slice works!";
+}
+
+test "test_swap" {
+ "Testing swap<T>...";
+ var a = 10;
+ var b = 20;
+ f" Before: a={a}, b={b}";
+ swap<int>(&a, &b);
+ f" After: a={a}, b={b}";
+ assert(a == 20 && b == 10, "swap failed");
+ " ✓ swap works!";
+}
+
+test "test_autofree" {
+ println "Testing autofree...";
+ {
+ autofree var p = malloc(1024);
+ if (p == NULL) { eprintln "Malloc failed!"; }
+ strcpy(p, "Auto-freed string");
+ print f"Allocated: {p}"; println "";
+ }
+ println "Exited block successfully (hopefully freed)";
+ {
+ autofree var p1 = malloc(10);
+ autofree var p2 = malloc(20);
+ }
+}
+
+test "test_raii_drop" {
+ DROP_COUNT = 0;
+ "Entering scope...";
+ create_resource(1);
+ "Exited scope.";
+ assert(DROP_COUNT == 1, "Expected Drop to be called once");
+ {
+ var r2 = Resource{id: 2};
+ var r3 = Resource{id: 3};
+ }
+ assert(DROP_COUNT == 3, "Expected 3 total drops");
+}
+
+test "test_immutable" {
+ var p1 = Point { x: 0, y: 0 };
+ var p2 = Point { x: 3, y: 4 };
+ var dist = distance(p1, p2);
+ "Distance: {dist}";
+ var sum = accumulate(10, 5);
+ "Accumulate: {sum}";
+ var p3 = process_point(p1);
+ "Processed: ({p3.x}, {p3.y})";
+ counter_immut();
+}
+
+test "test_permissions" {
+ const READ : U8 = 0b100;
+ const WRITE : U8 = 0b010;
+ const EXEC : U8 = 0b001;
+
+ var p1 = Permissions::new(READ);
+ "Start: {p1.mask} (Read)";
+
+ var p2 = Permissions::new(WRITE);
+ var p_rw = p1 | p2;
+ "Combined: {p_rw.mask} (Read + Write)";
+
+ if (p_rw.has(EXEC)) { " > Has Execute access"; }
+ else { " > No Execute access"; }
+
+ if (p_rw.has(READ)) { " > Has Read access"; }
+
+ var p_all = p_rw | Permissions::new(EXEC);
+ "Final: {p_all.mask} (All)";
+}
+
+test "test_value_defer" {
+ test_defer_logic();
+ println "end test";
+}
diff --git a/tests/memory/test_unsafe.zc b/tests/memory/test_unsafe.zc
new file mode 100644
index 0000000..126404a
--- /dev/null
+++ b/tests/memory/test_unsafe.zc
@@ -0,0 +1,56 @@
+
+raw {
+ #define MY_C_CONST 12345
+ int legacy_add(int a, int b) {
+ return a + b + MY_C_CONST;
+ }
+}
+
+extern fn legacy_add(a: int, b: int) -> int;
+
+fn process_arrays(n: int, a: restrict int*, b: restrict int*, out: restrict int*) {
+ for (var i = 0; i < n; i = i + 1) {
+ out[i] = a[i] + b[i];
+ }
+}
+
+fn counter() -> int {
+ static var count = 0;
+ count = count + 1;
+ return count;
+}
+
+test "test_raw" {
+ println "Testing Raw C Embedding...";
+ var res = legacy_add(10, 20);
+ // Expected: 10 + 20 + 12345 = 12375
+ assert(res == 12375, "Raw C Code failed");
+ println " Raw C Code: Success (Result: {res})";
+}
+
+test "test_restrict" {
+ var a: int[10];
+ var b: int[10];
+ var c: int[10];
+
+ for (var i = 0; i < 10; i = i + 1) {
+ a[i] = i;
+ b[i] = i * 2;
+ }
+
+ process_arrays(10, a, b, c);
+
+ for (var i = 0; i < 10; i = i + 1) {
+ assert(c[i] == i * 3, "Restrict test failed");
+ }
+}
+
+test "test_static_local" {
+ var a = counter(); // 1
+ var b = counter(); // 2
+ var c = counter(); // 3
+
+ assert a == 1;
+ assert b == 2;
+ assert c == 3;
+}