From 491e62664394a8689a3f8904fbe8dbc3dea05524 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 30 Aug 2026 02:08:45 +0200 Subject: Fix ICEs with recursive type declarations --- testsuite/compilable/self-referencing-record.elna | 5 +++ .../fail_compilation/alias-cycle-behind-const.elna | 4 ++ testsuite/fail_compilation/alias-cycle.elna | 4 ++ testsuite/fail_compilation/alias-field-cycle.elna | 5 +++ testsuite/fail_compilation/array-cycle.elna | 3 ++ .../non_constant_array_dimension.elna | 9 ++++ .../non_constant_array_dimension.elna.s | 1 + testsuite/fail_compilation/pointer-cycle.elna | 3 ++ testsuite/fail_compilation/procedure-cycle.elna | 3 ++ testsuite/fail_compilation/record-base-cycle.elna | 4 ++ .../fail_compilation/record-base-cycle.elna.s | 1 + testsuite/fail_compilation/slice-cycle.elna | 3 ++ testsuite/runnable/recursive_record.elna | 48 ++++++++++++++++++++++ 13 files changed, 93 insertions(+) create mode 100644 testsuite/compilable/self-referencing-record.elna create mode 100644 testsuite/fail_compilation/alias-cycle-behind-const.elna create mode 100644 testsuite/fail_compilation/alias-cycle.elna create mode 100644 testsuite/fail_compilation/alias-field-cycle.elna create mode 100644 testsuite/fail_compilation/array-cycle.elna create mode 100644 testsuite/fail_compilation/non_constant_array_dimension.elna create mode 100644 testsuite/fail_compilation/non_constant_array_dimension.elna.s create mode 100644 testsuite/fail_compilation/pointer-cycle.elna create mode 100644 testsuite/fail_compilation/procedure-cycle.elna create mode 100644 testsuite/fail_compilation/record-base-cycle.elna create mode 100644 testsuite/fail_compilation/record-base-cycle.elna.s create mode 100644 testsuite/fail_compilation/slice-cycle.elna create mode 100644 testsuite/runnable/recursive_record.elna (limited to 'testsuite') diff --git a/testsuite/compilable/self-referencing-record.elna b/testsuite/compilable/self-referencing-record.elna new file mode 100644 index 0000000..cc98f86 --- /dev/null +++ b/testsuite/compilable/self-referencing-record.elna @@ -0,0 +1,5 @@ +type + R = record + field: ^R + end +end. diff --git a/testsuite/fail_compilation/alias-cycle-behind-const.elna b/testsuite/fail_compilation/alias-cycle-behind-const.elna new file mode 100644 index 0000000..0c3b626 --- /dev/null +++ b/testsuite/fail_compilation/alias-cycle-behind-const.elna @@ -0,0 +1,4 @@ +type + A = B + B = const A (* @Error Type declaration forms a cycle: A -> B -> A *) +end. diff --git a/testsuite/fail_compilation/alias-cycle.elna b/testsuite/fail_compilation/alias-cycle.elna new file mode 100644 index 0000000..e6c822b --- /dev/null +++ b/testsuite/fail_compilation/alias-cycle.elna @@ -0,0 +1,4 @@ +type + A = B + B = A (* @Error Type declaration forms a cycle: A -> B -> A *) +end. diff --git a/testsuite/fail_compilation/alias-field-cycle.elna b/testsuite/fail_compilation/alias-field-cycle.elna new file mode 100644 index 0000000..f4a554a --- /dev/null +++ b/testsuite/fail_compilation/alias-field-cycle.elna @@ -0,0 +1,5 @@ +type + A = record (* @Error Type declaration forms a cycle: A -> A *) + field: A + end +end. diff --git a/testsuite/fail_compilation/array-cycle.elna b/testsuite/fail_compilation/array-cycle.elna new file mode 100644 index 0000000..617e23d --- /dev/null +++ b/testsuite/fail_compilation/array-cycle.elna @@ -0,0 +1,3 @@ +type + A = [2]A (* @Error Type declaration forms a cycle: A -> A *) +end. diff --git a/testsuite/fail_compilation/non_constant_array_dimension.elna b/testsuite/fail_compilation/non_constant_array_dimension.elna new file mode 100644 index 0000000..4ab0d34 --- /dev/null +++ b/testsuite/fail_compilation/non_constant_array_dimension.elna @@ -0,0 +1,9 @@ +proc f(len: Int) +var + array: [len]Int (* @Error Array dimensions for type 'Int' should be constant *) +begin + return + +begin + f(5) +end. diff --git a/testsuite/fail_compilation/non_constant_array_dimension.elna.s b/testsuite/fail_compilation/non_constant_array_dimension.elna.s new file mode 100644 index 0000000..8dc704d --- /dev/null +++ b/testsuite/fail_compilation/non_constant_array_dimension.elna.s @@ -0,0 +1 @@ + .file "non_constant_array_dimension.elna" diff --git a/testsuite/fail_compilation/pointer-cycle.elna b/testsuite/fail_compilation/pointer-cycle.elna new file mode 100644 index 0000000..f9ee649 --- /dev/null +++ b/testsuite/fail_compilation/pointer-cycle.elna @@ -0,0 +1,3 @@ +type + A = ^A (* @Error Type declaration forms a cycle: A -> A *) +end. diff --git a/testsuite/fail_compilation/procedure-cycle.elna b/testsuite/fail_compilation/procedure-cycle.elna new file mode 100644 index 0000000..aaed14c --- /dev/null +++ b/testsuite/fail_compilation/procedure-cycle.elna @@ -0,0 +1,3 @@ +type + A = proc(): A (* @Error Type declaration forms a cycle: A -> A *) +end. diff --git a/testsuite/fail_compilation/record-base-cycle.elna b/testsuite/fail_compilation/record-base-cycle.elna new file mode 100644 index 0000000..f3bcb20 --- /dev/null +++ b/testsuite/fail_compilation/record-base-cycle.elna @@ -0,0 +1,4 @@ +type + R = record(R) (* @Error Type declaration forms a cycle: R -> R *) + end +end. diff --git a/testsuite/fail_compilation/record-base-cycle.elna.s b/testsuite/fail_compilation/record-base-cycle.elna.s new file mode 100644 index 0000000..64f8722 --- /dev/null +++ b/testsuite/fail_compilation/record-base-cycle.elna.s @@ -0,0 +1 @@ + .file "record-base-cycle.elna" diff --git a/testsuite/fail_compilation/slice-cycle.elna b/testsuite/fail_compilation/slice-cycle.elna new file mode 100644 index 0000000..39eb7db --- /dev/null +++ b/testsuite/fail_compilation/slice-cycle.elna @@ -0,0 +1,3 @@ +type + A = []A (* @Error Type declaration forms a cycle: A -> A *) +end. diff --git a/testsuite/runnable/recursive_record.elna b/testsuite/runnable/recursive_record.elna new file mode 100644 index 0000000..6f6b4fa --- /dev/null +++ b/testsuite/runnable/recursive_record.elna @@ -0,0 +1,48 @@ +type + Node = record + value: Int; + next: ^Node + end + +var + first: ^Node + second: ^Node + third: ^Node + +proc malloc(size: Word): Pointer +extern + +proc free(ptr: Pointer) +extern + +proc sum(node: ^Node): Int +var + result: Int +begin + result := 0; + if node = nil then + result := 0 + else + result := node^.value + sum(node^.next) + end; + return result + +begin + first := malloc(#size(Node)); + second := malloc(#size(Node)); + third := malloc(#size(Node)); + + first^.value := 1; + first^.next := second; + second^.value := 2; + second^.next := third; + third^.value := 3; + third^.next := nil; + + assert(sum(first) = 6); + assert(first^.next^.next^.value = 3); + + free(first); + free(second); + free(third) +end. -- cgit v1.2.3