@@ -28622,3 +28622,42 @@ fn cmplx_whole_array_with_kind_keyword_returns_correct_kind_descriptor() { |
| 28622 | 28622 | let _ = std::fs::remove_file(&out); |
| 28623 | 28623 | let _ = std::fs::remove_file(&src); |
| 28624 | 28624 | } |
| 28625 | + |
| 28626 | +#[test] |
| 28627 | +fn rank2_section_with_vector_subscript_gathers_into_fresh_descriptor() { |
| 28628 | + // F2018 §9.5.3.3: a section like `A(:, pivots)` where one subscript |
| 28629 | + // is a range and another is a rank-1 integer array (vector subscript) |
| 28630 | + // must produce a rank-2 result whose dim 1 is permuted/gathered by |
| 28631 | + // the index array. afs_create_section can only express stride-based |
| 28632 | + // sections, so vector subscripts force a per-element gather into a |
| 28633 | + // fresh allocated descriptor. Without that path, the index array's |
| 28634 | + // base pointer was being stored into the section's start/end i64 |
| 28635 | + // slots with stride 0, producing garbage offsets and a SIGBUS |
| 28636 | + // (matched stdlib pivoting_qr cluster). |
| 28637 | + let src = write_program( |
| 28638 | + "program p\n real :: A(4,3), B(4,3)\n integer :: pivots(3)\n integer :: i, j\n do i = 1, 3\n do j = 1, 4\n A(j,i) = real((i-1)*4 + j)\n end do\n end do\n pivots = [3, 1, 2]\n B = A(:, pivots)\n if (abs(B(1,1) - 9.0) > 1.0e-6) error stop 1\n if (abs(B(4,1) - 12.0) > 1.0e-6) error stop 2\n if (abs(B(1,2) - 1.0) > 1.0e-6) error stop 3\n if (abs(B(4,2) - 4.0) > 1.0e-6) error stop 4\n if (abs(B(1,3) - 5.0) > 1.0e-6) error stop 5\n if (abs(B(4,3) - 8.0) > 1.0e-6) error stop 6\n print *, 'ok'\nend program\n", |
| 28639 | + "f90", |
| 28640 | + ); |
| 28641 | + let out = unique_path("rank2_vector_subscript_section", "bin"); |
| 28642 | + let compile = Command::new(compiler("armfortas")) |
| 28643 | + .args([src.to_str().unwrap(), "-o", out.to_str().unwrap()]) |
| 28644 | + .output() |
| 28645 | + .expect("rank-2 vector subscript compile failed to spawn"); |
| 28646 | + assert!( |
| 28647 | + compile.status.success(), |
| 28648 | + "rank-2 vector subscript compile failed: {}", |
| 28649 | + String::from_utf8_lossy(&compile.stderr) |
| 28650 | + ); |
| 28651 | + let run = Command::new(&out) |
| 28652 | + .output() |
| 28653 | + .expect("rank-2 vector subscript run failed"); |
| 28654 | + assert!( |
| 28655 | + run.status.success() && String::from_utf8_lossy(&run.stdout).contains("ok"), |
| 28656 | + "rank-2 vector subscript run failed: status={:?} stdout={} stderr={}", |
| 28657 | + run.status, |
| 28658 | + String::from_utf8_lossy(&run.stdout), |
| 28659 | + String::from_utf8_lossy(&run.stderr) |
| 28660 | + ); |
| 28661 | + let _ = std::fs::remove_file(&out); |
| 28662 | + let _ = std::fs::remove_file(&src); |
| 28663 | +} |