aboutsummaryrefslogtreecommitdiff
path: root/tests/i/memory-reallocation
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 05:33:33 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 05:33:33 +0000
commit4e22f464387725a5a282f3d72e11cfb694a31a5a (patch)
tree17fed09b30633e6aae583f490a0ad9c0c95fb045 /tests/i/memory-reallocation
parent4dd85fd6ecd9a67e5c2b68380873e6e114714355 (diff)
feat(memory): add checked REALLOC with failure preservation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'tests/i/memory-reallocation')
-rw-r--r--tests/i/memory-reallocation/case.json1
-rw-r--r--tests/i/memory-reallocation/expected.txt17
-rw-r--r--tests/i/memory-reallocation/notes.md5
-rw-r--r--tests/i/memory-reallocation/program.cps81
4 files changed, 104 insertions, 0 deletions
diff --git a/tests/i/memory-reallocation/case.json b/tests/i/memory-reallocation/case.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/tests/i/memory-reallocation/case.json
@@ -0,0 +1 @@
+{}
diff --git a/tests/i/memory-reallocation/expected.txt b/tests/i/memory-reallocation/expected.txt
new file mode 100644
index 0000000..9e9ccc9
--- /dev/null
+++ b/tests/i/memory-reallocation/expected.txt
@@ -0,0 +1,17 @@
+TRUE
+12:34
+12
+[Fatal] line 28: Memory allocation failed
+preserved:12
+56
+TRUE
+[Fatal] line 40: Invalid memory address (not an active allocation)
+released address caught
+[Fatal] line 47: Invalid memory address (not an active allocation)
+invalid zero resize caught
+71
+[Fatal] line 63: Invalid memory address (not an active allocation)
+[Fatal] line 69: Invalid memory address (not an active allocation)
+nested catch
+[Fatal] line 77: Invalid memory address (not an active allocation)
+internal buffer caught
diff --git a/tests/i/memory-reallocation/notes.md b/tests/i/memory-reallocation/notes.md
new file mode 100644
index 0000000..46560f5
--- /dev/null
+++ b/tests/i/memory-reallocation/notes.md
@@ -0,0 +1,5 @@
+# Trace notes
+
+Human review: pending.
+
+This case exercises explicit memory extensions. REALLOC(null, 0) returns null; REALLOC(null, 16) allocates. The record's 12 and 34 survive growth, and 12 survives shrinking to one INTEGER. A SIZE_MAX request fails without changing the pointer or its stored 12; a subsequent write of 56 survives resizing. A zero resize frees the block and returns null. Resizing its released address throws; a stack pointer throws even at zero size. C int 71 survives reallocation after an allocation returned from a function. Invalid resizing inside a function unwinds to its caller; another invalid free is caught inside that catch. A STRING literal is rejected as untracked storage. The final nested allocation/resize/free has no output.
diff --git a/tests/i/memory-reallocation/program.cps b/tests/i/memory-reallocation/program.cps
new file mode 100644
index 0000000..d119256
--- /dev/null
+++ b/tests/i/memory-reallocation/program.cps
@@ -0,0 +1,81 @@
+TYPE Raw = C_TYPE("void*")
+TYPE NativePointer = C_TYPE("int*")
+TYPE Pair
+ DECLARE First : INTEGER
+ DECLARE Second : INTEGER
+ENDTYPE
+TYPE PairPointer = ^Pair
+TYPE IntPointer = ^INTEGER
+DECLARE Empty : Raw
+DECLARE P : Raw
+DECLARE Q : Raw
+DECLARE Number : INTEGER
+DECLARE Pointer : IntPointer
+DECLARE PairAddress : PairPointer
+DECLARE Native : NativePointer
+OUTPUT REALLOC(Empty, 0) = Empty
+P <- REALLOC(Empty, 16)
+PairAddress <- (PairPointer)P
+PairAddress^.First <- 12
+PairAddress^.Second <- 34
+P <- REALLOC(P, 32)
+PairAddress <- (PairPointer)P
+OUTPUT PairAddress^.First, ":", PairAddress^.Second
+P <- REALLOC(P, (C_INT)8)
+Pointer <- (IntPointer)P
+OUTPUT Pointer^
+TRY
+ P <- REALLOC(P, -1)
+CATCH
+ Pointer <- (IntPointer)P
+ OUTPUT "preserved:", Pointer^
+ENDTRY
+Pointer^ <- 56
+P <- REALLOC(P, 16)
+Pointer <- (IntPointer)P
+OUTPUT Pointer^
+Q <- P
+OUTPUT REALLOC(P, 0) = Empty
+TRY
+ REALLOC(Q, 8)
+CATCH
+ OUTPUT "released address caught"
+ENDTRY
+Pointer <- ^Number
+Q <- (Raw)Pointer
+TRY
+ REALLOC(Q, 0)
+CATCH
+ OUTPUT "invalid zero resize caught"
+ENDTRY
+FUNCTION AllocateNative() RETURNS Raw
+ RETURN MALLOC(16)
+ENDFUNCTION
+P <- AllocateNative()
+Native <- (NativePointer)P
+Native^ <- (C_INT)71
+P <- REALLOC(P, 32)
+Native <- (NativePointer)P
+OUTPUT Native^
+FREE(P)
+// A runtime failure raised from a function propagates to the caller.
+FUNCTION InvalidResize(Value : Raw) RETURNS Raw
+ RETURN REALLOC(Value, 8)
+ENDFUNCTION
+TRY
+ InvalidResize(Q)
+CATCH
+ TRY
+ FREE(Q)
+ CATCH
+ OUTPUT "nested catch"
+ ENDTRY
+ENDTRY
+// STRING storage is deliberately outside the explicit allocation list.
+Q <- (Raw)(C_STRING)"internal"
+TRY
+ REALLOC(Q, 16)
+CATCH
+ OUTPUT "internal buffer caught"
+ENDTRY
+FREE(REALLOC(Empty, (C_INT)8))