Skip to content

Commit 46621d1

Browse files
committed
Fix cgen return-unwind drops, dedupe _ silence, and mark call moves at emission.
Stop poisoning the scope stack after inner-branch returns, run fallthrough cleanup before goto epilogue, regenerate example C snapshots, and note the fix in CHANGELOG.
1 parent bd7bf51 commit 46621d1

10 files changed

Lines changed: 178 additions & 131 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- **LSP**: diagnostics, hover, completion, go-to-definition; multi-error reporting; symbol table mirroring; diagnostics cleared on close; hover fixes for `let` bindings and module-qualified calls. Contiguous `//` doc comments attached to declarations (including `pub` items) for hover.
1010
- **Tooling**: GitHub Actions CI (Linux and Windows), pinned toolchain (1.96.0), `test_expectations.tsv` manifest, `--version`, line-numbered errors, Cursor agent skills. Split `tc` and `cgen` into submodules. `ion-build` driver and `ion.toml` manifests (`single`/`multi`, `out_dir`, `cflags`, `ldflags`, `stdlib_paths`, `emit_in_source`); per-example manifests and `build_hello`/`build_bad_main` harness smoke tests. Shared `discover_import_config` and stdlib search paths for `ion-compiler`, `ion-build`, and LSP. Integration harness precompiles `runtime/ion_runtime.c` once per run (`RUNTIME_OBJ`). `writing-ion-code` agent skill; `creating-ion-skills` examples index lists all eight project skills. Documented checked-in `examples/*.c` codegen snapshots in README and integration-test skill; regenerated example C output. Fixed `researching-pl-literature` skill `paper-seeds` reference formatting.
1111
- **Docs**: README, CONTRIBUTING, ION_SPEC, and agent skills aligned on project layout, `ion-build` workflow, `emit_in_source`, stdlib import order, LSP features and limitations, `src/build/` checklists, and portable Git Bash paths for `test_runner.sh`.
12-
- **Fixes**: match rvalue codegen, `Vec` struct drops, channel codegen, parser handling of `alias::call()`, scope-drop for moved-into-call bindings, HTTP server on Windows, integration harness on Windows. Integer indexing and `Vec<i32>` inference in the type checker. Match rvalue arms: reject diverging arms mixed with value arms; structural control-flow analysis for arm bodies (nested `if`/`else`, `loop` without `break`, `unsafe` blocks); reject mixed diverge and value-producing paths within one arm; cgen assigns through `if`/`else` value branches. `fmt::int_to_string` uses `String::push_byte` per digit instead of per-digit `push_str` branches; integration test asserts `0`, negatives, and `INT_MIN`. Clippy fix in `portable_source_label`.
12+
- **Fixes**: match rvalue codegen, `Vec` struct drops, channel codegen, parser handling of `alias::call()`, scope-drop for moved-into-call bindings, HTTP server on Windows, integration harness on Windows. Cgen return-unwind: stop marking bindings dropped after inner-branch `return` (restores outer-path drops), dedupe `_`-prefixed unused silences, and mark call arguments moved at emission to avoid double-free on unwind. Integer indexing and `Vec<i32>` inference in the type checker. Match rvalue arms: reject diverging arms mixed with value arms; structural control-flow analysis for arm bodies (nested `if`/`else`, `loop` without `break`, `unsafe` blocks); reject mixed diverge and value-producing paths within one arm; cgen assigns through `if`/`else` value branches. `fmt::int_to_string` uses `String::push_byte` per digit instead of per-digit `push_str` branches; integration test asserts `0`, negatives, and `INT_MIN`. Clippy fix in `portable_source_label`.
1313
- **Examples**: `text_summary` (fixture file), `data_lib` (multi-module), `channel_worker` (flat single-file). Per-example `*.toml` manifests for `ion-build`.
1414
- **Multi-file fixes**: merge private struct types for cross-module type checking; per-module C symbol prefixes in multi-file codegen (`io_print_int`); walk-up `runtime/` discovery for nested build directories. Integration tests `test_multi_struct`, `test_multi_fmt_io`. Example policy: single-file examples commit `.c` snapshots; `data_lib` multi-file keeps `.ion` only.
1515

examples/access_log.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,15 @@ int main(void) {
228228
}
229229
if (auth_failures != 1) {
230230
ret_val = 2;
231+
if (done_rx_mut.channel) { ion_channel_handle_drop(done_rx_mut.channel); }
231232
goto epilogue;
232233
}
233234
ion_string_t* server_line = fmt_int_to_string(server_errors);
234235
io_println(server_line);
235236
ion_string_t* auth_line = fmt_int_to_string(auth_failures);
236237
io_println(auth_line);
237238
ret_val = 0;
239+
if (done_rx_mut.channel) { ion_channel_handle_drop(done_rx_mut.channel); }
238240
goto epilogue;
239241
epilogue:
240242
return ret_val;
@@ -244,11 +246,10 @@ void io_print(ion_string_t* ION_MAYBE_UNUSED s) {
244246
{
245247
int _result = write(1, s->data, (int)s->len);
246248
(void)_result;
247-
(void)_result;
248249
}
250+
if (s) { ion_string_free(s); }
249251
goto epilogue;
250252
epilogue:
251-
if (s) { ion_string_free(s); }
252253
return;
253254
}
254255

