Commits

e2a0160b9f34047ed65a2e62245c50691c9214c7
Switch branches/tags
All users
All time
May 2026
Su Mo Tu We Th Fr Sa
26 27 28 29 30 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6

Commits on May 6, 2026

  1. mfwolffe committed
  2. Drop IR-peel short-circuit in try_defined_assignment
    The semantic_candidates filter above already proved that at least
    one specific in `interface assignment(=)` matches both operands by
    category and kind. The earlier IR-level gate (`if
    same_intrinsic_semantic_type(...) && !derived { return false }`)
    fired in two distinct false-positive shapes:
    
      1. `lv2 = s` where lv2 is `logical(int32), allocatable` and s is
         `type(bitset_64)`. Both operands peeled to `Bool` after Ptr
         stripping, so the gate skipped the user-defined
         `logint32_assign_64` and a scalar broadcast crashed.
    
      2. stdlib_strings / path call sites where the intrinsic memcpy
         happened to be wrong but didn't crash, masking the bug.
    
    Trust the semantic filter — the IR types only ever produce false
    positives here.
    mfwolffe committed
  3. Resolve afs-ld via AFS_LD env var and forward -L/-l/-rpath flags
    AFS_LD=1 (or any non-falsy value) now picks the sibling afs-ld
    binary alongside the armfortas executable, in addition to the
    existing AFS_LD_PATH override that names a specific path. The
    afs-ld backend now forwards library_search_paths, link_libs, and
    rpath through to the linker instead of erroring out, so the same
    driver invocation works under both system ld and afs-ld for the
    common cases.
    
    Test: hello_world_runs_through_driver_with_afs_ld_enable_flag.
    mfwolffe committed
  4. mfwolffe committed
  5. mfwolffe committed
  6. Stop treating assumed-size dummies as descriptor-passed
    arg_uses_descriptor_from_decls grouped ArraySpec::AssumedSize with
    AssumedShape / Deferred / AssumedRank and returned descriptor_arg=true
    for them.  Per F2018 §15.5.2 an assumed-size dummy (`tau(*)` or
    `a(lda, *)`) is passed as a bare element pointer, not a descriptor,
    so flagging it as descriptor_arg made every `tau(i)` reference go
    through array_descriptor_addr → array_base_addr — which loads through
    the slot a SECOND time as if the slot held a descriptor pointer.  For
    `real, intent(out) :: tau(*)` the second load read the first 8
    bytes of the (zero-initialised) array as the supposed base pointer,
    so the element address came out zero.
    
    Concretely, stdlib_sgeqr2 -> stdlib_slarfg(..., tau(i)) passed x4=null
    to slarfg, which then SEGV'd at the `tau = zero` store inside the
    `xnorm == 0` branch.  After the fix slarfg receives a proper element
    address and the QR/EIG cluster no longer crashes.
    mfwolffe committed
  7. Fill every element on RANDOM_NUMBER(array)
    The intrinsic random_number(harvest) was always lowered to a single
    scalar afs_random_number_f32/f64 call, even when harvest was a whole
    array.  That filled only harvest(1,1) and left the rest at whatever
    stack data happened to be there — programs like example_qr seemed to
    work on small problems by accident (zero-init bss) and crashed
    nondeterministically on real ones once LAPACK hit a row of garbage.
    
    Add afs_random_number_array_{f32,f64}(ptr, n) runtime entries that
    draw n independent values, and dispatch through them in the IR
    lowering when the harvest expression is a Name bound to an
    array-like local.  Scalar callers keep the original entries so
    existing code paths are unchanged.
    
    Probe: random_number(A) on a 3x3 array now produces independent
    draws in (0, 1) for every element, where before A(2,2)/A(3,3) etc.
    were left at -1.0.
    mfwolffe committed

Commits on May 5, 2026

  1. Plumb INQUIRE read=/write=/readwrite= and report std-unit capabilities
    stdlib savetxt(unit, x, ...) checks
        inquire(unit=unit, opened=opened, write=writable)
        if (.not. opened .or. writable(1:1) /= 'Y') call error_stop
    to verify the unit can be written before emitting any data.  Two gaps:
    
    1. afs_inquire_unit / afs_inquire_file had no parameter for write=,
       read=, or readwrite=, so the caller's writable variable was left
       at uninitialized stack data — savetxt always concluded the unit
       was not writable.
    
    2. The IR's Stmt::Inquire lowering never extracted these three specs
       from the AST, so even adding runtime params would have silently
       passed null buffers.
    
    Add (read_buf, write_buf, readwrite_buf) trios to both runtime
    functions and to both call-emission sites in IR.  Populate based on
    the connected unit's Action: Read => YES/NO/NO, Write => NO/YES/NO,
    ReadWrite => YES/YES/YES, disconnected => UNKNOWN.
    
    Make Action Copy so the action-cap helper can take it by value
    without cloning at every call site.
    mfwolffe committed
  2. Zero iostat= on successful write
    write(unit, fmt, iostat=ios, iomsg=iomsg) values would leave the user's
    ios variable at its uninitialized stack value on success — only error
    paths are even capable of writing it, and there are none in the runtime
    yet.  Stdlib's universal pattern is
    
        if (ios/=0) call error_stop(msg=trim(iomsg))
    
    so on a successful write the user's program would die with a spurious
    ERROR STOP because ios was random garbage.  Resolve the iostat= control
    target up front and store i32(0) after afs_fmt_end / lower_write_items_adv
    returns, both for unit-targeted writes and for internal-buffer writes.
    
    Combined with 4986129 (descriptor-aware section iteration), savetxt
    now writes example.dat / example.csv / example2.dat / example3.dat
    correctly with three rows of data each.  Remaining savetxt failure is
    a separate output_unit (stdout via unit 6) handling bug.
    mfwolffe committed
  3. Use runtime descriptor for assumed-shape section I/O iteration
    Both formatted-write (write(u, fmt) d(i, :)) and list-directed-write
    (write(u, *) d(i, :)) of an array section through an assumed-shape
    dummy were silently producing empty rows.  info.dims is empty for
    assumed-shape (decl_ext == 0), so the existing fixed-shape iterators
    ran zero iterations and emitted only newlines.
    
    Add lower_alloc_section_write_nd and lower_alloc_section_fmt_push_nd
    that load lower bound, upper bound, and per-dim memory stride from
    the runtime ArrayDescriptor — matching what compute_flat_elem_offset
    already does for descriptor reads — and route through them when
    local_uses_array_descriptor is true.  Stdlib savetxt and the many
    log_io_error / log_text_error / cov / similar paths flow through
    this code now.
    mfwolffe committed
  4. mfwolffe committed

Commits on May 4, 2026