Commits

trunk
Switch branches/tags
mfwolffe
Until Jun 4, 2026
June 2026
Su Mo Tu We Th Fr Sa
31 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 1 2 3 4
5 6 7 8 9 10 11

Commits on May 10, 2026

Commits on May 9, 2026

Commits on May 8, 2026

Commits on May 10, 2026

Commits on May 8, 2026

  1. Populate rank-remap pointer descriptor for section RHS
    F2018 §10.2.2.3: rank-remap pointer assignment
    
      real(sp), pointer :: tau(:)
      real(sp), target  :: q(5, 5)
      tau(1:k) => q(1:k, 1)
    
    lower_rank_remap_pointer_assignment used to require RHS = bare Name
    and bail on any FunctionCall (section/element) — the pointer
    descriptor never got its base_addr, rank, or extents populated.
    Subsequent 'geqrf(..., tau, ...)' (assumed-size dummy 'tau(*)') then
    received tau.base_addr = NULL, and slarfg's '*tau = ...' SEGV'd at
    depth.  Surfaced as SEGVs across stdlib's qr/eig/schur cluster:
    example_qr, example_qr_space, example_pivoting_qr*, example_eig*,
    example_schur*.
    
    Extend the source-shape match to handle FunctionCall (section
    designator on a Name): convert each Range(start:..) into Element(start),
    compute the address of the FIRST included element via
    lower_array_element_addr, and use that as the descriptor's base_addr
    with the target's bounds.
    mfwolffe committed
  2. Honor type_spec in reshape ArrayConstructor lowering
    F2018 §7.8: a typed array constructor '[T :: ...]' has element type T
    regardless of the element expressions' types. The reshape lowering at
    lower_reshape_array_expr_descriptor inferred elem_ty solely via
    first_array_constructor_type_info, which examines the first value
    expression. For 'reshape([real(dp) :: 1, 2, 3, 4], [2, 2])' the values
    are integer literals (4 bytes), so the materialised descriptor was
    elem_size=4 instead of 8.
    
    The malformed elem_size propagated through the reshape result; when
    passed to an assumed-shape dummy 'a(:,:)' and used as SOURCE= in an
    ALLOCATE, afs_prepare_array_copy saw 'dest.elem_size != source.elem_size'
    (8 != 4), freed the freshly-allocated dest buffer, zeroed base_addr,
    and the next read of 'amat(1,1)' SEGV'd. Surfaced across stdlib's det /
    determinant / eig / qr clusters whose examples invoke
    'det(reshape([real(dp)::1,2,3,4], [2,2]))'.
    
    Consult type_spec first; fall back to first-element inference only when
    no type_spec is present.
    mfwolffe committed
  3. Accept non-allocatable source in afs_prepare_array_copy
    F2018 §9.7.1.2: SOURCE-expr in ALLOCATE need only be a value of the
    right type/kind/shape — it doesn't have to itself be an ALLOCATABLE.
    The common stdlib pattern is
    
        pure module function det(a) result(d)
          real(dp), intent(in) :: a(:,:)        ! assumed-shape dummy
          real(dp), allocatable :: amat(:,:)
          allocate(amat(size(a,1), size(a,2)), source=a)
    
    afs_prepare_array_copy required both dest.is_allocated() AND
    source.is_allocated().  Assumed-shape dummies carry flags=CONTIGUOUS
    only — they're bound to the caller's data, not owned — so
    source.is_allocated() returned false, the routine freed the
    fresh dest buffer, zeroed dest.base_addr, and the next read of
    amat(1,1) faulted.  Surfaced as SEGV across stdlib's det / determinant
    / eig / qr / lstsq / solve_chol / solve_custom clusters.
    
    Replace source.is_allocated() with !source.base_addr.is_null():
    the source is valid as long as it points to data, regardless of
    whether it owns it.
    mfwolffe committed