fortrangoingonforty/armfortas / a8a93c9

Browse files

Test RANDOM_NUMBER fills every element of an array harvest

Authored by espadonne
Committed by mfwolffe
SHA
a8a93c99e26b721d51c656502af02faea9c7d061
Parents
3e3048a
Tree
5debdf9

1 changed file

StatusFile+-
M tests/cli_driver.rs 38 0
tests/cli_driver.rsmodified
@@ -28623,6 +28623,44 @@ fn cmplx_whole_array_with_kind_keyword_returns_correct_kind_descriptor() {
2862328623
     let _ = std::fs::remove_file(&src);
2862428624
 }
2862528625
 
28626
+#[test]
28627
+fn random_number_on_array_fills_every_element() {
28628
+    // F2018 §16.9.171: RANDOM_NUMBER(harvest) fills harvest with
28629
+    // independent draws from [0,1). The intrinsic-subroutine lowering
28630
+    // dispatched all real-kind harvests to the scalar runtime
28631
+    // (afs_random_number_f64), which fills exactly one slot — so for
28632
+    // an array harvest, elements 2..N stayed at uninit-stack-garbage
28633
+    // values (typically tiny denormals or NaN). Surfaced in stdlib
28634
+    // sparse_spmv: `random_number(A); count(abs(A) > tiny(...))`
28635
+    // returned 1 instead of size(A), nnz=1, COO%index allocated as
28636
+    // (2,1), then COO%index(2, idx) walked past dim 0 extent and
28637
+    // tripped "Bounds check failed: index 2 outside [1, 1]".
28638
+    let src = write_program(
28639
+        "program p\n  implicit none\n  integer, parameter :: dp = kind(0.0d0)\n  real(dp) :: a(8)\n  real    :: b(8)\n  integer :: i\n  call random_number(a)\n  call random_number(b)\n  do i = 1, 8\n    if (.not. (a(i) >= 0.0_dp .and. a(i) < 1.0_dp)) error stop 1\n    if (.not. (b(i) >= 0.0    .and. b(i) < 1.0   )) error stop 2\n  end do\n  if (count(a > 0.0_dp) /= 8) error stop 3\n  if (count(b > 0.0   ) /= 8) error stop 4\n  print *, 'ok'\nend program\n",
28640
+        "f90",
28641
+    );
28642
+    let out = unique_path("random_number_array_fill", "bin");
28643
+    let compile = Command::new(compiler("armfortas"))
28644
+        .args([src.to_str().unwrap(), "-o", out.to_str().unwrap()])
28645
+        .output()
28646
+        .expect("random_number array compile failed to spawn");
28647
+    assert!(
28648
+        compile.status.success(),
28649
+        "random_number array compile failed: {}",
28650
+        String::from_utf8_lossy(&compile.stderr)
28651
+    );
28652
+    let run = Command::new(&out).output().expect("run failed");
28653
+    assert!(
28654
+        run.status.success() && String::from_utf8_lossy(&run.stdout).contains("ok"),
28655
+        "random_number array run failed: status={:?} stdout={} stderr={}",
28656
+        run.status,
28657
+        String::from_utf8_lossy(&run.stdout),
28658
+        String::from_utf8_lossy(&run.stderr)
28659
+    );
28660
+    let _ = std::fs::remove_file(&out);
28661
+    let _ = std::fs::remove_file(&src);
28662
+}
28663
+
2862628664
 #[test]
2862728665
 fn allocatable_array_component_passed_to_assumed_size_unwraps_descriptor() {
2862828666
     // F2018 §15.5.2.4: when an allocatable rank-N array component