| 1 | ! Audit #4 MAJOR-5 — module-level allocatable arrays now work. |
| 2 | ! |
| 3 | ! Fixed: collect_module_globals now detects the |
| 4 | ! `is_allocatable && array_spec.is_some()` case BEFORE the |
| 5 | ! total<=0 deferred-shape skip and emits a 384-byte zero-init |
| 6 | ! descriptor global. ModuleGlobalInfo gains an `allocatable` |
| 7 | ! field; install_one_global propagates it into LocalInfo and |
| 8 | ! types the addr as `Ptr<Array<i8, 384>>` so the runtime |
| 9 | ! allocate/deallocate/subscript helpers see the descriptor. |
| 10 | ! |
| 11 | ! With this in place, the existing local-allocatable lowering |
| 12 | ! pipeline just works for module-scope allocatables — no |
| 13 | ! changes needed to the runtime ABI. |
| 14 | ! |
| 15 | ! Critical for fortsh: ~55 modules use allocatable shell state. |
| 16 | ! |
| 17 | ! IR-shape assertions (audit5 MIN-2, updated audit6 BLOCKING-4): |
| 18 | ! * The module variable must materialize as a real 384-byte |
| 19 | ! descriptor global (zeroed by the loader), not as a stub |
| 20 | ! scalar global or a never-installed local. |
| 21 | ! * `allocate(arr(5))` must lower to a runtime call into |
| 22 | ! afs_allocate_array — audit6 BLOCKING-4 unified the 1-D |
| 23 | ! and multi-D paths through afs_allocate_array because |
| 24 | ! afs_allocate_1d hardcoded lower=1 and couldn't represent |
| 25 | ! `allocate(a(0:N))`. The 1-D fast path is gone; everything |
| 26 | ! goes through afs_allocate_array now. |
| 27 | ! |
| 28 | ! CHECK: 10 20 30 40 50 |
| 29 | ! IR_CHECK: global @afs_mod_audit4_maj5_mod_arr: [i8 x 384] = zeroinit |
| 30 | ! IR_CHECK: call @afs_allocate_array |
| 31 | ! IR_NOT: call @afs_allocate_1d |
| 32 | program audit4_maj5_module_allocatable |
| 33 | use audit4_maj5_mod |
| 34 | allocate(arr(5)) |
| 35 | arr = [10, 20, 30, 40, 50] |
| 36 | print *, arr |
| 37 | end program |
| 38 | |
| 39 | module audit4_maj5_mod |
| 40 | integer, allocatable :: arr(:) |
| 41 | end module audit4_maj5_mod |
| 42 |