@@ -258,24 +259,20 @@ void io_println(ion_string_t* ION_MAYBE_UNUSED s) {
258259
(void)_result;
259260
int _newline = write(1, (uint8_t*)"\n", 1);
260261
(void)_newline;
261-
(void)_newline;
262-
(void)_result;
263262
}
263+
if (s) { ion_string_free(s); }
264264
goto epilogue;
265265
epilogue:
266-
if (s) { ion_string_free(s); }
267266
return;
268267
}
269268

270269
void io_print_str(uint8_t* ION_MAYBE_UNUSED s, int ION_MAYBE_UNUSED len) {
271270
if (len < 0) {
272-
(void)s;
273-
goto epilogue;
271+
goto epilogue;
274272
}
275273
{
276274
int _result = write(1, s, len);
277275
(void)_result;
278-
(void)_result;
279276
}
280277
goto epilogue;
281278
epilogue:
@@ -291,7 +288,6 @@ void io_print_int(int ION_MAYBE_UNUSED n) {
291288
{
292289
int _result = write(1, (uint8_t*)"0", 1);
293290
(void)_result;
294-
(void)_result;
295291
}
296292
(void)negative;
297293
(void)len;
@@ -304,9 +300,11 @@ void io_print_int(int ION_MAYBE_UNUSED n) {
304300
{
305301
int _result = write(1, (uint8_t*)"-2147483648", 11);
306302
(void)_result;
307-
(void)_result;
308303
}
309-
goto epilogue;
304+
(void)negative;
305+
(void)len;
306+
(void)buf;
307+
goto epilogue;
310308
}
311309
value = (0 - value);
312310
}
@@ -327,13 +325,11 @@ void io_print_int(int ION_MAYBE_UNUSED n) {
327325
{
328326
int _minus = write(1, (uint8_t*)"-", 1);
329327
(void)_minus;
330-
(void)_minus;
331328
}
332329
}
333330
{
334331
int _result = write(1, &buf[0], len);
335332
(void)_result;
336-
(void)_result;
337333
}
338334
goto epilogue;
339335
epilogue:
@@ -352,7 +348,6 @@ void fmt_println_int(int ION_MAYBE_UNUSED n) {
352348
{
353349
int _newline = write(1, (uint8_t*)"\n", 1);
354350
(void)_newline;
355-
(void)_newline;
356351
}
357352
goto epilogue;
358353
epilogue:
@@ -379,6 +374,11 @@ ion_string_t* fmt_int_to_string(int ION_MAYBE_UNUSED n) {
379374
negative = 1;
380375
if (value == (-2147483648)) {
381376
ret_val = ion_string_from_literal("-2147483648", 11);
377+
(void)result;
378+
(void)negative;
379+
(void)len;
380+
(void)buf;
381+
if (result) { ion_string_free(result); }
382382
goto epilogue;
383383
}
384384
value = (0 - value);

examples/channel_worker.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ int main(void) {
6565
goto epilogue;
6666
}
6767
ret_val = 0;
68+
if (done_rx_mut.channel) { ion_channel_handle_drop(done_rx_mut.channel); }
69+
if (job_tx.channel) { ion_channel_handle_drop(job_tx.channel); }
6870
goto epilogue;
6971
epilogue:
7072
return ret_val;

examples/hello_world.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ int main(void) {
2121
{
2222
int _result = write(1, (uint8_t*)"Hello, World!\n", 14);
2323
(void)_result;
24-
(void)_result;
2524
}
2625
ret_val = 0;
2726
goto epilogue;

examples/hello_world_safe.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,10 @@ void io_print(ion_string_t* ION_MAYBE_UNUSED s) {
3333
{
3434
int _result = write(1, s->data, (int)s->len);
3535
(void)_result;
36-
(void)_result;
3736
}
37+
if (s) { ion_string_free(s); }
3838
goto epilogue;
3939
epilogue:
40-
if (s) { ion_string_free(s); }
4140
return;
4241
}
4342

@@ -47,24 +46,20 @@ void io_println(ion_string_t* ION_MAYBE_UNUSED s) {
4746
(void)_result;
4847
int _newline = write(1, (uint8_t*)"\n", 1);
4948
(void)_newline;
50-
(void)_newline;
51-
(void)_result;
5249
}
50+
if (s) { ion_string_free(s); }
5351
goto epilogue;
5452
epilogue:
55-
if (s) { ion_string_free(s); }
5653
return;
5754
}
5855

5956
void io_print_str(uint8_t* ION_MAYBE_UNUSED s, int ION_MAYBE_UNUSED len) {
6057
if (len < 0) {
61-
(void)s;
62-
goto epilogue;
58+
goto epilogue;
6359
}
6460
{
6561
int _result = write(1, s, len);
6662
(void)_result;
67-
(void)_result;
6863
}
6964
goto epilogue;
7065
epilogue:
@@ -80,7 +75,6 @@ void io_print_int(int ION_MAYBE_UNUSED n) {
8075
{
8176
int _result = write(1, (uint8_t*)"0", 1);
8277
(void)_result;
83-
(void)_result;
8478
}
8579
(void)negative;
8680
(void)len;
@@ -93,9 +87,11 @@ void io_print_int(int ION_MAYBE_UNUSED n) {
9387
{
9488
int _result = write(1, (uint8_t*)"-2147483648", 11);
9589
(void)_result;
96-
(void)_result;
9790
}
98-
goto epilogue;
91+
(void)negative;
92+
(void)len;
93+
(void)buf;
94+
goto epilogue;
9995
}
10096
value = (0 - value);
10197
}
@@ -116,13 +112,11 @@ void io_print_int(int ION_MAYBE_UNUSED n) {
116112
{
117113
int _minus = write(1, (uint8_t*)"-", 1);
118114
(void)_minus;
119-
(void)_minus;
120115
}
121116
}
122117
{
123118
int _result = write(1, &buf[0], len);
124119
(void)_result;
125-
(void)_result;
126120
}
127121
goto epilogue;
128122
epilogue:

examples/http_server.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,6 @@ int handle_client(int ION_MAYBE_UNUSED client_fd) {
7373
int _sent6 = send_sys(client_fd, (uint8_t*)"<html><head><title>Ion HTTP Server</title></head><body><h1>Hello from Ion!</h1><p>This is a simple HTTP server written in Ion.</p></body></html>", 89, 0);
7474
(void)_sent6;
7575
close(client_fd);
76-
(void)_sent6;
77-
(void)_sent5;
78-
(void)_sent4;
79-
(void)_sent3;
80-
(void)_sent2;
81-
(void)_sent1;
8276
}
8377
ret_val = 0;
8478
goto epilogue;
@@ -148,7 +142,6 @@ static void* ion_spawn_entry_0(void* arg) {
148142
free(ctx);
149143
int _result = handle_client(client_fd);
150144
(void)_result;
151-
(void)_result;
152145
goto spawn_0_epilogue;
153146
spawn_0_epilogue:
154147
return NULL;

examples/showcase.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ int for_loop_example(void) {
249249
goto epilogue;
250250
}
251251
ret_val = 0;
252+
if (__for_container_2197) { ion_vec_free((ion_vec_t*)(__for_container_2197)); }
252253
goto epilogue;
253254
epilogue:
254255
return ret_val;
@@ -384,7 +385,6 @@ int pattern_matching_example(void) {
384385
int _c = match_val_5.data.variant_1.code;
385386
(void)_c;
386387
ret_val = 6;
387-
(void)_c;
388388
goto epilogue;
389389
break;
390390
}
@@ -404,8 +404,6 @@ int reference_example(void) {
404404
(void)_ref_y;
405405
int* _ref_x = &x;
406406
(void)_ref_x;
407-
(void)_ref_x;
408-
(void)_ref_y;
409407
}
410408
Vec_int* values = ((Vec_int*)(ion_vec_new(sizeof(int))));
411409
ion_vec_push((ion_vec_t*)(values), &((int){x}), sizeof(int));
@@ -505,6 +503,8 @@ int spawn_channel_example(void) {
505503
goto epilogue;
506504
}
507505
ret_val = 0;
506+
if (rx_back_mut.channel) { ion_channel_handle_drop(rx_back_mut.channel); }
507+
if (tx.channel) { ion_channel_handle_drop(tx.channel); }
508508
goto epilogue;
509509
epilogue:
510510
return ret_val;
@@ -519,6 +519,7 @@ int fn_literal_example(void) {
519519
goto epilogue;
520520
}
521521
ret_val = 0;
522+
(void)twice;
522523
goto epilogue;
523524
epilogue:
524525
return ret_val;

examples/spawn_channel.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ int main(void) {
5252
goto epilogue;
5353
}
5454
ret_val = 1;
55+
if (rx_back_mut.channel) { ion_channel_handle_drop(rx_back_mut.channel); }
56+
if (tx.channel) { ion_channel_handle_drop(tx.channel); }
5557
goto epilogue;
5658
epilogue:
5759
return ret_val;

0 commit comments

Comments
 (0)